Skip to content

Commit

Permalink
✨ feat: Add NOT for int
Browse files Browse the repository at this point in the history
  • Loading branch information
caoccao committed Nov 2, 2024
1 parent 699e248 commit ad74438
Show file tree
Hide file tree
Showing 7 changed files with 222 additions and 10 deletions.
30 changes: 30 additions & 0 deletions scripts/ts/test/test.logical.operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,30 @@ class Test {
public logicalNotEQ_IL_Z(a: int, b: long): boolean {
return a != b;
}

public logicalNot_EQEQ_II_Z(a: int, b: int): boolean {
return !(a === b);
}

public logicalNot_EQ_II_Z(a: int, b: int): boolean {
return !(a == b);
}

public logicalNot_GE_II_Z(a: int, b: int): boolean {
return !(a >= b);
}

public logicalNot_GT_II_Z(a: int, b: int): boolean {
return !(a > b);
}

public logicalNot_LE_II_Z(a: int, b: int): boolean {
return !(a <= b);
}

public logicalNot_LT_II_Z(a: int, b: int): boolean {
return !(a < b);
}
}

console.log(new Test().logicalEQEQ_DD_Z(1, 2));
Expand Down Expand Up @@ -186,3 +210,9 @@ console.log(new Test().logicalNotEQ_DD_Z(1, 2));
console.log(new Test().logicalNotEQ_FF_Z(1, 2));
console.log(new Test().logicalNotEQ_II_Z(1, 2));
console.log(new Test().logicalNotEQ_IL_Z(1, 2));
console.log(new Test().logicalNot_EQEQ_II_Z(1, 2));
console.log(new Test().logicalNot_EQ_II_Z(1, 2));
console.log(new Test().logicalNot_GE_II_Z(1, 2));
console.log(new Test().logicalNot_GT_II_Z(1, 2));
console.log(new Test().logicalNot_LT_II_Z(1, 2));
console.log(new Test().logicalNot_LE_II_Z(1, 2));
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@
import java.util.List;

public final class Ts2JavaAstBinExpr implements ITs2JavaAstStackManipulation<Swc4jAstBinExpr> {
private boolean logicalNot;

public Ts2JavaAstBinExpr() {
logicalNot = false;
}

public boolean isLogicalNot() {
return logicalNot;
}

@Override
public TypeDescription manipulate(JavaFunctionContext functionContext, Swc4jAstBinExpr ast) {
final List<StackManipulation> stackManipulations = functionContext.getStackManipulations();
Expand Down Expand Up @@ -74,7 +84,7 @@ public TypeDescription manipulate(JavaFunctionContext functionContext, Swc4jAstB
case NotEq:
case NotEqEq:
stackManipulation = Ts2JavaAstBinaryOp.getLogical(
functionContext, ast.getOp(), upCaseType);
functionContext, ast.getOp(), upCaseType, logicalNot);
break;
// case BitAnd:
// stackManipulation = Ts2JavaAstBinaryOp.getBitAndStackManipulation(functionContext);
Expand Down Expand Up @@ -105,4 +115,9 @@ private TypeDescription manipulateExpression(JavaFunctionContext functionContext
SimpleMap.of("exprType", expression.getType().name())));
}
}

