Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support of long arrays; bug fixes #16

Merged
merged 1 commit into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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