// for inner classes
boolean isInnerClass=false;
+
+ // inner classes/enum can have these
String surroundingclass=null;
ClassDescriptor surroudingdesc=null;
SymbolTable innerdescs;
+
+ // for enum type
+ boolean isEnum = false;
+ SymbolTable enumdescs;
+ HashMap<String, Integer> enumConstantTbl;
+ int enumconstantid = 0;
public ClassDescriptor(String classname, boolean isInterface) {
this("", classname, isInterface);
superinterfaces = new Vector<String>();
superIFdesc = new SymbolTable();
this.innerdescs = new SymbolTable();
+ this.enumdescs = new SymbolTable();
}
public int getId() {
}
if (printcr)
st+="\n";
+
+ for(Iterator it=this.getEnum(); it.hasNext();) {
+ ClassDescriptor icd = (ClassDescriptor)it.next();
+ st += icd.getModifier().toString() + " enum " + icd.getSymbol() + " {\n ";
+ Set keys = icd.getEnumConstantTbl().keySet();
+ String[] econstants = new String[keys.size()];
+ Iterator it_keys = keys.iterator();
+ while(it_keys.hasNext()) {
+ String key = (String)it_keys.next();
+ econstants[icd.getEnumConstant(key)] = key;
+ }
+ for(int i = 0; i < econstants.length; i++) {
+ st += econstants[i];
+ if(i < econstants.length-1) {
+ st += ", ";
+ }
+ }
+ st+="\n}\n";
+ printcr=true;
+ }
+ if (printcr)
+ st+="\n";
for(Iterator it=getMethods(); it.hasNext();) {
MethodDescriptor md=(MethodDescriptor)it.next();
throw new Error(fd.getSymbol()+" already defined");
fields.add(fd);
fieldvec.add(fd);
- if(fd.isStatic()) {
+ if((fd.isStatic()) || (fd.isVolatile())) {
this.incStaticFields();
}
}
return this.innerdescs;
}
- /*public String getSymbol() {
- if(this.isInnerClass) {
- return this.surroudingdesc.getSymbol() + "." + name;
+ public void setAsEnum() {
+ this.isEnum = true;
+ }
+
+ public boolean isEnum() {
+ return this.isEnum;
+ }
+
+ public void addEnum(ClassDescriptor icd) {
+ this.enumdescs.add(icd);
+ }
+
+ public Iterator getEnum() {
+ return this.enumdescs.getDescriptorsIterator();
+ }
+
+ public SymbolTable getEnumTable() {
+ return this.enumdescs;
+ }
+
+ public void addEnumConstant(String econstant) {
+ if(this.enumConstantTbl == null) {
+ this.enumConstantTbl = new HashMap<String, Integer>();
+ }
+ if(this.enumConstantTbl.containsKey(econstant)) {
+ return;
} else {
- return name;
+ this.enumConstantTbl.put(econstant, this.enumconstantid++);
}
+ return;
}
-
- public String getSafeSymbol() {
- if(this.isInnerClass) {
- return this.surroudingdesc.getSafeSymbol()+ "." + safename;
+
+ public int getEnumConstant(String econstant) {
+ if(this.enumConstantTbl.containsKey(econstant)) {
+ return this.enumConstantTbl.get(econstant).intValue();
} else {
- return safename;
+ return -1;
}
- }*/
+ }
+
+ public HashMap<String, Integer> getEnumConstantTbl() {
+ return this.enumConstantTbl;
+ }
+
+ public Modifiers getModifier() {
+ return this.modifiers;
+ }
}
return modifier.isStatic();
}
+ public boolean isVolatile() {
+ return modifier.isVolatile();
+ }
+
public boolean isGlobal() {
return isglobal;
}
else if ((state.MGC) && (fd.isStatic())) {
// TODO add version for normal Java later
// static field
- globaldefout.println(" "+fd.getType().getSafeSymbol()+ " "+cn.getSafeSymbol()+fd.getSafeSymbol()+";");
+ if(fd.isVolatile()) {
+ globaldefout.println(" volatile "+fd.getType().getSafeSymbol()+ " "+cn.getSafeSymbol()+fd.getSafeSymbol()+";");
+ } else {
+ globaldefout.println(" "+fd.getType().getSafeSymbol()+ " "+cn.getSafeSymbol()+fd.getSafeSymbol()+";");
+ }
+ classdefout.println(" "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
+ } else if ((state.MGC) && (fd.isVolatile())) {
+ // TODO add version for normal Java later
+ // static field
+ globaldefout.println(" volatile "+fd.getType().getSafeSymbol()+ " "+cn.getSafeSymbol()+fd.getSafeSymbol()+";");
classdefout.println(" "+fd.getType().getSafeSymbol()+" * "+fd.getSafeSymbol()+";");
} else
classdefout.println(" "+fd.getType().getSafeSymbol()+" "+fd.getSafeSymbol()+";");
for(int i=0; i<fields.size(); i++) {
FieldDescriptor fd=(FieldDescriptor)fields.get(i);
- if(fd.isStatic()) {
- // static field
+ if((fd.isStatic()) || (fd.isVolatile())) {
+ // static/volatile field
output.println(generateTemp(fm,fm.getParameter(0),lb)+"->"+fd.getSafeSymbol()+"=&(global_defs_p->"+cn.getSafeSymbol()+fd.getSafeSymbol()+");");
}
}
// DEBUG }
if(state.MGC) {
// TODO add version for normal Java later
- if(ffn.getField().isStatic()) {
+ if((ffn.getField().isStatic()) || (ffn.getField().isVolatile())) {
// static field
if((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic())) {
// is a static block or is invoked in some static block
// DEBUG }
if(state.MGC) {
// TODO add version for normal Java later
- if(fsfn.getField().isStatic()) {
+ if((fsfn.getField().isStatic()) || (fsfn.getField().isVolatile())) {
// static field
if((fm.getMethod().isStaticBlock()) || (fm.getMethod().isInvokedByStatic())) {
// is a static block or is invoked in some static block
if (toanalyze!=null)
toanalyze.add(cn);
state.addClass(cn);
- // for inner classes
+ // for inner classes/enum
if(state.MGC) {
// TODO add version for normal Java later
HashSet tovisit = new HashSet();
while(it_ics.hasNext()) {
tovisit.add(it_ics.next());
}
+
+ Iterator it_ienums = cd.getEnum();
+ while(it_ienums.hasNext()) {
+ ClassDescriptor iecd = (ClassDescriptor)it_ienums.next();
+ if(toanalyze != null) {
+ toanalyze.add(iecd);
+ }
+ state.addClass(iecd);
+ }
+ }
+
+ Iterator it_enums = cn.getEnum();
+ while(it_enums.hasNext()) {
+ ClassDescriptor ecd = (ClassDescriptor)it_enums.next();
+ if(toanalyze != null) {
+ toanalyze.add(ecd);
+ }
+ state.addClass(ecd);
}
}
} else if (isNode(type_pn,"task_declaration")) {
if (toanalyze!=null)
toanalyze.add(cn);
state.addClass(cn);
+
+ // for enum
+ if(state.MGC) {
+ // TODO add version for normal Java later
+ Iterator it_enums = cn.getEnum();
+ while(it_enums.hasNext()) {
+ ClassDescriptor ecd = (ClassDescriptor)it_enums.next();
+ if(toanalyze != null) {
+ toanalyze.add(ecd);
+ }
+ state.addClass(ecd);
+ }
+ }
+ } else if ((state.MGC) && isNode(type_pn,"enum_declaration")) {
+ // TODO add version for normal Java later
+ ClassDescriptor cn = parseEnumDecl(null, type_pn);
+ if (toanalyze!=null)
+ toanalyze.add(cn);
+ state.addClass(cn);
} else {
throw new Error(type_pn.getLabel());
}
}
}
+ private ClassDescriptor parseEnumDecl(ClassDescriptor cn, ParseNode pn) {
+ ClassDescriptor ecd=new ClassDescriptor(pn.getChild("name").getTerminal(), false);
+ ecd.setAsEnum();
+ if(cn != null) {
+ ecd.setSurroundingClass(cn.getSymbol());
+ ecd.setSurrounding(cn);
+ }
+ cn.addEnum(ecd);
+ if (!(ecd.getSymbol().equals(TypeUtil.ObjectClass)||
+ ecd.getSymbol().equals(TypeUtil.TagClass))) {
+ ecd.setSuper(TypeUtil.ObjectClass);
+ }
+ ecd.setModifiers(parseModifiersList(pn.getChild("modifiers")));
+ parseEnumBody(ecd, pn.getChild("enumbody"));
+ return ecd;
+ }
+
+ private void parseEnumBody(ClassDescriptor cn, ParseNode pn) {
+ ParseNode decls=pn.getChild("enum_constants_list");
+ if (decls!=null) {
+ ParseNodeVector pnv=decls.getChildren();
+ for(int i=0; i<pnv.size(); i++) {
+ ParseNode decl=pnv.elementAt(i);
+ if (isNode(decl,"enum_constant")) {
+ parseEnumConstant(cn,decl);
+ } else throw new Error();
+ }
+ }
+ }
+
+ private void parseEnumConstant(ClassDescriptor cn, ParseNode pn) {
+ cn.addEnumConstant(pn.getChild("name").getTerminal());
+ }
+
public ClassDescriptor parseInterfaceDecl(ParseNode pn) {
ClassDescriptor cn=new ClassDescriptor(pn.getChild("name").getTerminal(), true);
//cn.setAsInterface();
throw new Error("Error: inner class in Class " + cn.getSymbol() + " is not supported yet");
}
}
+ ParseNode enumnode=pn.getChild("enum_declaration");
+ if (enumnode!=null) {
+ if(state.MGC){
+ parseEnumDecl(cn,enumnode);
+ return;
+ } else {
+ // TODO add version for noraml Java later
+ throw new Error("Error: enumerated type in Class " + cn.getSymbol() + " is not supported yet");
+ }
+ }
ParseNode flagnode=pn.getChild("flag");
if (flagnode!=null) {
parseFlagDecl(cn, flagnode.getChild("flag_declaration"));
m.addModifier(Modifiers.ATOMIC);
else if (isNode(modn,"abstract"))
m.addModifier(Modifiers.ABSTRACT);
+ else if (isNode(modn,"volatile"))
+ m.addModifier(Modifiers.VOLATILE);
else throw new Error("Unrecognized Modifier");
}
}
public static final int NATIVE=64;
public static final int SYNCHRONIZED=128;
// TRANSIENT=256
-// VOLATILE=512
+ public static final int VOLATILE=512;
// STRICTFP=1024
public static final int ATOMIC=2048;
public boolean isFinal() {
return ((value&FINAL)!=0);
}
+
+ public boolean isVolatile() {
+ return ((value&VOLATILE)!= 0);
+ }
public String toString() {
String st="";
st+="atomic ";
if ((value&ABSTRACT)!=0)
st+="abstract ";
+ if((value&VOLATILE)!=0)
+ st += "volatile ";
return st;
}
}
cd = ((MethodDescriptor)md).getClassDesc();
SymbolTable fieldtbl = cd.getFieldTable();
FieldDescriptor fd=(FieldDescriptor)fieldtbl.get(varname);
- if((fd == null) || (!fd.isStatic())){
+ if((fd == null) || (!fd.isStatic()) || (!fd.isVolatile())){
// no such field in the class or it is not a static field
throw new Error("Name "+varname+" should not be used in static block: "+md);
} else {
terminal RBLOCK;
non terminal ParseNode sese_statement;
+// mgc
+// JSR-201) Enum Declaration
+non terminal ParseNode enum_declaration;
+non terminal ParseNode enum_body, enum_constants_opt, enum_constants, enum_constant;
+//non terminal ParseNode enum_arguments_opt, enum_body_declarations_opt;
+
start with goal;
{:
RESULT=cd;
:}
+ | enum_declaration:ed
+ {:
+ RESULT=ed;
+ :}
| task_declaration:td
{:
RESULT=td;
FINAL {: RESULT=new ParseNode("final"); :}|
NATIVE {: RESULT=new ParseNode("native"); :} |
SYNCHRONIZED {: RESULT=new ParseNode("synchronized"); :} |
- ATOMIC {: RESULT=new ParseNode("atomic"); :}
+ ATOMIC {: RESULT=new ParseNode("atomic"); :} |
+ VOLATILE {: RESULT=new ParseNode("volatile"); :}
// TRANSIENT |
-// VOLATILE |
+
// STRICTFP // note that semantic analysis must check that the
// context of the modifier allows strictfp.
;
pn.addChild("classbody").addChild(body);
RESULT=pn;
:}
+ | enum_declaration:ed
+ {:
+ RESULT=ed;
+ :}
// | interface_declaration:interfaced {:
// RESULT=(new ParseNode("interface")).addChild(interfaced).getRoot();
// :}
| SEMICOLON {: RESULT=new ParseNode("empty"); :}
;
+
+// mgc
+// JSR-201) Enum Declaration
+enum_declaration ::=
+ modifiers_opt:mo ENUM IDENTIFIER:id /*interfaces_opt:io*/ enum_body:body
+ {:
+ ParseNode pn=new ParseNode("enum_declaration");
+ pn.addChild("modifiers").addChild(mo);
+ pn.addChild("name").addChild(id);
+ //pn.addChild("superIF").addChild(ifo);
+ pn.addChild("enumbody").addChild(body);
+ RESULT=pn;
+ :}
+ ;
+enum_body ::=
+ LBRACE enum_constants_opt:eco /*enum_body_declarations_opt:ebdo*/ RBRACE
+ {: RESULT=eco; :}
+ ;
+enum_constants_opt ::=
+ {: RESULT=new ParseNode("empty"); :}
+ | enum_constants:ecs
+ {: RESULT=ecs; :}
+ ;
+enum_constants ::=
+ enum_constant:ec {:
+ ParseNode pn=new ParseNode("enum_constants_list");
+ pn.addChild(ec);
+ RESULT=pn;
+ :}
+ | enum_constants:ecs COMMA enum_constant:ec {:
+ ecs.addChild(ec);
+ RESULT=ecs;
+ :}
+ ;
+enum_constant ::=
+ IDENTIFIER:id /*enum_arguments_opt*/
+ {:
+ ParseNode pn=new ParseNode("enum_constant");
+ pn.addChild("name").addChild(id);
+ RESULT=pn;
+ :}
+// | IDENTIFIER enum_arguments_opt class_body
+ ;
+//enum_arguments_opt ::=
+// | LPAREN argument_list_opt RPAREN
+// ;
+//enum_body_declarations_opt ::=
+// | SEMICOLON class_body_declarations_opt:cbdo
+// ;
+
//Failure aware computation
flag_declaration ::=
| abstract_method_declaration:method {:
RESULT=(new ParseNode("method")).addChild(method).getRoot();
:}
+ | enum_declaration:ed {:
+ RESULT=(new ParseNode("enum_declaration")).addChild(ed).getRoot();
+ :}
// | class_declaration:class
// | interface_declaration:interface
| SEMICOLON {:
| statement:statement {:
RESULT=statement;
:}
+// | enum_declaration:ed {:
+// RESULT=ed;
+// :}
// | class_declaration
// | interface_declaration
;
expression ::= assignment_expression:exp {:
RESULT=exp; :}
;
+// note that this constraint must be enforced during semantic checking
+// 'constant_expression' should include enumerated constants.
//constant_expression ::=
// expression
// ;
--- /dev/null
+public enum Spiciness {
+ NOT, MILD, MEDIUM, HOT, FLAMING
+} ///:~
+
+public class EnumTest {
+
+ public EnumTest(){}
+
+ public static void main(String[] args) {
+ Spiciness howHot = Spiciness.MEDIUM;
+ System.out.println(howHot);
+ }
+} /* Output:
+MEDIUM
+*///:~
--- /dev/null
+public class VolatileTest extends Thread {
+ volatile int num;
+ String name;
+
+ {
+ num = 0;
+ }
+
+ public VolatileTest(String name) {
+ this.name = name;
+ }
+
+ public void run(){
+ if(name.equals("Thread1")){
+ num=10;
+ }
+ else{
+ System.out.println("value of num is :"+num);
+ }
+ }
+
+ public static void main(String args[]){
+ Thread t1 = new VolatileTest("Thread1");
+ t1.start();
+
+ Thread.sleep(1000);
+
+ Thread t2 = new VolatileTest("Thread2");
+ t2.start();
+ }
+}
\ No newline at end of file