Instanceof checks for jim
[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
9   private int m_taskexitnum;
10
11   public BuildIR(State state) {
12     this.state=state;
13     this.m_taskexitnum = 0;
14   }
15
16   public void buildtree() {
17     for(Iterator it=state.parsetrees.iterator(); it.hasNext();) {
18       ParseNode pn=(ParseNode)it.next();
19       parseFile(pn);
20     }
21   }
22
23   /** Parse the classes in this file */
24   public void parseFile(ParseNode pn) {
25     NameDescriptor packages;
26     Vector singleimports=new Vector();
27     Vector multiimports=new Vector();
28
29     ParseNode ipn=pn.getChild("imports").getChild("import_decls_list");
30     if (ipn!=null) {
31       ParseNodeVector pnv=ipn.getChildren();
32       for(int i=0; i<pnv.size(); i++) {
33         ParseNode pnimport=pnv.elementAt(i);
34         NameDescriptor nd=parseName(pnimport.getChild("name"));
35         if (isNode(pnimport,"import_single"))
36           singleimports.add(nd);
37         else
38           multiimports.add(nd);
39       }
40     }
41     ParseNode ppn=pn.getChild("packages").getChild("package");
42     if (ppn!=null) {
43       packages=parseName(pn.getChild("name"));
44     }
45     ParseNode tpn=pn.getChild("type_declaration_list");
46     if (tpn!=null) {
47       ParseNodeVector pnv=tpn.getChildren();
48       for(int i=0; i<pnv.size(); i++) {
49         ParseNode type_pn=pnv.elementAt(i);
50         if (isEmpty(type_pn))         /* Skip the semicolon */
51           continue;
52         if (isNode(type_pn,"class_declaration")) {
53           ClassDescriptor cn=parseTypeDecl(type_pn);
54           state.addClass(cn);
55         } else if (isNode(type_pn,"task_declaration")) {
56           TaskDescriptor td=parseTaskDecl(type_pn);
57           state.addTask(td);
58         } else {
59           throw new Error(type_pn.getLabel());
60         }
61       }
62     }
63   }
64
65   public TaskDescriptor parseTaskDecl(ParseNode pn) {
66     TaskDescriptor td=new TaskDescriptor(pn.getChild("name").getTerminal());
67     ParseNode bodyn=pn.getChild("body");
68     BlockNode bn=parseBlock(bodyn);
69     parseParameterList(td, pn);
70     state.addTreeCode(td,bn);
71     if (pn.getChild("flag_effects_list")!=null)
72       td.addFlagEffects(parseFlags(pn.getChild("flag_effects_list")));
73     return td;
74   }
75
76   public Vector parseFlags(ParseNode pn) {
77     Vector vfe=new Vector();
78     ParseNodeVector pnv=pn.getChildren();
79     for(int i=0; i<pnv.size(); i++) {
80       ParseNode fn=pnv.elementAt(i);
81       FlagEffects fe=parseFlagEffects(fn);
82       vfe.add(fe);
83     }
84     return vfe;
85   }
86
87   public FlagEffects parseFlagEffects(ParseNode pn) {
88     if (isNode(pn,"flag_effect")) {
89       String flagname=pn.getChild("name").getTerminal();
90       FlagEffects fe=new FlagEffects(flagname);
91       if (pn.getChild("flag_list")!=null)
92         parseFlagEffect(fe, pn.getChild("flag_list"));
93       if (pn.getChild("tag_list")!=null)
94         parseTagEffect(fe, pn.getChild("tag_list"));
95       return fe;
96     } else throw new Error();
97   }
98
99   public void parseTagEffect(FlagEffects fes, ParseNode pn) {
100     ParseNodeVector pnv=pn.getChildren();
101     for(int i=0; i<pnv.size(); i++) {
102       ParseNode pn2=pnv.elementAt(i);
103       boolean status=true;
104       if (isNode(pn2,"not")) {
105         status=false;
106         pn2=pn2.getChild("name");
107       }
108       String name=pn2.getTerminal();
109       fes.addTagEffect(new TagEffect(name,status));
110     }
111   }
112
113   public void parseFlagEffect(FlagEffects fes, ParseNode pn) {
114     ParseNodeVector pnv=pn.getChildren();
115     for(int i=0; i<pnv.size(); i++) {
116       ParseNode pn2=pnv.elementAt(i);
117       boolean status=true;
118       if (isNode(pn2,"not")) {
119         status=false;
120         pn2=pn2.getChild("name");
121       }
122       String name=pn2.getTerminal();
123       fes.addEffect(new FlagEffect(name,status));
124     }
125   }
126
127   public FlagExpressionNode parseFlagExpression(ParseNode pn) {
128     if (isNode(pn,"or")) {
129       ParseNodeVector pnv=pn.getChildren();
130       ParseNode left=pnv.elementAt(0);
131       ParseNode right=pnv.elementAt(1);
132       return new FlagOpNode(parseFlagExpression(left), parseFlagExpression(right), new Operation(Operation.LOGIC_OR));
133     } else if (isNode(pn,"and")) {
134       ParseNodeVector pnv=pn.getChildren();
135       ParseNode left=pnv.elementAt(0);
136       ParseNode right=pnv.elementAt(1);
137       return new FlagOpNode(parseFlagExpression(left), parseFlagExpression(right), new Operation(Operation.LOGIC_AND));
138     } else if (isNode(pn, "not")) {
139       ParseNodeVector pnv=pn.getChildren();
140       ParseNode left=pnv.elementAt(0);
141       return new FlagOpNode(parseFlagExpression(left), new Operation(Operation.LOGIC_NOT));
142
143     } else if (isNode(pn,"name")) {
144       return new FlagNode(pn.getTerminal());
145     } else {
146       throw new Error();
147     }
148   }
149
150   public Vector parseChecks(ParseNode pn) {
151     Vector ccs=new Vector();
152     ParseNodeVector pnv=pn.getChildren();
153     for(int i=0; i<pnv.size(); i++) {
154       ParseNode fn=pnv.elementAt(i);
155       ConstraintCheck cc=parseConstraintCheck(fn);
156       ccs.add(cc);
157     }
158     return ccs;
159   }
160
161   public ConstraintCheck parseConstraintCheck(ParseNode pn) {
162     if (isNode(pn,"cons_check")) {
163       String specname=pn.getChild("name").getChild("identifier").getTerminal();
164       Vector[] args=parseConsArgumentList(pn);
165       ConstraintCheck cc=new ConstraintCheck(specname);
166       for(int i=0; i<args[0].size(); i++) {
167         cc.addVariable((String)args[0].get(i));
168         cc.addArgument((ExpressionNode)args[1].get(i));
169       }
170       return cc;
171     } else throw new Error();
172   }
173
174   public void parseParameterList(TaskDescriptor td, ParseNode pn) {
175
176     boolean optional;
177     ParseNode paramlist=pn.getChild("task_parameter_list");
178     if (paramlist==null)
179       return;
180     ParseNodeVector pnv=paramlist.getChildren();
181     for(int i=0; i<pnv.size(); i++) {
182       ParseNode paramn=pnv.elementAt(i);
183       if(paramn.getChild("optional")!=null) {
184         optional = true;
185         paramn = paramn.getChild("optional").getFirstChild();
186         System.out.println("OPTIONAL FOUND!!!!!!!");
187       } else { optional = false;
188                System.out.println("NOT OPTIONAL");}
189
190       TypeDescriptor type=parseTypeDescriptor(paramn);
191
192       String paramname=paramn.getChild("single").getTerminal();
193       FlagExpressionNode fen=null;
194       if (paramn.getChild("flag")!=null)
195         fen=parseFlagExpression(paramn.getChild("flag").getFirstChild());
196
197       ParseNode tagnode=paramn.getChild("tag");
198
199       TagExpressionList tel=null;
200       if (tagnode!=null) {
201         tel=parseTagExpressionList(tagnode);
202       }
203
204       td.addParameter(type,paramname,fen, tel, optional);
205     }
206   }
207
208   public TagExpressionList parseTagExpressionList(ParseNode pn) {
209     //BUG FIX: change pn.getChildren() to pn.getChild("tag_expression_list").getChildren()
210     //To test, feed in any input program that uses tags
211     ParseNodeVector pnv=pn.getChild("tag_expression_list").getChildren();
212     TagExpressionList tel=new TagExpressionList();
213     for(int i=0; i<pnv.size(); i++) {
214       ParseNode tn=pnv.elementAt(i);
215       String type=tn.getChild("type").getTerminal();
216       String name=tn.getChild("single").getTerminal();
217       tel.addTag(type, name);
218     }
219     return tel;
220   }
221
222   public ClassDescriptor parseTypeDecl(ParseNode pn) {
223     ClassDescriptor cn=new ClassDescriptor(pn.getChild("name").getTerminal());
224     if (!isEmpty(pn.getChild("super").getTerminal())) {
225       /* parse superclass name */
226       ParseNode snn=pn.getChild("super").getChild("type").getChild("class").getChild("name");
227       NameDescriptor nd=parseName(snn);
228       cn.setSuper(nd.toString());
229     } else {
230       if (!(cn.getSymbol().equals(TypeUtil.ObjectClass)||
231             cn.getSymbol().equals(TypeUtil.TagClass)))
232         cn.setSuper(TypeUtil.ObjectClass);
233     }
234     cn.setModifiers(parseModifiersList(pn.getChild("modifiers")));
235     parseClassBody(cn, pn.getChild("classbody"));
236     return cn;
237   }
238
239   private void parseClassBody(ClassDescriptor cn, ParseNode pn) {
240     ParseNode decls=pn.getChild("class_body_declaration_list");
241     if (decls!=null) {
242       ParseNodeVector pnv=decls.getChildren();
243       for(int i=0; i<pnv.size(); i++) {
244         ParseNode decl=pnv.elementAt(i);
245         if (isNode(decl,"member")) {
246           parseClassMember(cn,decl);
247         } else if (isNode(decl,"constructor")) {
248           parseConstructorDecl(cn,decl.getChild("constructor_declaration"));
249         } else if (isNode(decl,"block")) {
250         } else throw new Error();
251       }
252     }
253   }
254
255   private void parseClassMember(ClassDescriptor cn, ParseNode pn) {
256     ParseNode fieldnode=pn.getChild("field");
257
258     if (fieldnode!=null) {
259       parseFieldDecl(cn,fieldnode.getChild("field_declaration"));
260       return;
261     }
262     ParseNode methodnode=pn.getChild("method");
263     if (methodnode!=null) {
264       parseMethodDecl(cn,methodnode.getChild("method_declaration"));
265       return;
266     }
267     ParseNode flagnode=pn.getChild("flag");
268     if (flagnode!=null) {
269       parseFlagDecl(cn, flagnode.getChild("flag_declaration"));
270       return;
271     }
272     throw new Error();
273   }
274
275   private TypeDescriptor parseTypeDescriptor(ParseNode pn) {
276     ParseNode tn=pn.getChild("type");
277     String type_st=tn.getTerminal();
278     if(type_st.equals("byte")) {
279       return state.getTypeDescriptor(TypeDescriptor.BYTE);
280     } else if(type_st.equals("short")) {
281       return state.getTypeDescriptor(TypeDescriptor.SHORT);
282     } else if(type_st.equals("boolean")) {
283       return state.getTypeDescriptor(TypeDescriptor.BOOLEAN);
284     } else if(type_st.equals("int")) {
285       return state.getTypeDescriptor(TypeDescriptor.INT);
286     } else if(type_st.equals("long")) {
287       return state.getTypeDescriptor(TypeDescriptor.LONG);
288     } else if(type_st.equals("char")) {
289       return state.getTypeDescriptor(TypeDescriptor.CHAR);
290     } else if(type_st.equals("float")) {
291       return state.getTypeDescriptor(TypeDescriptor.FLOAT);
292     } else if(type_st.equals("double")) {
293       return state.getTypeDescriptor(TypeDescriptor.DOUBLE);
294     } else if(type_st.equals("class")) {
295       ParseNode nn=tn.getChild("class");
296       return state.getTypeDescriptor(parseName(nn.getChild("name")));
297     } else if(type_st.equals("array")) {
298       ParseNode nn=tn.getChild("array");
299       TypeDescriptor td=parseTypeDescriptor(nn.getChild("basetype"));
300       Integer numdims=(Integer)nn.getChild("dims").getLiteral();
301       for(int i=0; i<numdims.intValue(); i++)
302         td=td.makeArray(state);
303       return td;
304     } else {
305       throw new Error();
306     }
307   }
308
309   private NameDescriptor parseName(ParseNode nn) {
310     ParseNode base=nn.getChild("base");
311     ParseNode id=nn.getChild("identifier");
312     if (base==null)
313       return new NameDescriptor(id.getTerminal());
314     return new NameDescriptor(parseName(base.getChild("name")),id.getTerminal());
315
316   }
317
318   private void parseFlagDecl(ClassDescriptor cn,ParseNode pn) {
319     String name=pn.getChild("name").getTerminal();
320     FlagDescriptor flag=new FlagDescriptor(name);
321     if (pn.getChild("external")!=null)
322       flag.makeExternal();
323     cn.addFlag(flag);
324   }
325
326   private void parseFieldDecl(ClassDescriptor cn,ParseNode pn) {
327     ParseNode mn=pn.getChild("modifier");
328     Modifiers m=parseModifiersList(mn);
329
330     ParseNode tn=pn.getChild("type");
331     TypeDescriptor t=parseTypeDescriptor(tn);
332     ParseNode vn=pn.getChild("variables").getChild("variable_declarators_list");
333     ParseNodeVector pnv=vn.getChildren();
334     boolean isglobal=pn.getChild("global")!=null;
335
336     for(int i=0; i<pnv.size(); i++) {
337       ParseNode vardecl=pnv.elementAt(i);
338       ParseNode tmp=vardecl;
339       TypeDescriptor arrayt=t;
340       while (tmp.getChild("single")==null) {
341         arrayt=arrayt.makeArray(state);
342         tmp=tmp.getChild("array");
343       }
344       String identifier=tmp.getChild("single").getTerminal();
345       ParseNode epn=vardecl.getChild("initializer");
346
347       ExpressionNode en=null;
348       if (epn!=null)
349         en=parseExpression(epn.getFirstChild());
350
351       cn.addField(new FieldDescriptor(m, arrayt, identifier, en, isglobal));
352     }
353   }
354
355   private ExpressionNode parseExpression(ParseNode pn) {
356     if (isNode(pn,"assignment"))
357       return parseAssignmentExpression(pn);
358     else if (isNode(pn,"logical_or")||isNode(pn,"logical_and")||
359              isNode(pn,"bitwise_or")||isNode(pn,"bitwise_xor")||
360              isNode(pn,"bitwise_and")||isNode(pn,"equal")||
361              isNode(pn,"not_equal")||isNode(pn,"comp_lt")||
362              isNode(pn,"comp_lte")||isNode(pn,"comp_gt")||
363              isNode(pn,"comp_gte")||isNode(pn,"leftshift")||
364              isNode(pn,"rightshift")||isNode(pn,"sub")||
365              isNode(pn,"urightshift")||isNode(pn,"sub")||
366              isNode(pn,"add")||isNode(pn,"mult")||
367              isNode(pn,"div")||isNode(pn,"mod")) {
368       ParseNodeVector pnv=pn.getChildren();
369       ParseNode left=pnv.elementAt(0);
370       ParseNode right=pnv.elementAt(1);
371       Operation op=new Operation(pn.getLabel());
372       return new OpNode(parseExpression(left),parseExpression(right),op);
373     } else if (isNode(pn,"unaryplus")||
374                isNode(pn,"unaryminus")||
375                isNode(pn,"not")||
376                isNode(pn,"comp")) {
377       ParseNode left=pn.getFirstChild();
378       Operation op=new Operation(pn.getLabel());
379       return new OpNode(parseExpression(left),op);
380     } else if (isNode(pn,"postinc")||
381                isNode(pn,"postdec")) {
382       ParseNode left=pn.getFirstChild();
383       AssignOperation op=new AssignOperation(pn.getLabel());
384       return new AssignmentNode(parseExpression(left),null,op);
385
386     } else if (isNode(pn,"preinc")||
387                isNode(pn,"predec")) {
388       ParseNode left=pn.getFirstChild();
389       AssignOperation op=isNode(pn,"preinc") ? new AssignOperation(AssignOperation.PLUSEQ) : new AssignOperation(AssignOperation.MINUSEQ);
390       return new AssignmentNode(parseExpression(left),
391                                 new LiteralNode("integer",new Integer(1)),op);
392     } else if (isNode(pn,"literal")) {
393       String literaltype=pn.getTerminal();
394       ParseNode literalnode=pn.getChild(literaltype);
395       Object literal_obj=literalnode.getLiteral();
396       return new LiteralNode(literaltype, literal_obj);
397     } else if (isNode(pn,"createobject")) {
398       TypeDescriptor td=parseTypeDescriptor(pn);
399       Vector args=parseArgumentList(pn);
400       boolean isglobal=pn.getChild("global")!=null;
401       String disjointId=null;
402       if( pn.getChild("disjoint") != null) {
403         disjointId = pn.getChild("disjoint").getTerminal();
404       }
405       CreateObjectNode con=new CreateObjectNode(td, isglobal, disjointId);
406       for(int i=0; i<args.size(); i++) {
407         con.addArgument((ExpressionNode)args.get(i));
408       }
409       /* Could have flag set or tag added here */
410       if (pn.getChild("flag_list")!=null||pn.getChild("tag_list")!=null) {
411         FlagEffects fe=new FlagEffects(null);
412         if (pn.getChild("flag_list")!=null)
413           parseFlagEffect(fe, pn.getChild("flag_list"));
414
415         if (pn.getChild("tag_list")!=null)
416           parseTagEffect(fe, pn.getChild("tag_list"));
417         con.addFlagEffects(fe);
418       }
419
420       return con;
421     } else if (isNode(pn,"createarray")) {
422       //System.out.println(pn.PPrint(3,true));
423       boolean isglobal=pn.getChild("global")!=null;
424       String disjointId=null;
425       if( pn.getChild("disjoint") != null) {
426         disjointId = pn.getChild("disjoint").getTerminal();
427       }
428       TypeDescriptor td=parseTypeDescriptor(pn);
429       Vector args=parseDimExprs(pn);
430       int num=0;
431       if (pn.getChild("dims_opt").getLiteral()!=null)
432         num=((Integer)pn.getChild("dims_opt").getLiteral()).intValue();
433       for(int i=0; i<(args.size()+num); i++)
434         td=td.makeArray(state);
435       CreateObjectNode con=new CreateObjectNode(td, isglobal, disjointId);
436       for(int i=0; i<args.size(); i++) {
437         con.addArgument((ExpressionNode)args.get(i));
438       }
439       return con;
440     } else if (isNode(pn,"name")) {
441       NameDescriptor nd=parseName(pn);
442       return new NameNode(nd);
443     } else if (isNode(pn,"this")) {
444       NameDescriptor nd=new NameDescriptor("this");
445       return new NameNode(nd);
446     } else if (isNode(pn,"isavailable")) {
447       NameDescriptor nd=new NameDescriptor(pn.getTerminal());
448       return new OpNode(new NameNode(nd),null,new Operation(Operation.ISAVAILABLE));
449     } else if (isNode(pn,"methodinvoke1")) {
450       NameDescriptor nd=parseName(pn.getChild("name"));
451       Vector args=parseArgumentList(pn);
452       MethodInvokeNode min=new MethodInvokeNode(nd);
453       for(int i=0; i<args.size(); i++) {
454         min.addArgument((ExpressionNode)args.get(i));
455       }
456       return min;
457     } else if (isNode(pn,"methodinvoke2")) {
458       String methodid=pn.getChild("id").getTerminal();
459       ExpressionNode exp=parseExpression(pn.getChild("base").getFirstChild());
460       Vector args=parseArgumentList(pn);
461       MethodInvokeNode min=new MethodInvokeNode(methodid,exp);
462       for(int i=0; i<args.size(); i++) {
463         min.addArgument((ExpressionNode)args.get(i));
464       }
465       return min;
466     } else if (isNode(pn,"fieldaccess")) {
467       ExpressionNode en=parseExpression(pn.getChild("base").getFirstChild());
468       String fieldname=pn.getChild("field").getTerminal();
469       return new FieldAccessNode(en,fieldname);
470     } else if (isNode(pn,"arrayaccess")) {
471       ExpressionNode en=parseExpression(pn.getChild("base").getFirstChild());
472       ExpressionNode index=parseExpression(pn.getChild("index").getFirstChild());
473       return new ArrayAccessNode(en,index);
474     } else if (isNode(pn,"cast1")) {
475       return new CastNode(parseTypeDescriptor(pn.getChild("type")),parseExpression(pn.getChild("exp").getFirstChild()));
476     } else if (isNode(pn,"cast2")) {
477       return new CastNode(parseExpression(pn.getChild("type").getFirstChild()),parseExpression(pn.getChild("exp").getFirstChild()));
478     } else if (isNode(pn, "getoffset")) {
479       TypeDescriptor td=parseTypeDescriptor(pn);
480       String fieldname = pn.getChild("field").getTerminal();
481       //System.out.println("Checking the values of: "+ " td.toString()= " + td.toString()+ "  fieldname= " + fieldname);
482       return new OffsetNode(td, fieldname);
483     } else if (isNode(pn, "tert")) {
484       return new TertiaryNode(parseExpression(pn.getChild("cond").getFirstChild()),
485                               parseExpression(pn.getChild("trueexpr").getFirstChild()),
486                               parseExpression(pn.getChild("falseexpr").getFirstChild()) );
487     } else if (isNode(pn, "instanceof")) {
488       ExpressionNode exp=parseExpression(pn.getChild("exp").getFirstChild());
489       TypeDescriptor t=parseTypeDescriptor(pn);
490       return new InstanceOfNode(exp,t);
491     } else {
492       System.out.println("---------------------");
493       System.out.println(pn.PPrint(3,true));
494       throw new Error();
495     }
496   }
497
498   private Vector parseDimExprs(ParseNode pn) {
499     Vector arglist=new Vector();
500     ParseNode an=pn.getChild("dim_exprs");
501     if (an==null)       /* No argument list */
502       return arglist;
503     ParseNodeVector anv=an.getChildren();
504     for(int i=0; i<anv.size(); i++) {
505       arglist.add(parseExpression(anv.elementAt(i)));
506     }
507     return arglist;
508   }
509
510   private Vector parseArgumentList(ParseNode pn) {
511     Vector arglist=new Vector();
512     ParseNode an=pn.getChild("argument_list");
513     if (an==null)       /* No argument list */
514       return arglist;
515     ParseNodeVector anv=an.getChildren();
516     for(int i=0; i<anv.size(); i++) {
517       arglist.add(parseExpression(anv.elementAt(i)));
518     }
519     return arglist;
520   }
521
522   private Vector[] parseConsArgumentList(ParseNode pn) {
523     Vector arglist=new Vector();
524     Vector varlist=new Vector();
525     ParseNode an=pn.getChild("cons_argument_list");
526     if (an==null)       /* No argument list */
527       return new Vector[] {varlist, arglist};
528     ParseNodeVector anv=an.getChildren();
529     for(int i=0; i<anv.size(); i++) {
530       ParseNode cpn=anv.elementAt(i);
531       ParseNode var=cpn.getChild("var");
532       ParseNode exp=cpn.getChild("exp").getFirstChild();
533       varlist.add(var.getTerminal());
534       arglist.add(parseExpression(exp));
535     }
536     return new Vector[] {varlist, arglist};
537   }
538
539   private ExpressionNode parseAssignmentExpression(ParseNode pn) {
540     AssignOperation ao=new AssignOperation(pn.getChild("op").getTerminal());
541     ParseNodeVector pnv=pn.getChild("args").getChildren();
542
543     AssignmentNode an=new AssignmentNode(parseExpression(pnv.elementAt(0)),parseExpression(pnv.elementAt(1)),ao);
544     return an;
545   }
546
547
548   private void parseMethodDecl(ClassDescriptor cn, ParseNode pn) {
549     ParseNode headern=pn.getChild("method_header");
550     ParseNode bodyn=pn.getChild("body");
551     MethodDescriptor md=parseMethodHeader(headern);
552     BlockNode bn=parseBlock(bodyn);
553     cn.addMethod(md);
554     state.addTreeCode(md,bn);
555   }
556
557   private void parseConstructorDecl(ClassDescriptor cn, ParseNode pn) {
558     ParseNode mn=pn.getChild("modifiers");
559     Modifiers m=parseModifiersList(mn);
560     ParseNode cdecl=pn.getChild("constructor_declarator");
561     boolean isglobal=cdecl.getChild("global")!=null;
562     String name=cdecl.getChild("name").getChild("identifier").getTerminal();
563     MethodDescriptor md=new MethodDescriptor(m, name, isglobal);
564     ParseNode paramnode=cdecl.getChild("parameters");
565     parseParameterList(md,paramnode);
566     ParseNode bodyn0=pn.getChild("body");
567     ParseNode bodyn=bodyn0.getChild("constructor_body");
568     cn.addMethod(md);
569     BlockNode bn=null;
570     if (bodyn!=null&&bodyn.getChild("block_statement_list")!=null)
571       bn=parseBlock(bodyn);
572     else
573       bn=new BlockNode();
574     if (bodyn!=null&&bodyn.getChild("superinvoke")!=null) {
575       ParseNode sin=bodyn.getChild("superinvoke");
576       NameDescriptor nd=new NameDescriptor("super");
577       Vector args=parseArgumentList(sin);
578       MethodInvokeNode min=new MethodInvokeNode(nd);
579       for(int i=0; i<args.size(); i++) {
580         min.addArgument((ExpressionNode)args.get(i));
581       }
582       BlockExpressionNode ben=new BlockExpressionNode(min);
583       bn.addFirstBlockStatement(ben);
584     }
585     state.addTreeCode(md,bn);
586   }
587
588   public BlockNode parseBlock(ParseNode pn) {
589     this.m_taskexitnum = 0;
590     if (pn==null||isEmpty(pn.getTerminal()))
591       return new BlockNode();
592     ParseNode bsn=pn.getChild("block_statement_list");
593     return parseBlockHelper(bsn);
594   }
595
596   private BlockNode parseBlockHelper(ParseNode pn) {
597     ParseNodeVector pnv=pn.getChildren();
598     BlockNode bn=new BlockNode();
599     for(int i=0; i<pnv.size(); i++) {
600       Vector bsv=parseBlockStatement(pnv.elementAt(i));
601       for(int j=0; j<bsv.size(); j++) {
602         bn.addBlockStatement((BlockStatementNode)bsv.get(j));
603       }
604     }
605     return bn;
606   }
607
608   public BlockNode parseSingleBlock(ParseNode pn) {
609     BlockNode bn=new BlockNode();
610     Vector bsv=parseBlockStatement(pn);
611     for(int j=0; j<bsv.size(); j++) {
612       bn.addBlockStatement((BlockStatementNode)bsv.get(j));
613     }
614     bn.setStyle(BlockNode.NOBRACES);
615     return bn;
616   }
617
618   public Vector parseSESEBlock(Vector parentbs, ParseNode pn) {
619     ParseNodeVector pnv=pn.getChildren();
620     Vector bv=new Vector();
621     for(int i=0; i<pnv.size(); i++) {
622       bv.addAll(parseBlockStatement(pnv.elementAt(i)));
623     }
624     return bv;
625   }
626
627   public Vector parseBlockStatement(ParseNode pn) {
628     Vector blockstatements=new Vector();
629     if (isNode(pn,"tag_declaration")) {
630       String name=pn.getChild("single").getTerminal();
631       String type=pn.getChild("type").getTerminal();
632
633       blockstatements.add(new TagDeclarationNode(name, type));
634     } else if (isNode(pn,"local_variable_declaration")) {
635       TypeDescriptor t=parseTypeDescriptor(pn);
636       ParseNode vn=pn.getChild("variable_declarators_list");
637       ParseNodeVector pnv=vn.getChildren();
638       for(int i=0; i<pnv.size(); i++) {
639         ParseNode vardecl=pnv.elementAt(i);
640
641
642         ParseNode tmp=vardecl;
643         TypeDescriptor arrayt=t;
644         while (tmp.getChild("single")==null) {
645           arrayt=arrayt.makeArray(state);
646           tmp=tmp.getChild("array");
647         }
648         String identifier=tmp.getChild("single").getTerminal();
649
650         ParseNode epn=vardecl.getChild("initializer");
651
652
653         ExpressionNode en=null;
654         if (epn!=null)
655           en=parseExpression(epn.getFirstChild());
656
657         blockstatements.add(new DeclarationNode(new VarDescriptor(arrayt, identifier),en));
658       }
659     } else if (isNode(pn,"nop")) {
660       /* Do Nothing */
661     } else if (isNode(pn,"expression")) {
662       blockstatements.add(new BlockExpressionNode(parseExpression(pn.getFirstChild())));
663     } else if (isNode(pn,"ifstatement")) {
664       blockstatements.add(new IfStatementNode(parseExpression(pn.getChild("condition").getFirstChild()),
665                                               parseSingleBlock(pn.getChild("statement").getFirstChild()),
666                                               pn.getChild("else_statement")!=null ? parseSingleBlock(pn.getChild("else_statement").getFirstChild()) : null));
667     } else if (isNode(pn,"taskexit")) {
668       Vector vfe=null;
669       if (pn.getChild("flag_effects_list")!=null)
670         vfe=parseFlags(pn.getChild("flag_effects_list"));
671       Vector ccs=null;
672       if (pn.getChild("cons_checks")!=null)
673         ccs=parseChecks(pn.getChild("cons_checks"));
674
675       blockstatements.add(new TaskExitNode(vfe, ccs, this.m_taskexitnum++));
676     } else if (isNode(pn,"atomic")) {
677       BlockNode bn=parseBlockHelper(pn);
678       blockstatements.add(new AtomicNode(bn));
679     } else if (isNode(pn,"return")) {
680       if (isEmpty(pn.getTerminal()))
681         blockstatements.add(new ReturnNode());
682       else {
683         ExpressionNode en=parseExpression(pn.getFirstChild());
684         blockstatements.add(new ReturnNode(en));
685       }
686     } else if (isNode(pn,"block_statement_list")) {
687       BlockNode bn=parseBlockHelper(pn);
688       blockstatements.add(new SubBlockNode(bn));
689     } else if (isNode(pn,"empty")) {
690       /* nop */
691     } else if (isNode(pn,"statement_expression_list")) {
692       ParseNodeVector pnv=pn.getChildren();
693       BlockNode bn=new BlockNode();
694       for(int i=0; i<pnv.size(); i++) {
695         ExpressionNode en=parseExpression(pnv.elementAt(i));
696         blockstatements.add(new BlockExpressionNode(en));
697       }
698       bn.setStyle(BlockNode.EXPRLIST);
699     } else if (isNode(pn,"forstatement")) {
700       BlockNode init=parseSingleBlock(pn.getChild("initializer").getFirstChild());
701       BlockNode update=parseSingleBlock(pn.getChild("update").getFirstChild());
702       ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
703       BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
704       blockstatements.add(new LoopNode(init,condition,update,body));
705     } else if (isNode(pn,"whilestatement")) {
706       ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
707       BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
708       blockstatements.add(new LoopNode(condition,body,LoopNode.WHILELOOP));
709     } else if (isNode(pn,"dowhilestatement")) {
710       ExpressionNode condition=parseExpression(pn.getChild("condition").getFirstChild());
711       BlockNode body=parseSingleBlock(pn.getChild("statement").getFirstChild());
712       blockstatements.add(new LoopNode(condition,body,LoopNode.DOWHILELOOP));
713     } else if (isNode(pn,"sese")) {
714       SESENode start=new SESENode();
715       SESENode end  =new SESENode();
716       start.setEnd( end   );
717       end.setStart( start );
718       blockstatements.add(start);
719       blockstatements.addAll(parseSESEBlock(blockstatements,pn.getChild("body").getFirstChild()));
720       blockstatements.add(end);
721     } else if (isNode(pn,"continue")) {
722         blockstatements.add(new ContinueBreakNode(false));
723     } else if (isNode(pn,"break")) {
724         blockstatements.add(new ContinueBreakNode(true));
725
726     } else {
727       System.out.println("---------------");
728       System.out.println(pn.PPrint(3,true));
729       throw new Error();
730     }
731     return blockstatements;
732   }
733
734   public MethodDescriptor parseMethodHeader(ParseNode pn) {
735     ParseNode mn=pn.getChild("modifiers");
736     Modifiers m=parseModifiersList(mn);
737
738     ParseNode tn=pn.getChild("returntype");
739     TypeDescriptor returntype;
740     if (tn!=null)
741       returntype=parseTypeDescriptor(tn);
742     else
743       returntype=new TypeDescriptor(TypeDescriptor.VOID);
744
745     ParseNode pmd=pn.getChild("method_declarator");
746     String name=pmd.getChild("name").getTerminal();
747     MethodDescriptor md=new MethodDescriptor(m, returntype, name);
748
749     ParseNode paramnode=pmd.getChild("parameters");
750     parseParameterList(md,paramnode);
751     return md;
752   }
753
754   public void parseParameterList(MethodDescriptor md, ParseNode pn) {
755     ParseNode paramlist=pn.getChild("formal_parameter_list");
756     if (paramlist==null)
757       return;
758     ParseNodeVector pnv=paramlist.getChildren();
759     for(int i=0; i<pnv.size(); i++) {
760       ParseNode paramn=pnv.elementAt(i);
761
762       if (isNode(paramn, "tag_parameter")) {
763         String paramname=paramn.getChild("single").getTerminal();
764         TypeDescriptor type=new TypeDescriptor(TypeDescriptor.TAG);
765         md.addTagParameter(type, paramname);
766       } else {
767         TypeDescriptor type=parseTypeDescriptor(paramn);
768
769         ParseNode tmp=paramn;
770         while (tmp.getChild("single")==null) {
771           type=type.makeArray(state);
772           tmp=tmp.getChild("array");
773         }
774         String paramname=tmp.getChild("single").getTerminal();
775
776         md.addParameter(type, paramname);
777       }
778     }
779   }
780
781   public Modifiers parseModifiersList(ParseNode pn) {
782     Modifiers m=new Modifiers();
783     ParseNode modlist=pn.getChild("modifier_list");
784     if (modlist!=null) {
785       ParseNodeVector pnv=modlist.getChildren();
786       for(int i=0; i<pnv.size(); i++) {
787         ParseNode modn=pnv.elementAt(i);
788         if (isNode(modn,"public"))
789           m.addModifier(Modifiers.PUBLIC);
790         else if (isNode(modn,"protected"))
791           m.addModifier(Modifiers.PROTECTED);
792         else if (isNode(modn,"private"))
793           m.addModifier(Modifiers.PRIVATE);
794         else if (isNode(modn,"static"))
795           m.addModifier(Modifiers.STATIC);
796         else if (isNode(modn,"final"))
797           m.addModifier(Modifiers.FINAL);
798         else if (isNode(modn,"native"))
799           m.addModifier(Modifiers.NATIVE);
800         else if (isNode(modn,"synchronized"))
801           m.addModifier(Modifiers.SYNCHRONIZED);
802         else if (isNode(modn,"atomic"))
803           m.addModifier(Modifiers.ATOMIC);
804         else throw new Error("Unrecognized Modifier");
805       }
806     }
807     return m;
808   }
809
810   private boolean isNode(ParseNode pn, String label) {
811     if (pn.getLabel().equals(label))
812       return true;
813     else return false;
814   }
815
816   private static boolean isEmpty(ParseNode pn) {
817     if (pn.getLabel().equals("empty"))
818       return true;
819     else
820       return false;
821   }
822
823   private static boolean isEmpty(String s) {
824     if (s.equals("empty"))
825       return true;
826     else
827       return false;
828   }
829
830   /** Throw an exception if something is unexpected */
831   private void check(ParseNode pn, String label) {
832     if (pn == null) {
833       throw new Error(pn+ "IE: Expected '" + label + "', got null");
834     }
835     if (!pn.getLabel().equals(label)) {
836       throw new Error(pn+ "IE: Expected '" + label + "', got '"+pn.getLabel()+"'");
837     }
838   }
839 }