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