Skip to content

Commit

Permalink
Add composite Pattern test including an anonymous class
Browse files Browse the repository at this point in the history
  • Loading branch information
hextriclosan committed Oct 2, 2024
1 parent 823622e commit d2146af
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 0 deletions.
9 changes: 9 additions & 0 deletions tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,15 @@ fn should_do_interface_and_abstract_class() {
assert_eq!(36630, get_int(last_frame_value))
}

#[test]
fn should_do_composite_pattern() {
let mut vm = VM::new("std");
let last_frame_value = vm
.run("samples.inheritance.interfaces.compositepattern.CompositePattern")
.unwrap();
assert_eq!(700, get_int(last_frame_value))
}

fn get_int(locals: Option<Vec<i32>>) -> i32 {
*locals.unwrap().last().unwrap()
}
Expand Down
71 changes: 71 additions & 0 deletions tests/test_data/CompositePattern.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package samples.inheritance.interfaces.compositepattern;

public class CompositePattern {
public static void main(String[] args) {
Composite outerComposite = new Composite(5);
outerComposite.addUnit(new Zealot());
outerComposite.addUnit(new Zealot());
outerComposite.addUnit(new DarkTemplar());
outerComposite.addUnit(new DarkTemplar());

Composite innerComposite = new Composite(3);
innerComposite.addUnit(new Zealot());
innerComposite.addUnit(new Unit() {
@Override
public int attack() {
return 7;
}
});
innerComposite.addUnit(new DarkTemplar());

outerComposite.addUnit(innerComposite);

int result = outerComposite.attack();
}
}

interface Unit {
int attack();
}

class Zealot implements Unit {
@Override
public int attack() {
return 11;
}
}

class DarkTemplar implements Unit {
@Override
public int attack() {
return 220;
}
}

class Composite implements Unit {

private final Unit[] units;
private int currentIndex;

public Composite(int size) {
units = new Unit[size];
currentIndex = 0;
}

public void addUnit(Unit unit) {
units[currentIndex++] = unit;
}

@Override
public int attack() {
int attackPower = 0;

for (Unit unit : units) {
if (unit != null) {
attackPower += unit.attack();
}
}

return attackPower;
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
17 changes: 17 additions & 0 deletions vm/src/execution_engine/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,17 @@ impl Engine {
stack_frame.incr_pc();
println!("DUP -> value={value}");
}
DUP_X1 => {
let value1 = stack_frame.pop();
let value2 = stack_frame.pop();
stack_frame.push(value1);
stack_frame.push(value2);
stack_frame.push(value1);


stack_frame.incr_pc();
println!("DUP_X1 -> value1={value1}, value2={value2}, value1={value1}");
}
DUP2 => {
let value1 = stack_frame.pop();
let value2 = stack_frame.pop();
Expand Down Expand Up @@ -1068,6 +1079,12 @@ impl Engine {
stack_frame.incr_pc();
println!("ARRAYLENGTH -> arrayref={arrayref}, len={len}");
}
IFNULL => { //todo: this one is opposite to IFNE ops code
let value = stack_frame.pop();
let offset = Self::get_two_bytes_ahead(stack_frame);
stack_frame.advance_pc(if value == 0 { offset } else { 3 });
println!("IFNULL -> value={value}, offset={offset}");
}
_ => unreachable!("{}", format! {"xxx = {}", stack_frame.get_bytecode_byte()}),
}
}
Expand Down

0 comments on commit d2146af

Please sign in to comment.