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