Skip to content

Commit

Permalink
Add support of long arrays; bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
hextriclosan committed Sep 19, 2024
1 parent e875902 commit 17eb519
Show file tree
Hide file tree
Showing 21 changed files with 565 additions and 104 deletions.
4 changes: 2 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ fn main() {
};

println!(
"\nresult={}",
result.map_or_else(|| "<empty>".to_string(), |v| v.to_string())
"\nresult={:?}",
result.map_or_else(|| vec![], |v| v)
);
}
81 changes: 69 additions & 12 deletions tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use vm::vm::VM;
fn should_do_adding() {
let vm = VM::new(vec!["tests/test_data/Adder.class"], "tests/test_data/std").unwrap();
let last_frame_value = vm.run("Adder").unwrap();
assert_eq!(55, last_frame_value.unwrap())
assert_eq!(55, get_int(last_frame_value))
}

#[test]
Expand All @@ -15,21 +15,32 @@ fn should_do_adding_with_longs() {
)
.unwrap();
let last_frame_value = vm.run("AdderLong").unwrap();
assert_eq!(1_000_000_000, last_frame_value.unwrap())
assert_eq!(171798691900, get_long(last_frame_value))
}

#[test]
fn should_do_adding_with_negative_longs() {
let vm = VM::new(
vec!["tests/test_data/AdderNegativeLong.class"],
"tests/test_data/std",
)
.unwrap();
let last_frame_value = vm.run("AdderNegativeLong").unwrap();
assert_eq!(-1990000000000000, get_long(last_frame_value))
}

#[test]
fn should_do_subtraction() {
let vm = VM::new(vec!["tests/test_data/Sub.class"], "tests/test_data/std").unwrap();
let last_frame_value = vm.run("Sub").unwrap();
assert_eq!(-999, last_frame_value.unwrap())
assert_eq!(-999, get_int(last_frame_value))
}

#[test]
fn should_do_subtraction_with_longs() {
let vm = VM::new(vec!["tests/test_data/SubLong.class"], "tests/test_data/std").unwrap();
let last_frame_value = vm.run("SubLong").unwrap();
assert_eq!(1_000_000_000, last_frame_value.unwrap())
assert_eq!(-1_000_000_000, get_long(last_frame_value))
}

#[test]
Expand All @@ -43,7 +54,21 @@ fn should_write_read_instance_fields() {
)
.unwrap();
let last_frame_value = vm.run("InstanceFieldsUser").unwrap();
assert_eq!(110022, last_frame_value.unwrap())
assert_eq!(110022, get_int(last_frame_value))
}

#[test]
fn should_write_read_instance_fields_with_longs() {
let vm = VM::new(
vec![
"tests/test_data/InstanceFieldsUserLong.class",
"tests/test_data/InstanceFieldsLong.class",
],
"tests/test_data/std",
)
.unwrap();
let last_frame_value = vm.run("InstanceFieldsUserLong").unwrap();
assert_eq!(4_380_866_642_760, get_long(last_frame_value))
}

#[test]
Expand All @@ -57,7 +82,7 @@ fn should_write_read_static_fields() {
)
.unwrap();
let last_frame_value = vm.run("StaticFieldsUser").unwrap();
assert_eq!(110022, last_frame_value.unwrap())
assert_eq!(110022, get_int(last_frame_value))
}

#[test]
Expand All @@ -68,7 +93,18 @@ fn should_do_extreme_stack_operations() {
)
.unwrap();
let last_frame_value = vm.run("ExtremeStackTest").unwrap();
assert_eq!(454, last_frame_value.unwrap())
assert_eq!(454, get_int(last_frame_value))
}

#[test]
fn should_do_extreme_stack_operations_with_longs() {
let vm = VM::new(
vec!["tests/test_data/ExtremeStackTestLong.class"],
"tests/test_data/std",
)
.unwrap();
let last_frame_value = vm.run("ExtremeStackTestLong").unwrap();
assert_eq!(454, get_long(last_frame_value))
}

#[test]
Expand All @@ -79,7 +115,7 @@ fn should_do_calculate_fibonacci_iteratively() {
)
.unwrap();
let last_frame_value = vm.run("FibonacciIterative").unwrap();
assert_eq!(55, last_frame_value.unwrap())
assert_eq!(55, get_int(last_frame_value))
}

#[test]
Expand All @@ -90,14 +126,21 @@ fn should_do_calculate_fibonacci_recursively() {
)
.unwrap();
let last_frame_value = vm.run("FibonacciRecursive").unwrap();
assert_eq!(55, last_frame_value.unwrap())
assert_eq!(55, get_int(last_frame_value))
}

#[test]
fn should_do_arrays() {
let vm = VM::new(vec!["tests/test_data/Array.class"], "tests/test_data/std").unwrap();
let last_frame_value = vm.run("Array").unwrap();
assert_eq!(740, last_frame_value.unwrap())
assert_eq!(740, get_int(last_frame_value))
}

#[test]
fn should_do_arrays_with_longs() {
let vm = VM::new(vec!["tests/test_data/ArrayLong.class"], "tests/test_data/std").unwrap();
let last_frame_value = vm.run("ArrayLong").unwrap();
assert_eq!(233646220932000, get_long(last_frame_value))
}

#[test]
Expand All @@ -108,7 +151,7 @@ fn should_do_class_static_initialization() {
)
.unwrap();
let last_frame_value = vm.run("StaticInitialization").unwrap();
assert_eq!(257, last_frame_value.unwrap())
assert_eq!(257, get_int(last_frame_value))
}

