Skip to content

Commit

Permalink
Merge pull request #8 from zavier/master
Browse files Browse the repository at this point in the history
sync
  • Loading branch information
Viscaria233 authored Apr 22, 2017
2 parents 91e46e6 + 1fe0f55 commit f4038da
Show file tree
Hide file tree
Showing 54 changed files with 2,192 additions and 262 deletions.
Original file line number Diff line number Diff line change
@@ -1,18 +1,145 @@
package com.coding2017.basic.stack.expr;

import java.util.Arrays;
import java.util.List;
import java.util.Stack;
import java.util.stream.Collectors;

import com.google.common.base.CharMatcher;
import com.google.common.collect.Lists;

public class InfixExpr {
String expr = null;

public InfixExpr(String expr) {
this.expr = expr;
}

public float evaluate() {

return 0.0f;
}




private static final CharMatcher CHAR_MATCHER = CharMatcher.anyOf(Operator.allOperator());

private Stack<String> operatorStack = new Stack<>();
private Stack<Float> numberStack = new Stack<>();

String expr = null;

public InfixExpr(String expr) {
this.expr = expr;
}

public float evaluate() {
List<String> list = splitByOperator(expr);
for (String s : list) {
if (Operator.isOperator(s)) {
if (operatorStack.isEmpty()) {
operatorStack.push(s);
} else {
while (true) {
String op = operatorStack.peek();
if (Operator.opOf(op).getPriority() >= Operator.opOf(s).getPriority()) {
calculateOnce();
} else {
break;
}
if (operatorStack.isEmpty()) {
break;
}
}
operatorStack.push(s);
}
} else {
numberStack.push(Float.parseFloat(s));
}
}
while (!operatorStack.isEmpty()) {
calculateOnce();
}
if (numberStack.isEmpty() || numberStack.size() != 1) {
throw new RuntimeException("expr error");
}
return numberStack.pop();
}

private void calculateOnce() {
String operator = operatorStack.pop();
Float secondNumber = numberStack.pop();
Float firstNumber = numberStack.pop();
Float calculate = calculate(firstNumber, secondNumber, operator);
numberStack.push(calculate);
}

private Float calculate(Float firstNumber, Float seconfNumber, String operator) {
if (Operator.ADD.getOp().equals(operator)) {
return firstNumber + seconfNumber;
} else if (Operator.MINUTE.getOp().equals(operator)) {
return firstNumber - seconfNumber;
} else if (Operator.MULTIPLY.getOp().equals(operator)) {
return firstNumber * seconfNumber;
} else if (Operator.DIVIDE.getOp().equals(operator)) {
return firstNumber / seconfNumber;
}
return null;
}

private List<String> splitByOperator(String expr) {
int pos = 0;
List<String> list = Lists.newArrayList();
while (pos < expr.length()) {
int index = CHAR_MATCHER.indexIn(expr, pos);
if (index < 0) {
list.add(expr.substring(pos).trim());
pos = expr.length();
} else {
list.add(expr.substring(pos, index).trim());
list.add(expr.substring(index, index + 1));
pos = index + 1;
}
}
return list;
}

enum Operator {
ADD("+", 1), MINUTE("-", 1), MULTIPLY("*", 2), DIVIDE("/", 2);

private String op;
private int priority;

Operator(String op, int priority) {
this.op = op;
this.priority = priority;
}

public static Operator opOf(String op) {
for (Operator operator : values()) {
if (operator.getOp().equals(op)) {
return operator;
}
}
return null;
}

public static boolean isOperator(String op) {
for (Operator operator : values()) {
if (operator.getOp().equals(op)) {
return true;
}
}
return false;
}

public static String allOperator() {
return Arrays.stream(values()).map(Operator::getOp).collect(Collectors.joining());
}

public String getOp() {
return op;
}

public void setOp(String op) {
this.op = op;
}

public int getPriority() {
return priority;
}

public void setPriority(int priority) {
this.priority = priority;
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.coding2017.jvm.attr;

import com.coding2017.jvm.clz.ClassFile;
import com.coding2017.jvm.loader.ByteCodeIterator;

public abstract class AttributeInfo {
public static final String CODE = "Code";
public static final String CONST_VALUE = "ConstantValue";
public static final String EXCEPTIONS = "Exceptions";
public static final String LINE_NUM_TABLE = "LineNumberTable";
public static final String LOCAL_VAR_TABLE = "LocalVariableTable";
public static final String STACK_MAP_TABLE = "StackMapTable";
int attrNameIndex;
int attrLen;

public AttributeInfo(int attrNameIndex, int attrLen) {

this.attrNameIndex = attrNameIndex;
this.attrLen = attrLen;
}

public static AttributeInfo parse(ClassFile clzFile, ByteCodeIterator iter) {
int nameIndex = iter.nextU2ToInt();
String name = clzFile.getConstantPool().getUTF8String(nameIndex);
int length = iter.nextU4ToInt();
if (AttributeInfo.CODE.equals(name)) {
return CodeAttr.parse(clzFile, iter, nameIndex, length);
} else if (AttributeInfo.LINE_NUM_TABLE.equals(name)) {
return LineNumberTable.parse(clzFile, iter, nameIndex, length);
} else if (AttributeInfo.LOCAL_VAR_TABLE.equals(name)) {
return LocalVariableTable.parse(clzFile, iter, nameIndex, length);
} else if (AttributeInfo.STACK_MAP_TABLE.equals(name)) {
return StackMapTable.parse(clzFile, iter, nameIndex, length);
} else {
throw new RuntimeException("not support attribute " + name);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.coding2017.jvm.attr;

import com.coding2017.jvm.clz.ClassFile;
import com.coding2017.jvm.loader.ByteCodeIterator;

public class CodeAttr extends AttributeInfo {
private int maxStack;
private int maxLocals;
private int codeLen;
private String code;

public String getCode() {
return code;
}

// 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 */) {
super(attrNameIndex, attrLen);
this.maxStack = maxStack;
this.maxLocals = maxLocals;
this.codeLen = codeLen;
this.code = code;
// this.cmds = cmds;
}

public void setLineNumberTable(LineNumberTable t) {
this.lineNumTable = t;
}

public void setLocalVariableTable(LocalVariableTable t) {
this.localVarTable = t;
}

public static CodeAttr parse(ClassFile clzFile, ByteCodeIterator iter, int nameIndex, int length) {
int maxStack = iter.nextU2ToInt();
int maxLocals = iter.nextU2ToInt();
int codeLength = iter.nextU4ToInt();
String code = iter.nextUxToHexString(codeLength);
CodeAttr codeAttr = new CodeAttr(nameIndex, length, maxStack, maxLocals, codeLength, code);
int exceptionTableLength = iter.nextU2ToInt();
if(exceptionTableLength > 0){
String exTable = iter.nextUxToHexString(exceptionTableLength * 8);
System.out.println("Encountered exception table , just ignore it :" + exTable);

}
int codeAttributeCount = iter.nextU2ToInt();
for (int j = 0; j < codeAttributeCount; j++) {
AttributeInfo attributeInfo = AttributeInfo.parse(clzFile, iter);
if (attributeInfo instanceof LineNumberTable) {
codeAttr.setLineNumberTable((LineNumberTable) attributeInfo);
} else if (attributeInfo instanceof LocalVariableTable) {
codeAttr.setLocalVariableTable((LocalVariableTable) attributeInfo);
} else if (attributeInfo instanceof StackMapTable) {
codeAttr.setStackMapTable((StackMapTable) attributeInfo);
}
}
return codeAttr;
}

private void setStackMapTable(StackMapTable t) {
this.stackMapTable = t;

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.coding2017.jvm.attr;

import java.util.ArrayList;
import java.util.List;

import com.coding2017.jvm.clz.ClassFile;
import com.coding2017.jvm.loader.ByteCodeIterator;

public class LineNumberTable extends AttributeInfo {
List<LineNumberItem> items = new ArrayList<LineNumberItem>();

private static class LineNumberItem {
int startPC;
int lineNum;

public int getStartPC() {
return startPC;
}

public void setStartPC(int startPC) {
this.startPC = startPC;
}

public int getLineNum() {
return lineNum;
}

public void setLineNum(int lineNum) {
this.lineNum = lineNum;
}
}

public void addLineNumberItem(LineNumberItem item) {
this.items.add(item);
}

public LineNumberTable(int attrNameIndex, int attrLen) {
super(attrNameIndex, attrLen);

}

public static LineNumberTable parse(ClassFile clzFile, ByteCodeIterator iter, int nameIndex, int length) {
int tableLength = iter.nextU2ToInt();
LineNumberTable lineNumberTable = new LineNumberTable(nameIndex, length);
for (int i = 0; i < tableLength; i++) {
LineNumberItem item = new LineNumberItem();
item.setStartPC(iter.nextU2ToInt());
item.setLineNum(iter.nextU2ToInt());
lineNumberTable.addLineNumberItem(item);
}

return lineNumberTable;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.coding2017.jvm.attr;

public class LocalVariableItem {
private int startPC;
private int length;
private int nameIndex;
private int descIndex;
private int index;

public int getStartPC() {
return startPC;
}

public void setStartPC(int startPC) {
this.startPC = startPC;
}

public int getLength() {
return length;
}

public void setLength(int length) {
this.length = length;
}

public int getNameIndex() {
return nameIndex;
}

public void setNameIndex(int nameIndex) {
this.nameIndex = nameIndex;
}

public int getDescIndex() {
return descIndex;
}

public void setDescIndex(int descIndex) {
this.descIndex = descIndex;
}

public int getIndex() {
return index;
}

public void setIndex(int index) {
this.index = index;
}
}
Loading

0 comments on commit f4038da

Please sign in to comment.