package org.reldb.rel.v0.tests.engine;
import org.junit.Test;
import org.reldb.rel.exceptions.DatabaseFormatVersionException;
import org.reldb.rel.v0.generator.Generator;
import org.reldb.rel.v0.interpreter.Instance;
import org.reldb.rel.v0.interpreter.Interpreter;
import org.reldb.rel.v0.storage.RelDatabase;
import org.reldb.rel.v0.values.*;
import org.reldb.rel.v0.vm.*;
import org.reldb.rel.v0.vm.instructions.core.*;
public class TestVM {
private Instance instance;
private Generator generator;
private VirtualMachine machine;
public TestVM() throws DatabaseFormatVersionException {
instance = new Instance("./", true, System.out);
RelDatabase database = instance.getDatabase();
Interpreter interpreter = new Interpreter(database, System.out);
generator = interpreter.getGenerator();
machine = new VirtualMachine(generator, null, System.out);
}
private CellMutableFactory cellGenerator = new CellMutableFactory();
@Test
public void testVMSimple() {
machine.reset();
Operator code = new Operator(0);
code.compile(new OpPushLiteral(ValueInteger.select(generator, 60))); // PUSH 60
code.compile(new OpPushLiteral(ValueInteger.select(generator, 45))); // PUSH 45
code.compile(new OpAdd()); // +
code.compile(new OpWriteRaw()); // WRITE
code.compile(new OpReturn()); // RETURN
(new Dumper()).dumpMachineCode(code);
machine.execute(code);
}
@Test
public void testVMComplex() {
machine.reset();
Operator code = new Operator(0, 1);
code.compile(new OpPushLiteral(ValueInteger.select(generator, 200))); // PUSH 200
code.compile(new OpVariableInitialise(0, 0, cellGenerator)); // assign to COUNTER
code.compile(new OpPushLiteral(ValueInteger.select(generator, 3))); // <HERE> PUSH 3
code.compile(new OpPushLiteral(ValueInteger.select(generator, 4))); // PUSH 4
code.compile(new OpAdd()); // +
code.compile(new OpWriteRaw()); // WRITE
code.compile(new OpVariableGet(0, 0)); // COUNTER
code.compile(new OpWriteRaw()); // WRITE
code.compile(new OpVariableGet(0, 0)); // COUNTER
code.compile(new OpPushLiteral(ValueInteger.select(generator, -1))); // PUSH -1
code.compile(new OpAdd()); // +
code.compile(new OpVariableSet(0, 0)); // assign to COUNTER
code.compile(new OpVariableGet(0, 0)); // COUNTER
code.compile(new OpPushLiteral(ValueInteger.select(generator, 0))); // PUSH 0
code.compile(new OpLte()); // <=
code.compile(new OpBranchIfTrue(17)); // Jump if true to <DONE>
code.compile(new OpJump(2)); // Jump to <HERE>
code.compile(new OpReturn()); // <DONE> RETURN
(new Dumper()).dumpMachineCode(code);
machine.execute(code);
}
@Test
public void testVMFnCall() {
machine.reset();
// void writeInt(int x)
Operator writeInt = new Operator(1);
writeInt.setParameterCount(1);
writeInt.compile(new OpParameterGet(1, 0)); // PUSH x
writeInt.compile(new OpWriteRaw()); // write X
writeInt.compile(new OpReturn()); // RETURN
// main
Operator main = new Operator(0, 1);
main.compile(new OpPushLiteral(ValueInteger.select(generator, 200))); // PUSH 200
main.compile(new OpVariableInitialise(0, 0, cellGenerator)); // assign to COUNTER
main.compile(new OpNop()); // <HERE> writeInt(
main.compile(new OpVariableGet(0, 0)); // COUNTER
main.compile(new OpInvoke(writeInt)); // );
main.compile(new OpVariableGet(0, 0)); // COUNTER
main.compile(new OpPushLiteral(ValueInteger.select(generator, -1))); // PUSH -1
main.compile(new OpAdd()); // +
main.compile(new OpVariableSet(0, 0)); // assign to COUNTER
main.compile(new OpVariableGet(0, 0)); // COUNTER
main.compile(new OpPushLiteral(ValueInteger.select(generator, 0))); // PUSH 0
main.compile(new OpLte()); // <=
main.compile(new OpBranchIfTrue(14)); // Jump if true to <DONE>
main.compile(new OpJump(2)); // Jump to <HERE>
main.compile(new OpReturn()); // <DONE> RETURN
(new Dumper()).dumpMachineCode(main);
machine.execute(main);
}
}