#[ignore]
Expand All @@ -124,5 +167,19 @@ fn should_do_class_static_initialization_multiple_classes() {
)
.unwrap();
let last_frame_value = vm.run("StaticInitializationUser").unwrap();
assert_eq!(350, last_frame_value.unwrap())
assert_eq!(350, get_int(last_frame_value))
}

fn get_int(locals: Option<Vec<i32>>) -> i32 {
*locals.unwrap().last().unwrap()
}

fn get_long(locals_opt: Option<Vec<i32>>) -> i64 {
let locals = locals_opt.unwrap();

let two = &locals[locals.len().saturating_sub(2)..];
let low = two[0];
let high = two[1];

((high as i64) << 32) | (low as i64)
}
Binary file modified tests/test_data/AdderLong.class
Binary file not shown.
6 changes: 4 additions & 2 deletions tests/test_data/AdderLong.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
//javac -g -parameters Adder.java

public class AdderLong {

public static void main(String[] args) {
long result = add(100_000_000_000L, -99_000_000_000L);
long result = add(
42_949_672_980L/*h=10,l=20*/,
128_849_018_920L/*h=30,l=40*/
);
}

private static long add(long a, long b) {
Expand Down
Binary file added tests/test_data/AdderNegativeLong.class
Binary file not shown.
12 changes: 12 additions & 0 deletions tests/test_data/AdderNegativeLong.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

public class AdderNegativeLong {

public static void main(String[] args) {
long result = add(-1_000_000_000_000_000L, -990_000_000_000_000L);
}

private static long add(long a, long b) {
return a + b;
}

}
Binary file added tests/test_data/ArrayLong.class
Binary file not shown.
134 changes: 134 additions & 0 deletions tests/test_data/ArrayLong.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
public class ArrayLong {

public static void main(String[] args) {
long result = calculate();
}

private static long calculate() {
// 1. Initialize two arrays with different sizes
long[] numbers1 = {
42_949_672_980l/*h=10,l=20*/,
128_849_018_920l/*h=30,l=40*/,
214_748_364_860l/*h=50,l=60*/,
300_647_710_800l/*h=70,l=80*/
};
long[] numbers2 = {
386_547_056_740l/*h=90,l=100*/,
472_446_402_680l/*h=110,l=120*/,
558_345_748_620l/*h=130,l=140*/,
644_245_094_560l/*h=150,l=160*/
};

// 2. Combine two arrays dynamically
long[] combinedArray = combineArrays(numbers1, numbers2);

// 3. Modify the combined array by squaring even numbers
squareEvenNumbers(combinedArray);

// 4. Double the size of the combined array dynamically
combinedArray = resizeArray(combinedArray, combinedArray.length * 2);

// 5. Fill the new half of the array with values
for (int i = combinedArray.length / 2; i < combinedArray.length; i++) {
combinedArray[i] = i * 2; // Fill new slots with multiples of 2
}

// 6. Find the second largest element in the combined array
long secondLargest = findSecondLargest(combinedArray);

// 7. Reverse the combined array
reverseArray(combinedArray);


// 8. Shift array elements to the left by 11 positions
shiftLeft(combinedArray, 11);

return combinedArray[0] + secondLargest;
}

// Method to combine two arrays into one dynamically
private static long[] combineArrays(long[] array1, long[] array2) {
int newLength = array1.length + array2.length;
long[] result = new long[newLength];

// Copy elements from the first array
for (int i = 0; i < array1.length; i++) {
result[i] = array1[i];
}

// Copy elements from the second array
for (int i = 0; i < array2.length; i++) {
result[array1.length + i] = array2[i];
}

return result;
}

// Method to square even numbers in the array
private static void squareEvenNumbers(long[] array) {
for (int i = 0; i < array.length; i++) {
if (array[i] % 2 == 0) {
array[i] = array[i] * array[i];
}
}
}

// Method to resize the array dynamically
private static long[] resizeArray(long[] array, int newSize) {
long[] newArray = new long[newSize];
for (int i = 0; i < array.length; i++) {
newArray[i] = array[i];
}
return newArray;
}

// Method to find the second largest element in the array
private static long findSecondLargest(long[] array) {
long largest = Long.MIN_VALUE;
long secondLargest = Long.MIN_VALUE;

for (long num : array) {
if (num > largest) {
secondLargest = largest;
largest = num;
} else if (num > secondLargest && num != largest) {
secondLargest = num;
}
}
return secondLargest;
}

// Method to reverse the array in place
private static void reverseArray(long[] array) {
int start = 0;
int end = array.length - 1;
while (start < end) {
long temp = array[start];
array[start] = array[end];
array[end] = temp;
start++;
end--;
}
}

// Method to shift the array elements to the left by a given number of positions
private static void shiftLeft(long[] array, int positions) {
int length = array.length;
long[] temp = new long[positions];

// Store the first 'positions' elements in a temporary array
for (int i = 0; i < positions; i++) {
temp[i] = array[i];
}

// Shift the remaining elements to the left
for (int i = positions; i < length; i++) {
array[i - positions] = array[i];
}

// Place the stored elements at the end
for (int i = 0; i < positions; i++) {
array[length - positions + i] = temp[i];
}
}
}
Binary file added tests/test_data/ExtremeStackTestLong.class
Binary file not shown.
Loading

0 comments on commit 17eb519

Please sign in to comment.