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