Finish semantic checks
[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         parseFile(pn);
13     }
14
15     /** Parse the classes in this file */
16     public void parseFile(ParseNode pn) {
17         ParseNode tpn=pn.getChild("type_declaration_list");
18         if (tpn!=null) {
19             ParseNodeVector pnv=tpn.getChildren();
20             for(int i=0;i<pnv.size();i++) {
21                 ParseNode type_pn=pnv.elementAt(i);
22                 if (isEmpty(type_pn)) /* Skip the semicolon */
23                     continue;
24                 ClassDescriptor cn=parseTypeDecl(type_pn);
25                 state.addClass(cn);
26             }
27         }
28     }
29
30     public ClassDescriptor parseTypeDecl(ParseNode pn) {
31         if (isNode(pn, "class_declaration")) {
32             ClassDescriptor cn=new ClassDescriptor(pn.getChild("name").getTerminal());
33             if (!isEmpty(pn.getChild("super").getTerminal())) {
34                 /* parse superclass name */
35                 ParseNode snn=pn.getChild("super").getChild("type").getChild("class").getChild("name");
36                 NameDescriptor nd=parseName(snn);
37                 cn.setSuper(nd.toString());
38             }
39             cn.setModifiers(parseModifiersList(pn.getChild("modifiers")));
40             parseClassBody(cn, pn.getChild("classbody"));
41             return cn;
42         } else throw new Error();
43     }
44
45     private void parseClassBody(ClassDescriptor cn, ParseNode pn) {
46         ParseNode decls=pn.getChild("class_body_declaration_list");
47         if (decls!=null) {
48             ParseNodeVector pnv=decls.getChildren();
49             for(int i=0;i<pnv.size();i++) {
50                 ParseNode decl=pnv.elementAt(i);
51                 if (isNode(decl,"member")) {
52                     parseClassMember(cn,decl);
53                 } else if (isNode(decl,"constructor")) {
54                     parseConstructorDecl(cn,decl.getChild("constructor_declaration"));
55                 } else if (isNode(decl,"block")) {
56                 } else throw new Error();
57             }
58         }
59     }
60
61     private void parseClassMember(ClassDescriptor 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(ClassDescriptor 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(ClassDescriptor 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);
238         state.addTreeCode(md,bn);
239     }
240
241     private void parseConstructorDecl(ClassDescriptor cn, ParseNode pn) {
242         ParseNode mn=pn.getChild("modifiers");
243         Modifiers m=parseModifiersList(mn);
244         ParseNode cdecl=pn.getChild("constructor_declarator");
245         String name=cdecl.getChild("name").getChild("identifier").getTerminal();
246         MethodDescriptor md=new MethodDescriptor(m, name);
247         ParseNode paramnode=cdecl.getChild("parameters");
248         parseParameterList(md,paramnode);
249         ParseNode bodyn0=pn.getChild("body");
250         ParseNode bodyn=bodyn0.getChild("constructor_body");
251         cn.addMethod(md);
252         if (bodyn!=null) {
253             BlockNode bn=parseBlock(bodyn);
254             state.addTreeCode(md,bn);
255         }
256     }
257
258     public BlockNode parseBlock(ParseNode pn) {
259         if (isEmpty(pn.getTerminal()))
260             return new BlockNode();
261         ParseNode bsn=pn.getChild("block_statement_list");
262         return parseBlockHelper(bsn);
263     }
264     
265     private BlockNode parseBlockHelper(ParseNode pn) {
266         ParseNodeVector pnv=pn.getChildren();
267         BlockNode bn=new BlockNode();
268         for(int i=0;i<pnv.size();i++) {
269             Vector bsv=parseBlockStatement(pnv.elementAt(i));
270             for(int j=0;j<bsv.size();j++) {
271                 bn.addBlockStatement((BlockStatementNode)bsv.get(j));
272             }
273         }
274         return bn;
275     }
276
277     public BlockNode parseSingleBlock(ParseNode pn) {
278         BlockNode bn=new BlockNode();
279         Vector bsv=parseBlockStatement(pn);
280         for(int j=0;j<bsv.size();j++) {
281             bn.addBlockStatement((BlockStatementNode)bsv.get(j));
282         }
283         bn.setStyle(BlockNode.NOBRACES);
284         return bn;
285     }
286
287     public Vector parseBlockStatement(ParseNode pn) {
288         Vector blockstatements=new Vector();
289         if (isNode(pn,"local_variable_declaration")) {
290             TypeDescriptor t=parseTypeDescriptor(pn);
291             ParseNode vn=pn.getChild("variable_declarators_list");
292             ParseNodeVector pnv=vn.getChildren();
293             for(int i=0;i<pnv.size();i++) {
294                 ParseNode vardecl=pnv.elementAt(i);
295                 String identifier=vardecl.getChild("single").getTerminal();
296                 ParseNode epn=vardecl.getChild("initializer");
297                 
298                 ExpressionNode en=null;
299                 if (epn!=null)
300                     en=parseExpression(epn.getFirstChild());
301                 
302                 blockstatements.add(new DeclarationNode(new VarDescriptor(t,identifier),en));
303             }
304         } else if (isNode(pn,"nop")) {
305             /* Do Nothing */
306         } else if (isNode(pn,"expression")) {
307             blockstatements.add(new BlockExpressionNode(parseExpression(pn.getFirstChild())));
308         } else if (isNode(pn,"ifstatement")) {
309             blockstatements.add(new IfStatementNode(parseExpression(pn.getChild("condition").getFirstChild()),
310                                        parseSingleBlock(pn.getChild("statement").getFirstChild()),
311                                        pn.getChild("else_statement")!=null?parseSingleBlock(pn.getChild("else_statement").getFirstChild()):null));
312         } else if (isNode(pn,"return")) {
313             if (isEmpty(pn.getTerminal()))
314                 blockstatements.add(new ReturnNode());
315             else {
316                 ExpressionNode en=parseExpression(pn.getFirstChild());
317                 blockstatements.add(new ReturnNode(en));
318             }
319         } else if (isNode(pn,"block_statement_list")) {
320             BlockNode bn=parseBlockHelper(pn);
321             blockstatements.add(new SubBlockNode(bn));
322         } else if (isNode(pn,"empty")) {
323             /* nop */
324         } else if (isNode(pn,"statement_expression_list")) {
325             ParseNodeVector pnv=pn.getChildren();
326             BlockNode bn=new BlockNode();
327             for(int i=0;i<pnv.size();i++) {
328                 ExpressionNode en=parseExpression(pnv.elementAt(i));
329                 blockstatements.add(new BlockExpressionNode(en));
330             }
331             bn.setStyle(BlockNode.EXPRLIST);
332         } else if (isNode(pn,"forstatement")) {
333             BlockNode init=parseSingleBlock(pn.getChild("initializer").getFirstChild());
334             BlockNode update=parseSingleBlock(pn.getChild("update").getFirstChild());
335             ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
336             BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
337             blockstatements.add(new LoopNode(init,condition,update,body));
338         } else if (isNode(pn,"whilestatement")) {
339             ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
340             BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
341             blockstatements.add(new LoopNode(condition,body,LoopNode.WHILELOOP));
342         } else if (isNode(pn,"dowhilestatement")) {
343             ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
344             BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
345             blockstatements.add(new LoopNode(condition,body,LoopNode.DOWHILELOOP));
346         } else {
347             System.out.println("---------------");
348             System.out.println(pn.PPrint(3,true));
349             throw new Error();
350         }
351         return blockstatements;
352     }
353
354     public MethodDescriptor parseMethodHeader(ParseNode pn) {
355         ParseNode mn=pn.getChild("modifiers");
356         Modifiers m=parseModifiersList(mn);
357         
358         ParseNode tn=pn.getChild("returntype");
359         TypeDescriptor returntype;
360         if (tn!=null) 
361             returntype=parseTypeDescriptor(tn);
362         else
363             returntype=new TypeDescriptor(TypeDescriptor.VOID);
364
365         ParseNode pmd=pn.getChild("method_declarator");
366         String name=pmd.getChild("name").getTerminal();
367         MethodDescriptor md=new MethodDescriptor(m, returntype, name);
368        
369         ParseNode paramnode=pmd.getChild("parameters");
370         parseParameterList(md,paramnode);
371         return md;
372     }
373
374     public void parseParameterList(MethodDescriptor md, ParseNode pn) {
375         ParseNode paramlist=pn.getChild("formal_parameter_list");
376         if (paramlist==null)
377             return;
378          ParseNodeVector pnv=paramlist.getChildren();
379          for(int i=0;i<pnv.size();i++) {
380              ParseNode paramn=pnv.elementAt(i);
381              TypeDescriptor type=parseTypeDescriptor(paramn);
382              String paramname=paramn.getChild("single").getTerminal();
383              md.addParameter(type,paramname);
384          }
385     }
386
387     public Modifiers parseModifiersList(ParseNode pn) {
388         Modifiers m=new Modifiers();
389         ParseNode modlist=pn.getChild("modifier_list");
390         if (modlist!=null) {
391             ParseNodeVector pnv=modlist.getChildren();
392             for(int i=0;i<pnv.size();i++) {
393                 ParseNode modn=pnv.elementAt(i);
394                 if (isNode(modn,"public"))
395                     m.addModifier(Modifiers.PUBLIC);
396                 if (isNode(modn,"protected"))
397                     m.addModifier(Modifiers.PROTECTED);
398                 if (isNode(modn,"private"))
399                     m.addModifier(Modifiers.PRIVATE);
400                 if (isNode(modn,"static"))
401                     m.addModifier(Modifiers.STATIC);
402                 if (isNode(modn,"final"))
403                     m.addModifier(Modifiers.FINAL);
404                 if (isNode(modn,"native"))
405                     m.addModifier(Modifiers.NATIVE);
406             }
407         }
408         return m;
409     }
410
411     private boolean isNode(ParseNode pn, String label) {
412         if (pn.getLabel().equals(label))
413             return true;
414         else return false;
415     }
416
417     private static boolean isEmpty(ParseNode pn) {
418         if (pn.getLabel().equals("empty"))
419             return true;
420         else
421             return false;
422     }
423
424     private static boolean isEmpty(String s) {
425         if (s.equals("empty"))
426             return true;
427         else
428             return false;
429     }
430
431     /** Throw an exception if something is unexpected */
432     private void check(ParseNode pn, String label) {
433         if (pn == null) {
434             throw new Error(pn+ "IE: Expected '" + label + "', got null");
435         }
436         if (! pn.getLabel().equals(label)) {
437             throw new Error(pn+ "IE: Expected '" + label + "', got '"+pn.getLabel()+"'");
438         }
439     }
440 }