Skip to content

Commit 622da78

Browse files
committed
added tests and fixed evaluator
1 parent 100e329 commit 622da78

File tree

5 files changed

+125
-19
lines changed

5 files changed

+125
-19
lines changed

jbbp/src/main/java/com/igormaznitsa/jbbp/compiler/conversion/JBBPToJava6Converter.java

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ public void visitEnd() {
240240
this.builder.mapSubClassesInterfaces,
241241
this.specialSection.toString(),
242242
specialMethodsText.length() == 0 ? null : specialMethodsText,
243-
this.builder.mainClassSustomText
243+
this.builder.mainClassCustomText
244244
);
245245

246246
this.result = buffer.toString();
@@ -606,7 +606,11 @@ private String arg2str(final Object obj) {
606606
throw new Error("Unexpected special");
607607
}
608608
} else if (obj instanceof Integer) {
609-
return obj.toString();
609+
if (((Integer) obj).intValue() < 0) {
610+
return '(' + obj.toString() + ')';
611+
} else {
612+
return obj.toString();
613+
}
610614
} else if (obj instanceof String) {
611615
return String.format("%s.getNamedValue(this, \"%s\")", (getCurrentStruct().isRoot() ? "this" : "this." + NAME_ROOT_STRUCT), obj.toString());
612616
} else if (obj instanceof JBBPNamedFieldInfo) {
@@ -689,7 +693,7 @@ boolean doesNeedBrackets(Object obj) {
689693
}
690694
final ExprTreeItem that = (ExprTreeItem) obj;
691695

692-
return that.op.getPriority() < this.op.getPriority() || ((that.op == Operator.LSHIFT || that.op == Operator.RSHIFT || that.op == Operator.URSHIFT) && (this.op == Operator.LSHIFT || this.op == Operator.RSHIFT || this.op == Operator.URSHIFT));
696+
return that.op.getPriority() <= this.op.getPriority() || ((that.op == Operator.LSHIFT || that.op == Operator.RSHIFT || that.op == Operator.URSHIFT) && (this.op == Operator.LSHIFT || this.op == Operator.RSHIFT || this.op == Operator.URSHIFT));
693697
}
694698

695699
@Override
@@ -709,7 +713,15 @@ public String toString() {
709713

710714
evaluator.visitItems(this.compiledBlock, offsetInBlock, visitor);
711715

712-
return buffer.toString();
716+
String result = buffer.toString();
717+
if (result.startsWith("(") && result.endsWith(")")) {
718+
try{
719+
result = Integer.toString(Integer.parseInt(result.substring(1,result.length()-1).trim()));
720+
}catch(NumberFormatException ex){
721+
// ignore the excepton because it is checking exception
722+
}
723+
}
724+
return result;
713725
}
714726

