diff --git a/group02/727171008/.classpath b/group02/727171008/.classpath
index 3e0fb272a8..429701a6eb 100644
--- a/group02/727171008/.classpath
+++ b/group02/727171008/.classpath
@@ -3,5 +3,6 @@
+
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/attr/CodeAttr.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/attr/CodeAttr.java
index 47a8bd2b1c..9ecd803572 100644
--- a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/attr/CodeAttr.java
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/attr/CodeAttr.java
@@ -1,6 +1,8 @@
package com.github.HarryHook.coding2017.jvm.attr;
import com.github.HarryHook.coding2017.jvm.clz.ClassFile;
+import com.github.HarryHook.coding2017.jvm.cmd.ByteCodeCommand;
+import com.github.HarryHook.coding2017.jvm.cmd.CommandParser;
import com.github.HarryHook.coding2017.jvm.constant.ConstantPool;
import com.github.HarryHook.coding2017.jvm.loader.ByteCodeIterator;
import com.sun.org.apache.bcel.internal.generic.NEW;
@@ -15,22 +17,24 @@ public String getCode() {
return code;
}
- // private ByteCodeCommand[] cmds ;
- // public ByteCodeCommand[] getCmds() {
- // return cmds;
- // }
+ private ByteCodeCommand[] cmds;
+
+ public ByteCodeCommand[] getCmds() {
+ return cmds;
+ }
+
private LineNumberTable lineNumTable;
private LocalVariableTable localVarTable;
private StackMapTable stackMapTable;
- public CodeAttr(int attrNameIndex, int attrLen, int maxStack, int maxLocals, int codeLen,
- String code /* ByteCodeCommand[] cmds */) {
+ public CodeAttr(int attrNameIndex, int attrLen, int maxStack, int maxLocals, int codeLen, String code,
+ ByteCodeCommand[] cmds) {
super(attrNameIndex, attrLen);
this.maxStack = maxStack;
this.maxLocals = maxLocals;
this.codeLen = codeLen;
this.code = code;
- // this.cmds = cmds;
+ this.cmds = cmds;
}
public void setLineNumberTable(LineNumberTable t) {
@@ -42,40 +46,44 @@ public void setLocalVariableTable(LocalVariableTable t) {
}
public static CodeAttr parse(ClassFile clzFile, ByteCodeIterator iter) {
-
+
int attrNameIndex = iter.nextU2ToInt();
int attrLen = iter.nextU4ToInt();
int maxStack = iter.nextU2ToInt();
int maxLocals = iter.nextU2ToInt();
int codeLen = iter.nextU4ToInt();
-
+
String code = iter.nextUxToHexString(codeLen);
System.out.println(code);
-
- CodeAttr codeAttr = new CodeAttr(attrNameIndex, attrLen, maxStack, maxLocals, codeLen, code);
-
+
+ ByteCodeCommand[] cmds = CommandParser.parse(clzFile, code);
+ CodeAttr codeAttr = new CodeAttr(attrNameIndex, attrLen, maxStack, maxLocals, codeLen, code, cmds);
+
int exceptionLength = iter.nextU2ToInt();
- if(exceptionLength > 0) {
+ if (exceptionLength > 0) {
String exceptionTable = iter.nextUxToHexString(exceptionLength);
System.out.println("exception Table has not complemented" + exceptionTable);
}
- //解析子属性
+ // 解析子属性
int subAttrCount = iter.nextU2ToInt();
-
- for(int j=1; j<=subAttrCount; j++) {
-
+
+ for (int j = 1; j <= subAttrCount; j++) {
+
int subAttrIndex = iter.nextU2ToInt();
String subAttrName = clzFile.getConstantPool().getUTF8String(subAttrIndex);
iter.back(2);
-
- if(AttributeInfo.LINE_NUM_TABLE.equalsIgnoreCase(subAttrName)) {
+
+ if (AttributeInfo.LINE_NUM_TABLE.equalsIgnoreCase(subAttrName)) {
LineNumberTable t = LineNumberTable.parse(iter);
codeAttr.setLineNumberTable(t);
-
- } else if(AttributeInfo.LOCAL_VAR_TABLE.equals(subAttrName)) {
+
+ } else if (AttributeInfo.LOCAL_VAR_TABLE.equals(subAttrName)) {
LocalVariableTable t = LocalVariableTable.parse(iter);
codeAttr.setLocalVariableTable(t);
-
+
+ } else if (AttributeInfo.STACK_MAP_TABLE.equalsIgnoreCase(subAttrName)) {
+ StackMapTable t = StackMapTable.parse(iter);
+ codeAttr.setStackMapTable(t);
} else {
throw new RuntimeException("Need implement" + subAttrName);
}
@@ -87,14 +95,17 @@ private void setStackMapTable(StackMapTable t) {
this.stackMapTable = t;
}
+
public String toString(ConstantPool pool) {
StringBuffer buffer = new StringBuffer();
- buffer.append("Code:").append(code).append("\n");
+ for(int i=0;i fields = new ArrayList();
- private List methods = new ArrayList();;
+ private List methods = new ArrayList();
public ClassIndex getClzIndex() {
return clzIndex;
}
+
public void setClzIndex(ClassIndex clzIndex) {
this.clzIndex = clzIndex;
}
+
public AccessFlag getAccessFlag() {
return accessFlag;
}
@@ -72,32 +73,61 @@ public void print() {
}
- private String getClassName() {
+ public String getClassName() {
int thisClassIndex = clzIndex.getThisClassIndex();
ClassInfo thisClass = (ClassInfo) this.getConstantPool().getConstantInfo(thisClassIndex);
return thisClass.getClassName();
}
- private String getSuperClassName() {
+ public String getSuperClassName() {
ClassInfo superClass = (ClassInfo) this.getConstantPool().getConstantInfo(this.clzIndex.getSuperClassIndex());
return superClass.getClassName();
}
-
+
public void addField(Field f) {
fields.add(f);
}
-
+
public List getFields() {
return fields;
}
-
+
public void addMethod(Method m) {
methods.add(m);
-
+
}
+
public List getMethods() {
return methods;
}
+ public Method getMethod(String methodName, String paramAndReturnType) {
+
+ for (Method m : methods) {
+
+ int nameIndex = m.getNameIndex();
+ int descriptionIndex = m.getDescriptorIndex();
+
+ String name = this.getConstantPool().getUTF8String(nameIndex);
+ String desc = this.getConstantPool().getUTF8String(descriptionIndex);
+ if (name.equals(methodName) && desc.equals(paramAndReturnType)) {
+ return m;
+ }
+ }
+ return null;
+ }
+
+ public Method getMainMethod() {
+ for (Method m : methods) {
+ int nameIndex = m.getNameIndex();
+ int descIndex = m.getDescriptorIndex();
+ String name = this.getConstantPool().getUTF8String(nameIndex);
+ String desc = this.getConstantPool().getUTF8String(descIndex);
+ if (name.equals("main") && desc.equals("([Ljava/lang/String;)V")) {
+ return m;
+ }
+ }
+ return null;
+ }
}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/BiPushCmd.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/BiPushCmd.java
new file mode 100644
index 0000000000..6b1c020682
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/BiPushCmd.java
@@ -0,0 +1,23 @@
+package com.github.HarryHook.coding2017.jvm.cmd;
+
+import com.github.HarryHook.coding2017.jvm.clz.ClassFile;
+import com.github.HarryHook.coding2017.jvm.constant.ConstantInfo;
+import com.github.HarryHook.coding2017.jvm.constant.ConstantPool;
+
+
+public class BiPushCmd extends OneOperandCmd {
+
+ public BiPushCmd(ClassFile clzFile,String opCode) {
+ super(clzFile,opCode);
+
+ }
+
+ @Override
+ public String toString(ConstantPool pool) {
+
+ return this.getOffset()+": "+ this.getOpCode()+" " + this.getReadableCodeText() + " " + this.getOperand();
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/ByteCodeCommand.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/ByteCodeCommand.java
new file mode 100644
index 0000000000..f5e6705a8a
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/ByteCodeCommand.java
@@ -0,0 +1,128 @@
+package com.github.HarryHook.coding2017.jvm.cmd;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.github.HarryHook.coding2017.jvm.clz.ClassFile;
+import com.github.HarryHook.coding2017.jvm.constant.ConstantInfo;
+import com.github.HarryHook.coding2017.jvm.constant.ConstantPool;
+
+
+public abstract class ByteCodeCommand {
+
+ String opCode;
+ ClassFile clzFile;
+ private int offset;
+
+ private static Map codeMap = new HashMap();
+
+ static{
+ codeMap.put("01", "aconst_null");
+
+ codeMap.put("BB", "new");
+ codeMap.put("37", "lstore");
+ codeMap.put("B7", "invokespecial");
+ codeMap.put("B6", "invokevirtual");
+ codeMap.put("B4", "getfield");
+ codeMap.put("B5", "putfield");
+ codeMap.put("B2", "getstatic");
+
+ codeMap.put("2A", "aload_0");
+ codeMap.put("2B", "aload_1");
+ codeMap.put("2C", "aload_2");
+
+ codeMap.put("10", "bipush");
+ codeMap.put("15", "iload");
+ codeMap.put("1A", "iload_0");
+ codeMap.put("1B", "iload_1");
+ codeMap.put("1C", "iload_2");
+ codeMap.put("1D", "iload_3");
+
+ codeMap.put("25", "fload_3");
+
+ codeMap.put("1E", "lload_0");
+
+ codeMap.put("24", "fload_2");
+ codeMap.put("4C", "astore_1");
+
+ codeMap.put("A2", "if_icmp_ge");
+ codeMap.put("A4", "if_icmple");
+
+ codeMap.put("A7", "goto");
+
+ codeMap.put("B1", "return");
+ codeMap.put("AC", "ireturn");
+ codeMap.put("AE", "freturn");
+
+ codeMap.put("03", "iconst_0");
+ codeMap.put("04", "iconst_1");
+
+ codeMap.put("3C", "istore_1");
+ codeMap.put("3D", "istore_2");
+
+ codeMap.put("59", "dup");
+
+ codeMap.put("60", "iadd");
+ codeMap.put("84", "iinc");
+
+ codeMap.put("12", "ldc");
+ }
+
+
+
+
+
+ protected ByteCodeCommand(ClassFile clzFile, String opCode){
+ this.clzFile = clzFile;
+ this.opCode = opCode;
+ }
+
+ protected ClassFile getClassFile() {
+ return clzFile;
+ }
+
+ public int getOffset() {
+ return offset;
+ }
+
+ public void setOffset(int offset) {
+ this.offset = offset;
+ }
+ protected ConstantInfo getConstantInfo(int index){
+ return this.getClassFile().getConstantPool().getConstantInfo(index);
+ }
+
+ protected ConstantPool getConstantPool(){
+ return this.getClassFile().getConstantPool();
+ }
+
+
+
+ public String getOpCode() {
+ return opCode;
+ }
+
+ public abstract int getLength();
+
+
+
+
+ public String toString(){
+
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(this.opCode);
+
+ return buffer.toString();
+ }
+ public abstract String toString(ConstantPool pool);
+
+ public String getReadableCodeText(){
+ String txt = codeMap.get(opCode);
+ if(txt == null){
+ return opCode;
+ }
+ return txt;
+ }
+
+ //public abstract void execute(StackFrame frame,FrameResult result);
+}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/CommandParser.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/CommandParser.java
new file mode 100644
index 0000000000..b982fa7aa4
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/CommandParser.java
@@ -0,0 +1,155 @@
+package com.github.HarryHook.coding2017.jvm.cmd;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.github.HarryHook.coding2017.jvm.clz.ClassFile;
+
+public class CommandParser {
+
+ public static final String aconst_null = "01";
+ public static final String new_object = "BB";
+ public static final String lstore = "37";
+ public static final String invokespecial = "B7";
+ public static final String invokevirtual = "B6";
+ public static final String getfield = "B4";
+ public static final String putfield = "B5";
+ public static final String getstatic = "B2";
+ public static final String ldc = "12";
+ public static final String dup = "59";
+ public static final String bipush = "10";
+ public static final String aload_0 = "2A";
+ public static final String aload_1 = "2B";
+ public static final String aload_2 = "2C";
+ public static final String iload = "15";
+ public static final String iload_1 = "1B";
+ public static final String iload_2 = "1C";
+ public static final String iload_3 = "1D";
+ public static final String fload_3 = "25";
+
+ public static final String voidreturn = "B1";
+ public static final String ireturn = "AC";
+ public static final String freturn = "AE";
+
+ public static final String astore_1 = "4C";
+ public static final String if_icmp_ge = "A2";
+ public static final String if_icmple = "A4";
+ public static final String goto_no_condition = "A7";
+ public static final String iconst_0 = "03";
+ public static final String iconst_1 = "04";
+ public static final String istore_1 = "3C";
+ public static final String istore_2 = "3D";
+ public static final String iadd = "60";
+ public static final String iinc = "84";
+
+ public static ByteCodeCommand[] parse(ClassFile clzFile, String codes) {
+
+ if ((codes == null) || (codes.length() == 0) || (codes.length() % 2) != 0) {
+ throw new RuntimeException("the orignal code is not correct");
+
+ }
+
+ codes = codes.toUpperCase();
+
+ CommandIterator iter = new CommandIterator(codes);
+ List cmds = new ArrayList();
+
+ while (iter.hasNext()) {
+ String opCode = iter.next2CharAsString();
+
+ if (new_object.equals(opCode)) {
+ NewObjectCmd cmd = new NewObjectCmd(clzFile, opCode);
+
+ cmd.setOprand1(iter.next2CharAsInt());
+ cmd.setOprand2(iter.next2CharAsInt());
+
+ cmds.add(cmd);
+ } else if (invokespecial.equals(opCode)) {
+ InvokeSpecialCmd cmd = new InvokeSpecialCmd(clzFile, opCode);
+ cmd.setOprand1(iter.next2CharAsInt());
+ cmd.setOprand2(iter.next2CharAsInt());
+ // System.out.println( cmd.toString(clzFile.getConstPool()));
+ cmds.add(cmd);
+ } else if (invokevirtual.equals(opCode)) {
+ InvokeVirtualCmd cmd = new InvokeVirtualCmd(clzFile, opCode);
+ cmd.setOprand1(iter.next2CharAsInt());
+ cmd.setOprand2(iter.next2CharAsInt());
+
+ cmds.add(cmd);
+ } else if (getfield.equals(opCode)) {
+ GetFieldCmd cmd = new GetFieldCmd(clzFile, opCode);
+ cmd.setOprand1(iter.next2CharAsInt());
+ cmd.setOprand2(iter.next2CharAsInt());
+ cmds.add(cmd);
+ } else if (getstatic.equals(opCode)) {
+ GetStaticFieldCmd cmd = new GetStaticFieldCmd(clzFile, opCode);
+ cmd.setOprand1(iter.next2CharAsInt());
+ cmd.setOprand2(iter.next2CharAsInt());
+ cmds.add(cmd);
+ } else if (putfield.equals(opCode)) {
+ PutFieldCmd cmd = new PutFieldCmd(clzFile, opCode);
+ cmd.setOprand1(iter.next2CharAsInt());
+ cmd.setOprand2(iter.next2CharAsInt());
+ cmds.add(cmd);
+ } else if (ldc.equals(opCode)) {
+ LdcCmd cmd = new LdcCmd(clzFile, opCode);
+ cmd.setOperand(iter.next2CharAsInt());
+ cmds.add(cmd);
+ } else if (bipush.equals(opCode)) {
+ BiPushCmd cmd = new BiPushCmd(clzFile, opCode);
+ cmd.setOperand(iter.next2CharAsInt());
+ cmds.add(cmd);
+ } else if (dup.equals(opCode) || aload_0.equals(opCode) || aload_1.equals(opCode) || aload_2.equals(opCode)
+ || iload_1.equals(opCode) || iload_2.equals(opCode) || iload_3.equals(opCode)
+ || fload_3.equals(opCode) || voidreturn.equals(opCode) || astore_1.equals(opCode)) {
+
+ NoOperandCmd cmd = new NoOperandCmd(clzFile, opCode);
+ cmds.add(cmd);
+ } else {
+ throw new RuntimeException("Sorry, the java instruction " + opCode + " has not been implemented");
+ }
+
+ }
+
+ calcuateOffset(cmds);
+
+ ByteCodeCommand[] result = new ByteCodeCommand[cmds.size()];
+ cmds.toArray(result);
+ return result;
+ }
+
+ private static void calcuateOffset(List cmds) {
+
+ int offset = 0;
+ for (ByteCodeCommand cmd : cmds) {
+ cmd.setOffset(offset);
+ offset += cmd.getLength();
+ }
+
+ }
+
+ private static class CommandIterator {
+ String codes = null;
+ int pos = 0;
+
+ CommandIterator(String codes) {
+ this.codes = codes;
+ }
+
+ public boolean hasNext() {
+ return pos < this.codes.length();
+ }
+
+ public String next2CharAsString() {
+ String result = codes.substring(pos, pos + 2);
+ pos += 2;
+ return result;
+ }
+
+ public int next2CharAsInt() {
+ String s = this.next2CharAsString();
+ return Integer.valueOf(s, 16).intValue();
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/GetFieldCmd.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/GetFieldCmd.java
new file mode 100644
index 0000000000..ec34e7b4a7
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/GetFieldCmd.java
@@ -0,0 +1,18 @@
+package com.github.HarryHook.coding2017.jvm.cmd;
+
+import com.github.HarryHook.coding2017.jvm.clz.ClassFile;
+import com.github.HarryHook.coding2017.jvm.constant.ConstantPool;
+
+public class GetFieldCmd extends TwoOperandCmd {
+
+ public GetFieldCmd(ClassFile clzFile, String opCode) {
+ super(clzFile, opCode);
+ }
+
+ @Override
+ public String toString(ConstantPool pool) {
+
+ return super.getOperandAsField(pool);
+ }
+
+}
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/GetStaticFieldCmd.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/GetStaticFieldCmd.java
new file mode 100644
index 0000000000..1090e17374
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/GetStaticFieldCmd.java
@@ -0,0 +1,24 @@
+package com.github.HarryHook.coding2017.jvm.cmd;
+
+
+import com.github.HarryHook.coding2017.jvm.clz.ClassFile;
+import com.github.HarryHook.coding2017.jvm.constant.ClassInfo;
+import com.github.HarryHook.coding2017.jvm.constant.ConstantPool;
+import com.github.HarryHook.coding2017.jvm.constant.FieldRefInfo;
+import com.github.HarryHook.coding2017.jvm.constant.UTF8Info;
+
+
+public class GetStaticFieldCmd extends TwoOperandCmd {
+
+ public GetStaticFieldCmd(ClassFile clzFile,String opCode) {
+ super(clzFile,opCode);
+
+ }
+
+ @Override
+ public String toString(ConstantPool pool) {
+
+ return super.getOperandAsField(pool);
+ }
+
+}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/InvokeSpecialCmd.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/InvokeSpecialCmd.java
new file mode 100644
index 0000000000..4afc337f47
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/InvokeSpecialCmd.java
@@ -0,0 +1,23 @@
+package com.github.HarryHook.coding2017.jvm.cmd;
+
+import com.github.HarryHook.coding2017.jvm.clz.ClassFile;
+import com.github.HarryHook.coding2017.jvm.constant.ConstantPool;
+import com.github.HarryHook.coding2017.jvm.constant.MethodRefInfo;
+
+
+public class InvokeSpecialCmd extends TwoOperandCmd {
+
+ public InvokeSpecialCmd(ClassFile clzFile,String opCode) {
+ super(clzFile,opCode);
+
+ }
+
+ @Override
+ public String toString(ConstantPool pool) {
+
+ return super.getOperandAsMethod(pool);
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/InvokeVirtualCmd.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/InvokeVirtualCmd.java
new file mode 100644
index 0000000000..6b494dceda
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/InvokeVirtualCmd.java
@@ -0,0 +1,21 @@
+package com.github.HarryHook.coding2017.jvm.cmd;
+
+import com.github.HarryHook.coding2017.jvm.clz.ClassFile;
+import com.github.HarryHook.coding2017.jvm.constant.ConstantPool;
+
+public class InvokeVirtualCmd extends TwoOperandCmd {
+
+ public InvokeVirtualCmd(ClassFile clzFile,String opCode) {
+ super(clzFile,opCode);
+ }
+
+ @Override
+ public String toString(ConstantPool pool) {
+
+ return super.getOperandAsMethod(pool);
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/LdcCmd.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/LdcCmd.java
new file mode 100644
index 0000000000..073ddd73a9
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/LdcCmd.java
@@ -0,0 +1,29 @@
+package com.github.HarryHook.coding2017.jvm.cmd;
+
+import com.github.HarryHook.coding2017.jvm.clz.ClassFile;
+import com.github.HarryHook.coding2017.jvm.constant.ConstantInfo;
+import com.github.HarryHook.coding2017.jvm.constant.ConstantPool;
+import com.github.HarryHook.coding2017.jvm.constant.StringInfo;
+
+public class LdcCmd extends OneOperandCmd {
+
+ public LdcCmd(ClassFile clzFile,String opCode) {
+ super(clzFile,opCode);
+ }
+
+ @Override
+ public String toString(ConstantPool pool) {
+
+ ConstantInfo info = (ConstantInfo)pool.getConstantInfo(this.getOperand());
+
+ String value = "TBD";
+ if(info instanceof StringInfo){
+ StringInfo strInfo = (StringInfo)info;
+ value = strInfo.toString();
+ }
+
+ return this.getOffset()+":"+this.getOpCode()+" " + this.getReadableCodeText() + " "+ value;
+
+ }
+
+}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/NewObjectCmd.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/NewObjectCmd.java
new file mode 100644
index 0000000000..9c959e31dd
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/NewObjectCmd.java
@@ -0,0 +1,19 @@
+package com.github.HarryHook.coding2017.jvm.cmd;
+
+import com.github.HarryHook.coding2017.jvm.clz.ClassFile;
+import com.github.HarryHook.coding2017.jvm.constant.ConstantPool;
+
+public class NewObjectCmd extends TwoOperandCmd{
+
+ public NewObjectCmd(ClassFile clzFile, String opCode){
+ super(clzFile,opCode);
+ }
+
+ @Override
+ public String toString(ConstantPool pool) {
+
+ return super.getOperandAsClassInfo(pool);
+ }
+
+
+}
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/NoOperandCmd.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/NoOperandCmd.java
new file mode 100644
index 0000000000..554eac0690
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/NoOperandCmd.java
@@ -0,0 +1,23 @@
+package com.github.HarryHook.coding2017.jvm.cmd;
+
+import com.github.HarryHook.coding2017.jvm.clz.ClassFile;
+import com.github.HarryHook.coding2017.jvm.constant.ConstantPool;
+
+public class NoOperandCmd extends ByteCodeCommand{
+
+ public NoOperandCmd(ClassFile clzFile, String opCode) {
+ super(clzFile, opCode);
+ }
+
+ @Override
+ public String toString(ConstantPool pool) {
+ return this.getOffset()+":" +this.getOpCode() + " "+ this.getReadableCodeText();
+ }
+
+
+
+ public int getLength(){
+ return 1;
+ }
+
+}
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/OneOperandCmd.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/OneOperandCmd.java
new file mode 100644
index 0000000000..77bf40708b
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/OneOperandCmd.java
@@ -0,0 +1,27 @@
+package com.github.HarryHook.coding2017.jvm.cmd;
+
+import com.github.HarryHook.coding2017.jvm.clz.ClassFile;
+
+public abstract class OneOperandCmd extends ByteCodeCommand {
+
+ private int operand;
+
+ public OneOperandCmd(ClassFile clzFile,String opCode) {
+ super(clzFile, opCode);
+
+ }
+ public int getOperand() {
+
+ return this.operand;
+ }
+
+ public void setOperand(int oprand1) {
+ this.operand = oprand1;
+
+ }
+ public int getLength(){
+ return 2;
+ }
+
+
+}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/PutFieldCmd.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/PutFieldCmd.java
new file mode 100644
index 0000000000..f3a197114c
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/PutFieldCmd.java
@@ -0,0 +1,19 @@
+package com.github.HarryHook.coding2017.jvm.cmd;
+
+import com.github.HarryHook.coding2017.jvm.clz.ClassFile;
+import com.github.HarryHook.coding2017.jvm.constant.ConstantPool;
+
+public class PutFieldCmd extends TwoOperandCmd {
+
+ public PutFieldCmd(ClassFile clzFile,String opCode) {
+ super(clzFile,opCode);
+ }
+
+ @Override
+ public String toString(ConstantPool pool) {
+
+ return super.getOperandAsField(pool);
+ }
+
+
+}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/TwoOperandCmd.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/TwoOperandCmd.java
new file mode 100644
index 0000000000..13edc86215
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/cmd/TwoOperandCmd.java
@@ -0,0 +1,67 @@
+package com.github.HarryHook.coding2017.jvm.cmd;
+
+import com.github.HarryHook.coding2017.jvm.clz.ClassFile;
+import com.github.HarryHook.coding2017.jvm.constant.ClassInfo;
+import com.github.HarryHook.coding2017.jvm.constant.ConstantInfo;
+import com.github.HarryHook.coding2017.jvm.constant.ConstantPool;
+import com.github.HarryHook.coding2017.jvm.constant.FieldRefInfo;
+import com.github.HarryHook.coding2017.jvm.constant.MethodRefInfo;
+
+public abstract class TwoOperandCmd extends ByteCodeCommand{
+
+ int oprand1 = -1;
+ int oprand2 = -1;
+
+ public int getOprand1() {
+ return oprand1;
+ }
+
+ public void setOprand1(int oprand1) {
+ this.oprand1 = oprand1;
+ }
+
+ public void setOprand2(int oprand2) {
+ this.oprand2 = oprand2;
+ }
+
+ public int getOprand2() {
+ return oprand2;
+ }
+
+ public TwoOperandCmd(ClassFile clzFile,String opCode) {
+ super(clzFile, opCode);
+ }
+
+ public int getIndex(){
+ int oprand1 = this.getOprand1();
+ int oprand2 = this.getOprand2();
+ int index = oprand1 << 8 | oprand2;
+ return index;
+ }
+
+ protected String getOperandAsClassInfo(ConstantPool pool){
+ int index = getIndex();
+ String codeTxt = getReadableCodeText();
+ ClassInfo info = (ClassInfo)pool.getConstantInfo(index);
+ return this.getOffset()+":"+this.getOpCode()+" "+ codeTxt +" "+ info.getClassName();
+ }
+
+ protected String getOperandAsMethod(ConstantPool pool){
+ int index = getIndex();
+ String codeTxt = getReadableCodeText();
+ ConstantInfo constInfo = this.getConstantInfo(index);
+ MethodRefInfo info = (MethodRefInfo)this.getConstantInfo(index);
+ return this.getOffset()+":"+this.getOpCode()+" " + codeTxt +" "+ info.toString();
+ }
+
+ protected String getOperandAsField(ConstantPool pool){
+ int index = getIndex();
+
+ String codeTxt = getReadableCodeText();
+ FieldRefInfo info = (FieldRefInfo)this.getConstantInfo(index);
+ return this.getOffset()+":"+this.getOpCode()+" " + codeTxt +" "+ info.toString();
+ }
+ public int getLength(){
+ return 3;
+ }
+}
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/ClassInfo.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/ClassInfo.java
index 305ac57f5a..e4822e2bbb 100644
--- a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/ClassInfo.java
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/ClassInfo.java
@@ -25,4 +25,8 @@ public String getClassName() {
UTF8Info utf8Info = (UTF8Info) constantPool.getConstantInfo(index);
return utf8Info.getValue();
}
+ @Override
+ public void accept(Visitor visitor) {
+ visitor.visitClassInfo(this);
+ }
}
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/ConstantInfo.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/ConstantInfo.java
index 3d81ed1adb..6c502016a3 100644
--- a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/ConstantInfo.java
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/ConstantInfo.java
@@ -28,7 +28,16 @@ public ConstantInfo getConstantInfo(int index) {
return this.constantPool.getConstantInfo(index);
}
-
-
-
+ public abstract void accept(Visitor visitor);
+
+ public static interface Visitor{
+ public void visitClassInfo(ClassInfo info);
+ public void visitFieldRef(FieldRefInfo info);
+ public void visitMethodRef(MethodRefInfo info);
+ public void visitNameAndType(NameAndTypeInfo info);
+ public void visitString(StringInfo info);
+ public void visistUTF8(UTF8Info info);
+
+ }
+
}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/ConstantPool.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/ConstantPool.java
index 9d06349f3b..92d1b381d1 100644
--- a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/ConstantPool.java
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/ConstantPool.java
@@ -25,7 +25,7 @@ public String getUTF8String(int index) {
return ((UTF8Info) this.constantInfos.get(index)).getValue();
}
- public Object getSize() {
+ public int getSize() {
return this.constantInfos.size() - 1;
}
}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/FieldRefInfo.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/FieldRefInfo.java
index 6e8ddcb91b..d2d6a19f90 100644
--- a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/FieldRefInfo.java
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/FieldRefInfo.java
@@ -55,4 +55,9 @@ public String getFieldType() {
NameAndTypeInfo typeInfo = (NameAndTypeInfo) this.getConstantInfo(this.getNameAndTypeIndex());
return typeInfo.getTypeInfo();
}
+
+ @Override
+ public void accept(Visitor visitor) {
+ visitor.visitFieldRef(this);
+ }
}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/MethodRefInfo.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/MethodRefInfo.java
index 7815c8a6a2..a1055932a0 100644
--- a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/MethodRefInfo.java
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/MethodRefInfo.java
@@ -54,4 +54,9 @@ public String getParamAndReturnType() {
return typeInfo.getTypeInfo();
}
+ @Override
+ public void accept(Visitor visitor) {
+ visitor.visitMethodRef(this);
+ }
+
}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/NameAndTypeInfo.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/NameAndTypeInfo.java
index 519656f681..29495489f4 100644
--- a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/NameAndTypeInfo.java
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/NameAndTypeInfo.java
@@ -45,4 +45,10 @@ public String getTypeInfo() {
public String toString() {
return "(" + getName() + "," + getTypeInfo() + ")";
}
+
+ @Override
+ public void accept(Visitor visitor) {
+ visitor.visitNameAndType(this);
+
+ }
}
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/NullConstantInfo.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/NullConstantInfo.java
index 59489a965c..b0f5ad9b80 100644
--- a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/NullConstantInfo.java
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/NullConstantInfo.java
@@ -11,4 +11,9 @@ public int getType() {
return -1;
}
+ @Override
+ public void accept(Visitor visitor) {
+
+ }
+
}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/StringInfo.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/StringInfo.java
index 1d625069be..442405aa36 100644
--- a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/StringInfo.java
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/StringInfo.java
@@ -24,4 +24,10 @@ public String toString() {
return this.getConstantPool().getUTF8String(index);
}
+ @Override
+ public void accept(Visitor visitor) {
+ visitor.visitString(this);
+
+ }
+
}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/UTF8Info.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/UTF8Info.java
index 27c2ec9059..5c740bf402 100644
--- a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/UTF8Info.java
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/constant/UTF8Info.java
@@ -29,8 +29,14 @@ public String toString() {
public void setValue(String value) {
this.value = value;
}
- public String getValue(){
+
+ public String getValue() {
return value;
}
+ @Override
+ public void accept(Visitor visitor) {
+ visitor.visistUTF8(this);
+
+ }
}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/method/Method.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/method/Method.java
index d7dedc0439..08b8ff029b 100644
--- a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/method/Method.java
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/method/Method.java
@@ -2,6 +2,7 @@
package com.github.HarryHook.coding2017.jvm.method;
import com.github.HarryHook.coding2017.jvm.clz.ClassFile;
+import com.github.HarryHook.coding2017.jvm.cmd.ByteCodeCommand;
import javax.management.RuntimeErrorException;
@@ -76,8 +77,11 @@ public String toString(ConstantPool pool) {
StringBuffer buffer = new StringBuffer();
String name = ((UTF8Info) pool.getConstantInfo(this.nameIndex)).getValue();
String desc = ((UTF8Info) pool.getConstantInfo(this.descriptorIndex)).getValue();
- buffer.append(name);
- buffer.append(desc);
+ buffer.append(name).append(":").append(desc).append("\n");
+ buffer.append(this.codeAttr.toString(pool));
return buffer.toString();
}
+ public ByteCodeCommand[] getCmds() {
+ return this.getCodeAttr().getCmds();
+}
}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/print/ClassFilePrinter.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/print/ClassFilePrinter.java
new file mode 100644
index 0000000000..6ede47692c
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/print/ClassFilePrinter.java
@@ -0,0 +1,51 @@
+package com.github.HarryHook.coding2017.jvm.print;
+
+import com.github.HarryHook.coding2017.jvm.clz.ClassFile;
+import com.github.HarryHook.coding2017.jvm.constant.ClassInfo;
+import com.github.HarryHook.coding2017.jvm.constant.ConstantInfo;
+import com.github.HarryHook.coding2017.jvm.constant.ConstantPool;
+import com.github.HarryHook.coding2017.jvm.constant.FieldRefInfo;
+import com.github.HarryHook.coding2017.jvm.constant.MethodRefInfo;
+import com.github.HarryHook.coding2017.jvm.constant.NameAndTypeInfo;
+import com.github.HarryHook.coding2017.jvm.constant.StringInfo;
+import com.github.HarryHook.coding2017.jvm.constant.UTF8Info;
+import com.github.HarryHook.coding2017.jvm.loader.ClassFileLoader;
+
+public class ClassFilePrinter {
+ ClassFile clzFile = null;
+
+ public ClassFilePrinter(ClassFile clzFile) {
+ this.clzFile = clzFile;
+ }
+
+ public void print() {
+
+ if (clzFile.getAccessFlag().isPublicClass()) {
+ System.out.println("Access flag : public ");
+ }
+ System.out.println("Class Name:" + clzFile.getClassName());
+
+ System.out.println("Super Class Name:" + clzFile.getSuperClassName());
+
+ System.out.println("minor version:" + clzFile.getMinorVersion());
+
+ System.out.println("major version:" + clzFile.getMinorVersion());
+
+ ConstantPoolPrinter cnstPoolPrinter = new ConstantPoolPrinter(clzFile.getConstantPool());
+ cnstPoolPrinter.print();
+
+ }
+
+ public static void main(String[] args) {
+ String path = "F:\\Coding2017\\group02\\727171008\\bin";
+ ClassFileLoader loader = new ClassFileLoader();
+ loader.addClassPath(path);
+ String className = "com.github.HarryHook.coding2017.jvm.test.EmployeeV1";
+
+ ClassFile clzFile = loader.loadClass(className);
+
+ ClassFilePrinter printer = new ClassFilePrinter(clzFile);
+
+ printer.print();
+ }
+}
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/print/ConstantPoolPrinter.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/print/ConstantPoolPrinter.java
new file mode 100644
index 0000000000..3d6c791185
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/print/ConstantPoolPrinter.java
@@ -0,0 +1,25 @@
+package com.github.HarryHook.coding2017.jvm.print;
+
+import com.github.HarryHook.coding2017.jvm.constant.ClassInfo;
+import com.github.HarryHook.coding2017.jvm.constant.ConstantInfo;
+import com.github.HarryHook.coding2017.jvm.constant.ConstantPool;
+import com.github.HarryHook.coding2017.jvm.constant.FieldRefInfo;
+import com.github.HarryHook.coding2017.jvm.constant.MethodRefInfo;
+import com.github.HarryHook.coding2017.jvm.constant.NameAndTypeInfo;
+import com.github.HarryHook.coding2017.jvm.constant.StringInfo;
+import com.github.HarryHook.coding2017.jvm.constant.UTF8Info;
+
+public class ConstantPoolPrinter {
+ ConstantPool pool;
+ ConstantPoolPrinter(ConstantPool pool){
+ this.pool = pool;
+ }
+ public void print(){
+
+ System.out.println("Constant Pool:");
+
+
+
+
+ }
+}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/test/ClassFileloaderTest.java b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/test/ClassFileloaderTest.java
index 524907ce9f..ee7e3b3092 100644
--- a/group02/727171008/src/com/github/HarryHook/coding2017/jvm/test/ClassFileloaderTest.java
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/jvm/test/ClassFileloaderTest.java
@@ -9,6 +9,10 @@
import com.github.HarryHook.coding2017.jvm.clz.ClassFile;
import com.github.HarryHook.coding2017.jvm.clz.ClassIndex;
+import com.github.HarryHook.coding2017.jvm.cmd.BiPushCmd;
+import com.github.HarryHook.coding2017.jvm.cmd.ByteCodeCommand;
+import com.github.HarryHook.coding2017.jvm.cmd.OneOperandCmd;
+import com.github.HarryHook.coding2017.jvm.cmd.TwoOperandCmd;
import com.github.HarryHook.coding2017.jvm.constant.ClassInfo;
import com.github.HarryHook.coding2017.jvm.constant.ConstantPool;
import com.github.HarryHook.coding2017.jvm.constant.MethodRefInfo;
@@ -259,5 +263,80 @@ private void assertMethodEquals(ConstantPool pool,Method m , String expectedName
Assert.assertEquals(expectedDesc, methodDesc);
Assert.assertEquals(expectedCode, code);
}
-
+ /*
+ * 第四次测试
+ */
+ @Test
+ public void testByteCodeCommand(){
+ {
+ Method initMethod = this.clzFile.getMethod("", "(Ljava/lang/String;I)V");
+ ByteCodeCommand [] cmds = initMethod.getCmds();
+
+ assertOpCodeEquals("0: aload_0", cmds[0]);
+ assertOpCodeEquals("1: invokespecial #12", cmds[1]);
+ assertOpCodeEquals("4: aload_0", cmds[2]);
+ assertOpCodeEquals("5: aload_1", cmds[3]);
+ assertOpCodeEquals("6: putfield #15", cmds[4]);
+ assertOpCodeEquals("9: aload_0", cmds[5]);
+ assertOpCodeEquals("10: iload_2", cmds[6]);
+ assertOpCodeEquals("11: putfield #17", cmds[7]);
+ assertOpCodeEquals("14: return", cmds[8]);
+ }
+
+ {
+ Method setNameMethod = this.clzFile.getMethod("setName", "(Ljava/lang/String;)V");
+ ByteCodeCommand [] cmds = setNameMethod.getCmds();
+
+ assertOpCodeEquals("0: aload_0", cmds[0]);
+ assertOpCodeEquals("1: aload_1", cmds[1]);
+ assertOpCodeEquals("2: putfield #15", cmds[2]);
+ assertOpCodeEquals("5: return", cmds[3]);
+
+ }
+
+ {
+ Method sayHelloMethod = this.clzFile.getMethod("sayHello", "()V");
+ ByteCodeCommand [] cmds = sayHelloMethod.getCmds();
+
+ assertOpCodeEquals("0: getstatic #28", cmds[0]);
+ assertOpCodeEquals("3: ldc #34", cmds[1]);
+ assertOpCodeEquals("5: invokevirtual #36", cmds[2]);
+ assertOpCodeEquals("8: return", cmds[3]);
+
+ }
+
+ {
+ Method mainMethod = this.clzFile.getMainMethod();
+
+ ByteCodeCommand [] cmds = mainMethod.getCmds();
+
+ assertOpCodeEquals("0: new #1", cmds[0]);
+ assertOpCodeEquals("3: dup", cmds[1]);
+ assertOpCodeEquals("4: ldc #43", cmds[2]);
+ assertOpCodeEquals("6: bipush 29", cmds[3]);
+ assertOpCodeEquals("8: invokespecial #45", cmds[4]);
+ assertOpCodeEquals("11: astore_1", cmds[5]);
+ assertOpCodeEquals("12: aload_1", cmds[6]);
+ assertOpCodeEquals("13: invokevirtual #47", cmds[7]);
+ assertOpCodeEquals("16: return", cmds[8]);
+ }
+
+ }
+
+ private void assertOpCodeEquals(String expected, ByteCodeCommand cmd){
+
+ String acctual = cmd.getOffset()+": "+cmd.getReadableCodeText();
+
+ if(cmd instanceof OneOperandCmd){
+ if(cmd instanceof BiPushCmd){
+ acctual += " " + ((OneOperandCmd)cmd).getOperand();
+ } else{
+ acctual += " #" + ((OneOperandCmd)cmd).getOperand();
+ }
+ }
+ if(cmd instanceof TwoOperandCmd){
+ acctual += " #" + ((TwoOperandCmd)cmd).getIndex();
+ }
+ Assert.assertEquals(expected, acctual);
+ }
}
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/queue/CircleQueue.java b/group02/727171008/src/com/github/HarryHook/coding2017/queue/CircleQueue.java
new file mode 100644
index 0000000000..cd82fb2550
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/queue/CircleQueue.java
@@ -0,0 +1,38 @@
+package com.github.HarryHook.coding2017.queue;
+
+/**
+ * 用数组实现循环队列
+ *
+ * @author liuxin
+ *
+ * @param
+ */
+public class CircleQueue {
+
+ private final static int DEFAULT_SIZE = 10;
+
+ // 用数组来保存循环队列的元素
+ private Object[] elementData = new Object[DEFAULT_SIZE];
+
+ // 队头
+ private int front = 0;
+ // 队尾
+ private int rear = 0;
+
+ public boolean isEmpty() {
+ return false;
+
+ }
+
+ public int size() {
+ return -1;
+ }
+
+ public void enQueue(E data) {
+
+ }
+
+ public E deQueue() {
+ return null;
+ }
+}
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/queue/Josephus.java b/group02/727171008/src/com/github/HarryHook/coding2017/queue/Josephus.java
new file mode 100644
index 0000000000..7b5fe53f5e
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/queue/Josephus.java
@@ -0,0 +1,18 @@
+package com.github.HarryHook.coding2017.queue;
+
+import java.util.List;
+
+/**
+ * 用Queue来实现Josephus问题 在这个古老的问题当中, N个深陷绝境的人一致同意用这种方式减少生存人数: N个人围成一圈(位置记为0到N-1),
+ * 并且从第一个人报数, 报到M的人会被杀死, 直到最后一个人留下来 该方法返回一个List, 包含了被杀死人的次序
+ *
+ * @author liuxin
+ *
+ */
+public class Josephus {
+
+ public static List execute(int n, int m) {
+ return null;
+ }
+
+}
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/queue/JosephusTest.java b/group02/727171008/src/com/github/HarryHook/coding2017/queue/JosephusTest.java
new file mode 100644
index 0000000000..39d2ef9971
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/queue/JosephusTest.java
@@ -0,0 +1,25 @@
+package com.github.HarryHook.coding2017.queue;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class JosephusTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testExecute() {
+
+ Assert.assertEquals("[1, 3, 5, 0, 4, 2, 6]", Josephus.execute(7, 2).toString());
+
+ }
+
+}
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/queue/Queue.java b/group02/727171008/src/com/github/HarryHook/coding2017/queue/Queue.java
new file mode 100644
index 0000000000..3be0147770
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/queue/Queue.java
@@ -0,0 +1,55 @@
+package com.github.HarryHook.coding2017.queue;
+
+import java.util.NoSuchElementException;
+
+public class Queue {
+ private Node first;
+ private Node last;
+ private int size;
+
+ private static class Node {
+ private E item;
+ private Node next;
+ }
+
+ public Queue() {
+ first = null;
+ last = null;
+ size = 0;
+ }
+
+ public boolean isEmpty() {
+ return first == null;
+ }
+
+ public int size() {
+ return size;
+ }
+
+ public void enQueue(E data) {
+ Node oldlast = last;
+ last = new Node();
+ last.item = data;
+ last.next = null;
+ if (isEmpty()) {
+ first = last;
+ } else {
+ oldlast.next = last;
+ }
+ size++;
+ }
+
+ public E deQueue() {
+ if (isEmpty()) {
+ throw new NoSuchElementException("Queue underflow");
+ }
+ E item = first.item;
+ first = first.next;
+ size--;
+ if (isEmpty()) {
+ last = null;
+ }
+ return item;
+ }
+
+}
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/queue/QueueWithTwoStacks.java b/group02/727171008/src/com/github/HarryHook/coding2017/queue/QueueWithTwoStacks.java
new file mode 100644
index 0000000000..c72abadcd2
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/queue/QueueWithTwoStacks.java
@@ -0,0 +1,37 @@
+package com.github.HarryHook.coding2017.queue;
+
+import java.util.Stack;
+
+/**
+ * 用两个栈来实现一个队列
+ *
+ * @author liuxin
+ *
+ * @param
+ */
+public class QueueWithTwoStacks {
+ private Stack stack1;
+ private Stack stack2;
+
+ public QueueWithTwoStacks() {
+ stack1 = new Stack();
+ stack2 = new Stack();
+ }
+
+ public boolean isEmpty() {
+ return false;
+ }
+
+ public int size() {
+ return -1;
+ }
+
+ public void enQueue(E item) {
+
+ }
+
+ public E deQueue() {
+ return null;
+ }
+
+}
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/InfixExpr.java b/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/InfixExpr.java
index 5b1dbd7fa4..b9667fdaac 100644
--- a/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/InfixExpr.java
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/InfixExpr.java
@@ -13,73 +13,64 @@ public InfixExpr(String expr) {
public float evaluate() {
char[] ch = expr.toCharArray();
- MyStack stackOfTocken = new MyStack();
+ MyStack stackOfOperator = new MyStack();
MyStack stackOfNumber = new MyStack();
for (int i = 0; i < ch.length; i++) {
if (Character.isDigit(ch[i])) {
- int tmp = Integer.parseInt("" + ch[i]);
+ float tmp = Float.parseFloat("" + ch[i]);
while (i < ch.length - 1 && Character.isDigit(ch[++i])) {
- tmp = tmp * 10 + Integer.parseInt("" + ch[i]);
+ tmp = tmp * 10 + Float.parseFloat("" + ch[i]);
}
-
+
stackOfNumber.push(tmp);
}
if (ch[i] == '+' || ch[i] == '-' || ch[i] == '*' || ch[i] == '/') {
- stackOfTocken.push(ch[i]);
+ stackOfOperator.push(ch[i]);
}
- if (!(stackOfTocken.isEmpty()) && (char) stackOfTocken.peek() == '*') {
- int tmp = Integer.parseInt("" + ch[++i]);
+ char operator = (char) stackOfOperator.peek();
+ if (operator == '*' || operator == '/') {
+ float tmp = Float.parseFloat("" + ch[++i]);
while (i < ch.length - 1 && Character.isDigit(ch[++i])) {
- tmp = tmp * 10 + Integer.parseInt("" + ch[i]);
+ tmp = tmp * 10 + Float.parseFloat("" + ch[i]);
}
if (i != ch.length - 1) {
i--;
}
stackOfNumber.push(tmp);
- int tmp1 = Integer.parseInt("" + stackOfNumber.pop());
- int tmp2 = Integer.parseInt("" + stackOfNumber.pop());
- stackOfNumber.push(tmp1 * tmp2);
- stackOfTocken.pop();
-
- }
- if (!(stackOfTocken.isEmpty()) && (char) stackOfTocken.peek() == '/') {
- int tmp = Integer.parseInt("" + ch[++i]);
- while (i < ch.length - 1 && Character.isDigit(ch[++i])) {
- tmp = tmp * 10 + Integer.parseInt("" + ch[i]);
+ float tmp1 = Float.parseFloat("" + stackOfNumber.pop());
+ float tmp2 = Float.parseFloat("" + stackOfNumber.pop());
+ if (operator == '*') {
+ stackOfNumber.push(tmp1 * tmp2);
+ } else {
+ stackOfNumber.push(tmp2 / tmp1);
}
- if (i != ch.length - 1) {
- i--;
- }
- stackOfNumber.push(tmp);
- int tmp1 = Integer.parseInt("" + stackOfNumber.pop());
- int tmp2 = Integer.parseInt("" + stackOfNumber.pop());
- stackOfNumber.push(tmp2 / tmp1);
- stackOfTocken.pop();
+ stackOfOperator.pop();
}
+
}
- // 将栈中的数字和运算法逆置,便于计算
+ // 将栈中的数字和运算符逆置,从左往右结合
reverse(stackOfNumber);
- reverse(stackOfTocken);
-
- while (!(stackOfTocken.isEmpty())) {
- if ((char) stackOfTocken.peek() == '+') {
- int tmp1 = Integer.parseInt("" + stackOfNumber.pop());
- int tmp2 = Integer.parseInt("" + stackOfNumber.pop());
- stackOfNumber.push(tmp1 + tmp2);
- }
-
- if ((char) stackOfTocken.peek() == '-') {
- int tmp1 = Integer.parseInt("" + stackOfNumber.pop());
- int tmp2 = Integer.parseInt("" + stackOfNumber.pop());
- stackOfNumber.push(tmp1 - tmp2);
+ reverse(stackOfOperator);
+
+ while (!(stackOfOperator.isEmpty())) {
+ char operator = (char) stackOfOperator.peek();
+ if (operator == '+' || operator == '-') {
+ float tmp1 = Float.parseFloat("" + stackOfNumber.pop());
+ float tmp2 = Float.parseFloat("" + stackOfNumber.pop());
+ if (operator == '+') {
+ stackOfNumber.push(tmp1 + tmp2);
+ } else {
+ stackOfNumber.push(tmp1 - tmp2);
+ }
}
- stackOfTocken.pop();
+
+ stackOfOperator.pop();
}
return Float.parseFloat("" + stackOfNumber.pop());
@@ -104,4 +95,9 @@ private void reverse(MyStack s) {
s.push(temp2);
}
+
+ public static void main(String[] args) {
+ InfixExpr expr = new InfixExpr("2+3*4+5");
+ System.out.println(expr.evaluate());
+ }
}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/InfixToPostfix.java b/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/InfixToPostfix.java
new file mode 100644
index 0000000000..10088e28cd
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/InfixToPostfix.java
@@ -0,0 +1,53 @@
+package com.github.HarryHook.coding2017.stack.expr;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;
+
+//中序表达式: 3*20+12*5-40/2 转换成后续表达式:3 20 * 12 5 * + 40 2 / -
+//思路:当前token依次从左往右读取, 数字依次append, 当前入栈的运算符的优先级小于等于栈顶的运算符,栈顶操作符出栈
+public class InfixToPostfix {
+
+ public List convert(String expr) {
+
+ TokenParser parser = new TokenParser();
+ List tokens = parser.parse(expr);
+
+ List listOfTokens = new ArrayList<>();
+
+ Stack opsStack = new Stack<>();
+
+ for (Token token : tokens) {
+
+ if (token.isNumber()) {
+ listOfTokens.add(token);
+ } else if (token.isOperator()) { // 还需判断当前操作符和栈顶操作符的优先级
+ if (opsStack.isEmpty()) {
+ opsStack.push(token);
+ } else {
+ if (!token.hasHigherPriority(opsStack.peek())) {
+ listOfTokens.add(opsStack.pop());
+ }
+ opsStack.push(token);
+ }
+
+ }
+ }
+ while (!(opsStack.isEmpty())) { // exprStack 为空,但操作符栈还有元素
+ listOfTokens.add(opsStack.pop());
+ }
+ return listOfTokens;
+ }
+
+ public static void main(String[] args) {
+ InfixToPostfix toPostfix = new InfixToPostfix();
+ List t = new ArrayList();
+ String expr = "3+20+12*5+40/2";
+ t = toPostfix.convert(expr);
+ System.out.println("expr: " + expr);
+ System.out.println("PostfixExpr: " + t);
+ }
+
+}
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/PostfixExpr.java b/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/PostfixExpr.java
new file mode 100644
index 0000000000..49bebad1a7
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/PostfixExpr.java
@@ -0,0 +1,54 @@
+package com.github.HarryHook.coding2017.stack.expr;
+
+import java.util.List;
+import java.util.Stack;
+
+public class PostfixExpr {
+ String expr = null;
+
+ public PostfixExpr(String expr) {
+ this.expr = expr;
+ }
+
+ public float evaluate() {
+
+ TokenParser parser = new TokenParser();
+ List tokens = parser.parse(this.expr);
+
+ Stack numStack = new Stack<>();
+ for (Token token : tokens) {
+
+ if (token.isNumber()) {
+ numStack.push(new Float(token.getIntValue()));
+ } else {
+ Float f2 = numStack.pop();
+ Float f1 = numStack.pop();
+ numStack.push(calculate(token.toString(), f1, f2));
+ }
+ }
+ return numStack.pop().floatValue();
+ }
+
+ // 注意,此时计算的顺序和前序的次序相反
+ private Float calculate(String op, Float f1, Float f2) {
+ if (op.equals("+")) {
+ return f1 + f2;
+ }
+ if (op.equals("-")) {
+ return f1 - f2;
+ }
+ if (op.equals("*")) {
+ return f1 * f2;
+ }
+ if (op.equals("/")) {
+ return f1 / f2;
+ }
+ throw new RuntimeException(op + " is not supported");
+ }
+
+ public static void main(String[] args) {
+ PostfixExpr expr = new PostfixExpr("9 3 1-3*+ 10 2/+");
+ System.out.println("The result of the expression: " + expr.evaluate());
+ }
+
+}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/PostfixExprTest.java b/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/PostfixExprTest.java
new file mode 100644
index 0000000000..7e78fa3997
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/PostfixExprTest.java
@@ -0,0 +1,37 @@
+package com.github.HarryHook.coding2017.stack.expr;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class PostfixExprTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testEvaluate() {
+ {
+ PostfixExpr expr = new PostfixExpr("6 5 2 3 + 8 * + 3 + *");
+ Assert.assertEquals(288, expr.evaluate(), 0.0f);
+ }
+ {
+ // 9+(3-1)*3+10/2
+ PostfixExpr expr = new PostfixExpr("9 3 1-3*+ 10 2/+");
+ Assert.assertEquals(20, expr.evaluate(), 0.0f);
+ }
+
+ {
+ // 10-2*3+50
+ PostfixExpr expr = new PostfixExpr("10 2 3 * - 50 +");
+ Assert.assertEquals(54, expr.evaluate(), 0.0f);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/PrefixExpr.java b/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/PrefixExpr.java
new file mode 100644
index 0000000000..d93b6e32fe
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/PrefixExpr.java
@@ -0,0 +1,58 @@
+package com.github.HarryHook.coding2017.stack.expr;
+
+import java.util.List;
+import java.util.Stack;
+
+public class PrefixExpr {
+ String expr = null;
+
+ public PrefixExpr(String expr) {
+ this.expr = expr;
+ }
+
+ public float evaluate() {
+
+ TokenParser parser = new TokenParser();
+ List tokens = parser.parse(this.expr);
+
+ Stack exprStack = new Stack<>();
+ Stack numStack = new Stack<>();
+ for (Token token : tokens) {
+ exprStack.push(token);
+ }
+ System.out.println(tokens);
+ while (!exprStack.isEmpty()) {
+ Token t = exprStack.pop();
+ if (t.isNumber()) {
+ numStack.push(new Float(t.getIntValue()));
+ } else if(t.isOperator()){
+ Float f1 = numStack.pop();
+ Float f2 = numStack.pop();
+ numStack.push(calculate(t.toString(), f1, f2));
+ }
+ }
+ return numStack.pop().floatValue();
+ }
+
+ private Float calculate(String op, Float f1, Float f2) {
+ if (op.equals("+")) {
+ return f1 + f2;
+ }
+ if (op.equals("-")) {
+ return f1 - f2;
+ }
+ if (op.equals("*")) {
+ return f1 * f2;
+ }
+ if (op.equals("/")) {
+ return f1 / f2;
+ }
+ throw new RuntimeException(op + " is not supported");
+ }
+
+ public static void main(String[] args) {
+ PrefixExpr expr = new PrefixExpr("-++6/*2 9 3 * 4 2 8");
+ System.out.println("The result of the expression: " + expr.evaluate());
+ }
+
+}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/PrefixExprTest.java b/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/PrefixExprTest.java
new file mode 100644
index 0000000000..3dbef83ca2
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/PrefixExprTest.java
@@ -0,0 +1,43 @@
+package com.github.HarryHook.coding2017.stack.expr;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class PrefixExprTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testEvaluate() {
+ {
+ // 2*3+4*5
+ PrefixExpr expr = new PrefixExpr("+ * 2 3* 4 5");
+ Assert.assertEquals(26, expr.evaluate(), 0.001f);
+ }
+ {
+ // 4*2 + 6+9*2/3 -8
+ PrefixExpr expr = new PrefixExpr("-++6/*2 9 3 * 4 2 8");
+ Assert.assertEquals(12, expr.evaluate(), 0.001f);
+ }
+ {
+ // (3+4)*5-6
+ PrefixExpr expr = new PrefixExpr("- * + 3 4 5 6");
+ Assert.assertEquals(29, expr.evaluate(), 0.001f);
+ }
+ {
+ // 1+((2+3)*4)-5
+ PrefixExpr expr = new PrefixExpr("- + 1 * + 2 3 4 5");
+ Assert.assertEquals(16, expr.evaluate(), 0.001f);
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/Token.java b/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/Token.java
new file mode 100644
index 0000000000..097d635bd2
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/Token.java
@@ -0,0 +1,50 @@
+package com.github.HarryHook.coding2017.stack.expr;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+class Token {
+ public static final List OPERATORS = Arrays.asList("+", "-", "*", "/");
+ private static final Map priorities = new HashMap<>();
+ static {
+ priorities.put("+", 1);
+ priorities.put("-", 1);
+ priorities.put("*", 2);
+ priorities.put("/", 2);
+ }
+ static final int OPERATOR = 1;
+ static final int NUMBER = 2;
+ String value;
+ int type;
+
+ public Token(int type, String value) {
+ this.type = type;
+ this.value = value;
+ }
+
+ public boolean isNumber() {
+ return type == NUMBER;
+ }
+
+ public boolean isOperator() {
+ return type == OPERATOR;
+ }
+
+ public int getIntValue() {
+ return Integer.valueOf(value).intValue();
+ }
+
+ public String toString() {
+ return value;
+ }
+
+ public boolean hasHigherPriority(Token t) {
+ if (!this.isOperator() && !t.isOperator()) {
+ throw new RuntimeException("numbers can't compare priority");
+ }
+ return priorities.get(this.value) - priorities.get(t.value) > 0;
+ }
+
+}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/TokenParser.java b/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/TokenParser.java
new file mode 100644
index 0000000000..8d520fd68a
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/TokenParser.java
@@ -0,0 +1,56 @@
+package com.github.HarryHook.coding2017.stack.expr;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TokenParser {
+
+ public List parse(String expr) {
+ List tokens = new ArrayList<>();
+
+ int i = 0;
+
+ while (i < expr.length()) {
+
+ char c = expr.charAt(i);
+
+ if (isOperator(c)) {
+
+ Token t = new Token(Token.OPERATOR, String.valueOf(c));
+ tokens.add(t);
+ i++;
+
+ } else if (Character.isDigit(c)) {
+
+ int nextOperatorIndex = indexOfNextOperator(i, expr);
+ String value = expr.substring(i, nextOperatorIndex);
+ Token t = new Token(Token.NUMBER, value);
+ tokens.add(t);
+ i = nextOperatorIndex;
+
+ } else {
+ System.out.println("char :[" + c + "] is not number or operator,ignore");
+ i++;
+ }
+
+ }
+ return tokens;
+ }
+
+ private int indexOfNextOperator(int i, String expr) {
+
+ while (Character.isDigit(expr.charAt(i))) {
+ i++;
+ if (i == expr.length()) {
+ break;
+ }
+ }
+ return i;
+
+ }
+
+ private boolean isOperator(char c) {
+ String sc = String.valueOf(c);
+ return Token.OPERATORS.contains(sc);
+ }
+}
\ No newline at end of file
diff --git a/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/TokenParserTest.java b/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/TokenParserTest.java
new file mode 100644
index 0000000000..3067467a10
--- /dev/null
+++ b/group02/727171008/src/com/github/HarryHook/coding2017/stack/expr/TokenParserTest.java
@@ -0,0 +1,39 @@
+package com.github.HarryHook.coding2017.stack.expr;
+
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TokenParserTest {
+
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void test() {
+
+ TokenParser parser = new TokenParser();
+ List tokens = parser.parse("300*20+12*5-20/4");
+
+ Assert.assertEquals(300, tokens.get(0).getIntValue());
+ Assert.assertEquals("*", tokens.get(1).toString());
+ Assert.assertEquals(20, tokens.get(2).getIntValue());
+ Assert.assertEquals("+", tokens.get(3).toString());
+ Assert.assertEquals(12, tokens.get(4).getIntValue());
+ Assert.assertEquals("*", tokens.get(5).toString());
+ Assert.assertEquals(5, tokens.get(6).getIntValue());
+ Assert.assertEquals("-", tokens.get(7).toString());
+ Assert.assertEquals(20, tokens.get(8).getIntValue());
+ Assert.assertEquals("/", tokens.get(9).toString());
+ Assert.assertEquals(4, tokens.get(10).getIntValue());
+ }
+
+}
\ No newline at end of file