Skip to content

Commit 6dd65a7

Browse files
committed
Most mathematical expressions work now
1 parent f10d5a1 commit 6dd65a7

File tree

3 files changed

+692
-171
lines changed

3 files changed

+692
-171
lines changed

compiler/src/main/java/dev/ultreon/pythonc/JvmWriter.java

Lines changed: 153 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,92 @@ public void xorValues() {
691691
}
692692
}
693693

694+
public void notValue() {
695+
Context context = getContext();
696+
Type value = context.pop();
697+
var mv = pc.mv == null ? pc.rootInitMv : pc.mv;
698+
if (value == Type.INT_TYPE) {
699+
mv.visitInsn(ICONST_M1); // Push -1
700+
mv.visitInsn(IXOR); // Perform value ^ -1
701+
context.push(Type.INT_TYPE);
702+
} else if (value == Type.LONG_TYPE) {
703+
mv.visitLdcInsn(-1L); // Push -1 as a long
704+
mv.visitInsn(LXOR); // Perform value ^ -1
705+
context.push(Type.LONG_TYPE);
706+
} else {
707+
throw new RuntimeException("Unsupported not for " + value);
708+
}
709+
}
710+
711+
public void negateValue() {
712+
Context context = getContext();
713+
Type value = context.pop();
714+
var mv = pc.mv == null ? pc.rootInitMv : pc.mv;
715+
if (value == Type.INT_TYPE) {
716+
mv.visitInsn(INEG);
717+
context.push(Type.INT_TYPE);
718+
} else if (value == Type.LONG_TYPE) {
719+
mv.visitInsn(LNEG);
720+
context.push(Type.LONG_TYPE);
721+
} else if (value == Type.DOUBLE_TYPE) {
722+
mv.visitInsn(DNEG);
723+
context.push(Type.DOUBLE_TYPE);
724+
} else if (value == Type.FLOAT_TYPE) {
725+
mv.visitInsn(FNEG);
726+
context.push(Type.FLOAT_TYPE);
727+
} else {
728+
throw new RuntimeException("Unsupported negate for " + value);
729+
}
730+
}
731+
732+
public void leftShiftValues() {
733+
Context context = getContext();
734+
Type left = context.pop();
735+
Type right = context.pop();
736+
var mv = pc.mv == null ? pc.rootInitMv : pc.mv;
737+
if (left == Type.INT_TYPE && right == Type.INT_TYPE) {
738+
mv.visitInsn(ISHL);
739+
context.push(Type.INT_TYPE);
740+
} else if (left == Type.LONG_TYPE && right == Type.INT_TYPE) {
741+
mv.visitInsn(LSHL);
742+
context.push(Type.LONG_TYPE);
743+
} else if (left == Type.INT_TYPE && right == Type.LONG_TYPE) {
744+
mv.visitInsn(L2I);
745+
mv.visitInsn(LSHL);
746+
context.push(Type.LONG_TYPE);
747+
} else if (left == Type.LONG_TYPE && right == Type.LONG_TYPE) {
748+
mv.visitInsn(L2I);
749+
mv.visitInsn(LSHL);
750+
context.push(Type.LONG_TYPE);
751+
} else {
752+
throw new RuntimeException("Unsupported left shift between " + left + " and " + right);
753+
}
754+
}
755+
756+
public void rightShiftValues() {
757+
Context context = getContext();
758+
Type left = context.pop();
759+
Type right = context.pop();
760+
var mv = pc.mv == null ? pc.rootInitMv : pc.mv;
761+
if (left == Type.INT_TYPE && right == Type.INT_TYPE) {
762+
mv.visitInsn(ISHR);
763+
context.push(Type.INT_TYPE);
764+
} else if (left == Type.LONG_TYPE && right == Type.INT_TYPE) {
765+
mv.visitInsn(LSHR);
766+
context.push(Type.LONG_TYPE);
767+
} else if (left == Type.INT_TYPE && right == Type.LONG_TYPE) {
768+
mv.visitInsn(L2I);
769+
mv.visitInsn(LSHR);
770+
context.push(Type.LONG_TYPE);
771+
} else if (left == Type.LONG_TYPE && right == Type.LONG_TYPE) {
772+
mv.visitInsn(L2I);
773+
mv.visitInsn(LSHR);
774+
context.push(Type.LONG_TYPE);
775+
} else {
776+
throw new RuntimeException("Unsupported right shift between " + left + " and " + right);
777+
}
778+
}
779+
694780
public void jump(Label endLabel) {
695781
var mv = pc.mv == null ? pc.rootInitMv : pc.mv;
696782
mv.visitJumpInsn(Opcodes.GOTO, endLabel);
@@ -849,7 +935,8 @@ public void newArray(Type type) {
849935
var mv = pc.mv == null ? pc.rootInitMv : pc.mv;
850936
Context context = getContext();
851937
Type pop = context.pop();
852-
if (pop != Type.INT_TYPE && pop != Type.SHORT_TYPE && pop != Type.BYTE_TYPE) throw new RuntimeException("Expected stack int, got " + pop);
938+
if (pop != Type.INT_TYPE && pop != Type.SHORT_TYPE && pop != Type.BYTE_TYPE)
939+
throw new RuntimeException("Expected stack int, got " + pop);
853940
mv.visitTypeInsn(ANEWARRAY, type.getInternalName());
854941

855942
context.push(Type.getType("[" + type.getDescriptor()));
@@ -892,11 +979,75 @@ public void returnLong() {
892979
mv.visitInsn(LRETURN);
893980
}
894981

895-
public void returnFloat() {
982+
public void returnFloatValues() {
896983
Context context = getContext();
897984
context.pop(Type.FLOAT_TYPE);
898985

899986
var mv = pc.mv == null ? pc.rootInitMv : pc.mv;
900987
mv.visitInsn(FRETURN);
901988
}
989+
990+
public void floorDivideValues() {
991+
Context context = getContext();
992+
Type left = context.pop();
993+
Type right = context.pop();
994+
995+
var mv = pc.mv == null ? pc.rootInitMv : pc.mv;
996+
if (left == Type.INT_TYPE && right == Type.INT_TYPE) {
997+
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Math", "floorDiv", "(II)I", false);
998+
context.push(Type.INT_TYPE);
999+
} else if (left == Type.LONG_TYPE && right == Type.INT_TYPE) {
1000+
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Math", "floorDiv", "(JI)J", false);
1001+
context.push(Type.LONG_TYPE);
1002+
} else if (left == Type.INT_TYPE && right == Type.LONG_TYPE) {
1003+
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Math", "floorDiv", "(JI)J", false);
1004+
context.push(Type.LONG_TYPE);
1005+
} else if (left == Type.LONG_TYPE && right == Type.LONG_TYPE) {
1006+
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Math", "floorDiv", "(JJ)J", false);
1007+
context.push(Type.LONG_TYPE);
1008+
} else {
1009+
throw new RuntimeException("Unsupported floorDiv between " + left + " and " + right);
1010+
}
1011+
}
1012+
1013+
public void powValues() {
1014+
Context context = getContext();
1015+
Type left = context.pop();
1016+
Type right = context.pop();
1017+
1018+
var mv = pc.mv == null ? pc.rootInitMv : pc.mv;
1019+
if (left == Type.INT_TYPE && right == Type.INT_TYPE) {
1020+
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Math", "pow", "(II)D", false);
1021+
context.push(Type.DOUBLE_TYPE);
1022+
} else if (left == Type.LONG_TYPE && right == Type.INT_TYPE) {
1023+
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Math", "pow", "(JI)D", false);
1024+
context.push(Type.DOUBLE_TYPE);
1025+
} else if (left == Type.INT_TYPE && right == Type.LONG_TYPE) {
1026+
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Math", "pow", "(JI)D", false);
1027+
context.push(Type.DOUBLE_TYPE);
1028+
} else if (left == Type.LONG_TYPE && right == Type.LONG_TYPE) {
1029+
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Math", "pow", "(JJ)D", false);
1030+
context.push(Type.DOUBLE_TYPE);
1031+
} else {
1032+
throw new RuntimeException("Unsupported pow between " + left + " and " + right);
1033+
}
1034+
}
1035+
1036+
public void positiveValue() {
1037+
Context context = getContext();
1038+
Type pop = context.pop();
1039+
var mv = pc.mv == null ? pc.rootInitMv : pc.mv;
1040+
if (pop == Type.BOOLEAN_TYPE) {
1041+
// Assume boolean value is on the stack (1 for true, 0 for false)
1042+
Label isFalse = new Label();
1043+
Label end = new Label();
1044+
1045+
mv.visitJumpInsn(IFEQ, isFalse); // If value == 0 (false), jump
1046+
mv.visitInsn(ICONST_1); // Push 1 for true
1047+
mv.visitJumpInsn(GOTO, end);
1048+
mv.visitLabel(isFalse);
1049+
mv.visitInsn(ICONST_0); // Push 0 for false
1050+
mv.visitLabel(end);
1051+
}
1052+
}
9021053
}

0 commit comments

Comments
 (0)