715727
@Override
@@ -875,7 +887,7 @@ public static final class Builder {
875887
/**
876888
* Text to be inserted into custom section of the resut class.
877889
*/
878-
private String mainClassSustomText;
890+
private String mainClassCustomText;
879891

880892
private Builder(final JBBPParser parser) {
881893
this.srcParser = parser;
@@ -909,9 +921,9 @@ public Builder setMapSubClassesInterfaces(final Map<String, String> mapClassName
909921
* @param value text value, it can be null
910922
* @return the builder instance, must not be null
911923
*/
912-
public Builder setMainClassSustomText(final String value) {
924+
public Builder setMainClassCustomText(final String value) {
913925
assertNonLocked();
914-
this.mainClassSustomText = value;
926+
this.mainClassCustomText = value;
915927
return this;
916928
}
917929

jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/conversion/JBBPToJBBPToJava6ConverterCompilationTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public void testMapSubstructToInterface() throws Exception {
6868
@Test
6969
public void testCustomText() throws Exception {
7070
final JBBPParser parser = JBBPParser.prepare("byte a;");
71-
assertTrue(JBBPToJava6Converter.makeBuilder(parser).setMainClassName(CLASS_NAME).setMainClassSustomText("public void test(){}").build().convert().contains("public void test(){}"));
71+
assertTrue(JBBPToJava6Converter.makeBuilder(parser).setMainClassName(CLASS_NAME).setMainClassCustomText("public void test(){}").build().convert().contains("public void test(){}"));
7272
}
7373

7474
@Test

jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/conversion/JBBPToJBBPToJava6ConverterExpressionTest.java

Lines changed: 89 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,27 @@
2323

2424
import java.io.IOException;
2525
import java.io.InputStream;
26+
import java.lang.reflect.InvocationTargetException;
27+
import java.util.Random;
2628

2729
import static com.igormaznitsa.jbbp.TestUtils.getField;
28-
import static org.junit.Assert.assertTrue;
29-
import static org.junit.Assert.fail;
30+
import static org.junit.Assert.*;
3031

3132
public class JBBPToJBBPToJava6ConverterExpressionTest extends AbstractJBBPToJava6ConverterTest {
3233

34+
private final JBBPBitInputStream UNLIMITED_STREAM = new JBBPBitInputStream(new InputStream() {
35+
@Override
36+
public int read() throws IOException {
37+
return RND.nextInt();
38+
}
39+
});
40+
41+
3342
private void assertExpression(final int etalonValue, final String expression) throws Exception {
34-
assertTrue("Etalon value must not be zero or egative one : " + etalonValue, etalonValue > 0);
43+
assertTrue("Etalon value must not be zero or negative one : " + etalonValue, etalonValue > 0);
3544
final Object obj = compileAndMakeInstance(String.format("byte [%s] data;", expression));
3645

37-
final JBBPBitInputStream in = new JBBPBitInputStream(new InputStream() {
38-
@Override
39-
public int read() throws IOException {
40-
return RND.nextInt();
41-
}
42-
});
43-
44-
callRead(obj, in);
46+
callRead(obj, UNLIMITED_STREAM);
4547

4648
final int detectedlength = getField(obj, "data", byte[].class).length;
4749

@@ -76,11 +78,87 @@ public void testShifts() throws Exception {
7678
assertExpression(123456 >> (3 << 2), "123456>>(3<<2)");
7779
}
7880

81+
@Test
82+
public void testBrackets() throws Exception {
83+
assertExpression(3*(9/2), "3*(9/2)");
84+
}
85+
7986
@Test
8087
public void testComplex() throws Exception {
8188
assertExpression(3 * 2 + 8 << 4 - 3, "3*2+8<<4-3");
8289
assertExpression(3 * 2 + 8 << 4 - 3 & 7, "3*2+8<<4-3&7");
90+
assertExpression(60|7-~17%1, "60|7-~17%1");
8391
assertExpression((11 * (8 - 7)) % 13 + (1234 >> 3 << 2) >>> 1 + (13 - 1) / 2 + ((11 + 22) * 33 / 44 % 55) - (123 & 345 | 234 ^ ~123) & 255, "(11 * (8 - 7)) % 13 + ( 1234>>3<<2)>>>1 + (13 - 1) / 2 + ((11 + 22) * 33 / 44 % 55) - (123 & 345 | 234 ^ ~123) & 255");
8492
}
8593

94+
@Test
95+
public void testSynthesidExpression() throws Exception {
96+
final Random rnd = new Random(5111975);
97+
final String [] operatorsTwo = new String [] {"-","+","*","/","%",">>",">>>","<<","^","|","&"};
98+
final String [] operatorsOne = new String [] {"-","+","~"};
99+
100+
int rightCounter = 0;
101+
102+
for(int i=0;i<1000;i++){
103+
final StringBuilder buffer = new StringBuilder();
104+
if (rnd.nextInt(100)>60) {
105+
buffer.append(operatorsOne[rnd.nextInt(operatorsOne.length)]);
106+
}
107+
buffer.append(1+rnd.nextInt(100));
108+
109+
buffer.append(operatorsTwo[rnd.nextInt(operatorsTwo.length)]);
110+
111+
final int totalItems = rnd.nextInt(100)+1;
112+
int brakeCounter = 0;
113+
114+
for(int j=0;j<totalItems;j++){
115+
if (rnd.nextInt(100)>80) {
116+
buffer.append(operatorsOne[rnd.nextInt(operatorsOne.length)]);
117+
}
118+
buffer.append(1+rnd.nextInt(100));
119+
buffer.append(operatorsTwo[rnd.nextInt(operatorsTwo.length)]);
120+
121+
if (rnd.nextInt(100)>80) {
122+
buffer.append('(');
123+
brakeCounter++;
124+
}
125+
}
126+
127+
buffer.append(1+rnd.nextInt(100));
128+
129+
while(brakeCounter>0){
130+
buffer.append(')');
131+
brakeCounter--;
132+
}
133+
134+
String expression = buffer.toString().replace("--","-").replace("++","+");
135+
136+
Object theInstance;
137+
final StringBuilder src = new StringBuilder();
138+
try {
139+
theInstance = compileAndMakeInstanceSrc("byte [" + expression + "] array;", " public static int makeExpressionResult(){ return " + expression + ";}",src);
140+
} catch(Exception ex){
141+
fail("Can't compile : "+expression);
142+
return;
143+
}
144+
145+
try {
146+
final int etalon = (Integer) theInstance.getClass().getMethod("makeExpressionResult").invoke(null);
147+
if (etalon > 0 && etalon < 100000) {
148+
System.out.println("Testing expression : " + expression);
149+
assertEquals(src.toString(),etalon,getField(callRead(theInstance,new JBBPBitInputStream(UNLIMITED_STREAM)),"array", byte[].class).length);
150+
rightCounter ++;
151+
}
152+
}catch (InvocationTargetException ex){
153+
if (!(ex.getCause() instanceof ArithmeticException)) {
154+
ex.printStackTrace();
155+
fail("Unexpected exception : "+ex.getCause());
156+
return;
157+
}
158+
}
159+
}
160+
161+
System.out.println("Totally generated right expressions : "+rightCounter);
162+
}
163+
86164
}

jbbp/src/test/java/com/igormaznitsa/jbbp/compiler/varlen/JBBPExpressionEvaluatorTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,12 @@ public int provideArraySize(final String fieldName, final JBBPNamedNumericFieldM
493493
assertEquals(123 * (value - 45 / 3), expr.eval(null, 0, compiledBlock, map));
494494
}
495495

496+
@Test
497+
public void testExpression_NotAfterMinus() throws Exception {
498+
JBBPExpressionEvaluator expr = new JBBPExpressionEvaluator("60|7-~17%1", null, null);
499+
assertEquals(60|7-~17%1, expr.eval(null, 0, null, null));
500+
}
501+
496502
@Test
497503
public void testExpression_CheckExternalFieldAndStreamOffset() throws Exception {
498504
final int value = 1234;

jbbp/src/test/java/com/igormaznitsa/jbbp/testaux/AbstractJBBPToJava6ConverterTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import com.igormaznitsa.jbbp.JBBPCustomFieldTypeProcessor;
1919
import com.igormaznitsa.jbbp.JBBPParser;
20+
import com.igormaznitsa.jbbp.compiler.conversion.JBBPToJava6Converter;
2021
import com.igormaznitsa.jbbp.io.JBBPBitInputStream;
2122
import com.igormaznitsa.jbbp.io.JBBPBitOrder;
2223
import com.igormaznitsa.jbbp.io.JBBPBitOutputStream;
@@ -98,6 +99,15 @@ protected void callWrite(final Object instance, final JBBPBitOutputStream outStr
9899
instance.getClass().getMethod("write", JBBPBitOutputStream.class).invoke(instance, outStream);
99100
}
100101

102+
protected Object compileAndMakeInstanceSrc(final String script, final String classCustomText, final StringBuilder srcBuffer) throws Exception {
103+
final String classBody = JBBPToJava6Converter.makeBuilder(JBBPParser.prepare(script)).setMainClassName(CLASS_NAME).setMainClassPackage(PACKAGE_NAME).setMainClassCustomText(classCustomText).build().convert();
104+
if (srcBuffer!=null) {
105+
srcBuffer.append(classBody);
106+
}
107+
final ClassLoader cloader = saveAndCompile(new JavaClassContent(PACKAGE_NAME + '.' + CLASS_NAME, classBody));
108+
return cloader.loadClass(PACKAGE_NAME + '.' + CLASS_NAME).newInstance();
109+
}
110+
101111
protected Object compileAndMakeInstance(final String script) throws Exception {
102112
return this.compileAndMakeInstance(PACKAGE_NAME + '.' + CLASS_NAME, script, null);
103113
}

0 commit comments

Comments
 (0)