public Ts2JavaAstBinExpr setLogicalNot(boolean logicalNot) {
this.logicalNot = logicalNot;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ public static Division getDivision(TypeDescription type) {
public static StackManipulation getLogical(
JavaFunctionContext functionContext,
Swc4jAstBinaryOp binaryOp,
TypeDescription type) {
TypeDescription type,
boolean logicalNot) {
functionContext.increaseLogicalDepth();
Label labelFalse = functionContext.getLogicalLabels().get(1);
List<StackManipulation> stackManipulations = new ArrayList<>();
Expand All @@ -97,24 +98,24 @@ public static StackManipulation getLogical(
int opcodeCompare;
switch (binaryOp) {
case Gt:
opcodeCompare = Opcodes.IF_ICMPLE;
opcodeCompare = logicalNot ? Opcodes.IF_ICMPGT : Opcodes.IF_ICMPLE;
break;
case GtEq:
opcodeCompare = Opcodes.IF_ICMPLT;
opcodeCompare = logicalNot ? Opcodes.IF_ICMPGE : Opcodes.IF_ICMPLT;
break;
case Lt:
opcodeCompare = Opcodes.IF_ICMPGE;
opcodeCompare = logicalNot ? Opcodes.IF_ICMPLT : Opcodes.IF_ICMPGE;
break;
case LtEq:
opcodeCompare = Opcodes.IF_ICMPGT;
opcodeCompare = logicalNot ? Opcodes.IF_ICMPLE : Opcodes.IF_ICMPGT;
break;
case EqEq:
case EqEqEq:
opcodeCompare = Opcodes.IF_ICMPNE;
opcodeCompare = logicalNot ? Opcodes.IF_ICMPEQ : Opcodes.IF_ICMPNE;
break;
case NotEq:
case NotEqEq:
opcodeCompare = Opcodes.IF_ICMPEQ;
opcodeCompare = logicalNot ? Opcodes.IF_ICMPNE : Opcodes.IF_ICMPEQ;
break;
default:
throw new Ts2JavaException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.caoccao.javet.buddy.ts2java.exceptions.Ts2JavaAstException;
import com.caoccao.javet.swc4j.ast.expr.Swc4jAstBinExpr;
import com.caoccao.javet.swc4j.ast.expr.Swc4jAstIdent;
import com.caoccao.javet.swc4j.ast.expr.Swc4jAstUnaryExpr;
import com.caoccao.javet.swc4j.ast.interfaces.ISwc4jAstExpr;
import com.caoccao.javet.swc4j.ast.stmt.Swc4jAstReturnStmt;
import com.caoccao.javet.utils.SimpleFreeMarkerFormat;
Expand All @@ -34,14 +35,17 @@ public TypeDescription manipulate(JavaFunctionContext functionContext, Swc4jAstR
TypeDescription returnType = TypeDescription.ForLoadedType.of(void.class);
if (ast.getArg().isPresent()) {
TypeDescription fromType;
ISwc4jAstExpr arg = ast.getArg().get();
ISwc4jAstExpr arg = ast.getArg().get().unParenExpr();
switch (arg.getType()) {
case BinExpr:
fromType = new Ts2JavaAstBinExpr().manipulate(functionContext, arg.as(Swc4jAstBinExpr.class));
break;
case Ident:
fromType = new Ts2JavaAstIdent().manipulate(functionContext, arg.as(Swc4jAstIdent.class));
break;
case UnaryExpr:
fromType = new Ts2JavaAstUnaryExpr().manipulate(functionContext, arg.as(Swc4jAstUnaryExpr.class));
break;
default:
throw new Ts2JavaAstException(
arg,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2024-2024. caoccao.com Sam Cao
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.caoccao.javet.buddy.ts2java.ast;

import com.caoccao.javet.buddy.ts2java.compiler.JavaFunctionContext;
import com.caoccao.javet.buddy.ts2java.exceptions.Ts2JavaAstException;
import com.caoccao.javet.swc4j.ast.expr.Swc4jAstBinExpr;
import com.caoccao.javet.swc4j.ast.expr.Swc4jAstUnaryExpr;
import com.caoccao.javet.swc4j.ast.interfaces.ISwc4jAstExpr;
import com.caoccao.javet.utils.SimpleFreeMarkerFormat;
import com.caoccao.javet.utils.SimpleMap;
import net.bytebuddy.description.type.TypeDescription;

public final class Ts2JavaAstUnaryExpr implements ITs2JavaAstStackManipulation<Swc4jAstUnaryExpr> {
@Override
public TypeDescription manipulate(JavaFunctionContext functionContext, Swc4jAstUnaryExpr ast) {
ISwc4jAstExpr arg = ast.getArg().unParenExpr();
switch (ast.getOp()) {
case Bang:
switch (arg.getType()) {
case BinExpr:
return new Ts2JavaAstBinExpr().setLogicalNot(true).manipulate(
functionContext, arg.as(Swc4jAstBinExpr.class));
default:
throw new Ts2JavaAstException(
arg,
SimpleFreeMarkerFormat.format("UnaryExpr arg type ${argType} is not supported.",
SimpleMap.of("argType", arg.getType().name())));
}
default:
throw new Ts2JavaAstException(
ast,
SimpleFreeMarkerFormat.format("UnaryExpr op ${op} is not supported.",
SimpleMap.of("op", ast.getOp().name())));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public TypeDescription manipulate(JavaFunctionContext functionContext, Swc4jAstV
Swc4jAstTsTypeAnn tsTypeAnn = bindingIdent.getTypeAnn().get();
TypeDescription variableType = Ts2JavaAstTsTypeAnn.getTypeDescription(tsTypeAnn);
if (varDeclarator.getInit().isPresent()) {
ISwc4jAstExpr expression = varDeclarator.getInit().get();
ISwc4jAstExpr expression = varDeclarator.getInit().get().unParenExpr();
TypeDescription valueType;
switch (expression.getType()) {
case BinExpr: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,32 @@ public boolean logicalGT_II_Z(int a, int b) {
return a > b;
}

/*
public logicalNot_II_Z(II)Z
L0
LINENUMBER 204 L0
ILOAD 1
ILOAD 2
IF_ICMPEQ L1
ICONST_1
GOTO L2
L1
FRAME SAME
ICONST_0
L2
FRAME SAME1 I
IRETURN
L3
LOCALVARIABLE this Lcom/caoccao/javet/buddy/ts2java/ast/TestLogicalOperations; L0 L3 0
LOCALVARIABLE a I L0 L3 1
LOCALVARIABLE b I L0 L3 2
MAXSTACK = 2
MAXLOCALS = 3
*/
public boolean logicalNot_EQ_II_Z(int a, int b) {
return !(a == b);
}

/*
public logicalAnd_II_Z(II)Z
L0
Expand Down Expand Up @@ -738,4 +764,89 @@ public void testLogicalNotEQ_IL_Z() throws Exception {
assertTrue((boolean) method.invoke(object, 2, 1L));
assertFalse((boolean) method.invoke(object, 1, 1L));
}

@Test
public void testLogicalNot_EQEQ_II_Z() throws Exception {
Method method = clazz.getMethod("logicalNot_EQEQ_II_Z", int.class, int.class);
assertNotNull(method);
assertEquals(boolean.class, method.getReturnType());
assertEquals(2, method.getParameterCount());
assertEquals(int.class, method.getParameters()[0].getType());
assertEquals(int.class, method.getParameters()[1].getType());
Object object = clazz.getConstructor().newInstance();
assertTrue((boolean) method.invoke(object, 1, 2));
assertTrue((boolean) method.invoke(object, 2, 1));
assertFalse((boolean) method.invoke(object, 1, 1));
}

@Test
public void testLogicalNot_EQ_II_Z() throws Exception {
assertTrue(logicalNot_EQ_II_Z(1, 2));
Method method = clazz.getMethod("logicalNot_EQ_II_Z", int.class, int.class);
assertNotNull(method);
assertEquals(boolean.class, method.getReturnType());
assertEquals(2, method.getParameterCount());
assertEquals(int.class, method.getParameters()[0].getType());
assertEquals(int.class, method.getParameters()[1].getType());
Object object = clazz.getConstructor().newInstance();
assertTrue((boolean) method.invoke(object, 1, 2));
assertTrue((boolean) method.invoke(object, 2, 1));
assertFalse((boolean) method.invoke(object, 1, 1));
}

@Test
public void testLogicalNot_GE_II_Z() throws Exception {
Method method = clazz.getMethod("logicalNot_GE_II_Z", int.class, int.class);
assertNotNull(method);
assertEquals(boolean.class, method.getReturnType());
assertEquals(2, method.getParameterCount());
assertEquals(int.class, method.getParameters()[0].getType());
assertEquals(int.class, method.getParameters()[1].getType());
Object object = clazz.getConstructor().newInstance();
assertTrue((boolean) method.invoke(object, 1, 2));
assertFalse((boolean) method.invoke(object, 2, 1));
assertFalse((boolean) method.invoke(object, 1, 1));
}

@Test
public void testLogicalNot_GT_II_Z() throws Exception {
Method method = clazz.getMethod("logicalNot_GT_II_Z", int.class, int.class);
assertNotNull(method);
assertEquals(boolean.class, method.getReturnType());
assertEquals(2, method.getParameterCount());
assertEquals(int.class, method.getParameters()[0].getType());
assertEquals(int.class, method.getParameters()[1].getType());
Object object = clazz.getConstructor().newInstance();
assertTrue((boolean) method.invoke(object, 1, 2));
assertFalse((boolean) method.invoke(object, 2, 1));
assertTrue((boolean) method.invoke(object, 1, 1));
}

@Test
public void testLogicalNot_LE_II_Z() throws Exception {
Method method = clazz.getMethod("logicalNot_LE_II_Z", int.class, int.class);
assertNotNull(method);
assertEquals(boolean.class, method.getReturnType());
assertEquals(2, method.getParameterCount());
assertEquals(int.class, method.getParameters()[0].getType());
assertEquals(int.class, method.getParameters()[1].getType());
Object object = clazz.getConstructor().newInstance();
assertFalse((boolean) method.invoke(object, 1, 2));
assertTrue((boolean) method.invoke(object, 2, 1));
assertFalse((boolean) method.invoke(object, 1, 1));
}

@Test
public void testLogicalNot_LT_II_Z() throws Exception {
Method method = clazz.getMethod("logicalNot_LT_II_Z", int.class, int.class);
assertNotNull(method);
assertEquals(boolean.class, method.getReturnType());
assertEquals(2, method.getParameterCount());
assertEquals(int.class, method.getParameters()[0].getType());
assertEquals(int.class, method.getParameters()[1].getType());
Object object = clazz.getConstructor().newInstance();
assertFalse((boolean) method.invoke(object, 1, 2));
assertTrue((boolean) method.invoke(object, 2, 1));
assertTrue((boolean) method.invoke(object, 1, 1));
}
}

0 comments on commit ad74438

Please sign in to comment.