Skip to content
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: 4 additions & 0 deletions include/scratchcpp/virtualmachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,11 @@ class LIBSCRATCHCPP_EXPORT VirtualMachine

void setBytecode(unsigned int *code);

unsigned int **procedures() const;
const BlockFunc *functions() const;
const Value *constValues() const;
Value **variables() const;
List **lists() const;

unsigned int *bytecode() const;

Expand Down
8 changes: 4 additions & 4 deletions src/engine/script_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ struct ScriptPrivate
ScriptPrivate(Target *target, IEngine *engine);
ScriptPrivate(const ScriptPrivate &) = delete;

unsigned int *bytecode;
unsigned int *bytecode = nullptr;
std::vector<unsigned int> bytecodeVector;

Target *target;
IEngine *engine;
Target *target = nullptr;
IEngine *engine = nullptr;

unsigned int **procedures = nullptr;
std::vector<unsigned int *> proceduresVector;

BlockFunc *functions;
BlockFunc *functions = nullptr;
std::vector<BlockFunc> functionsVector;

const Value *constValues = nullptr;
Expand Down
24 changes: 24 additions & 0 deletions src/engine/virtualmachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,36 @@ void VirtualMachine::setBytecode(unsigned int *code)
impl->pos = code;
}

/*! Returns the array of procedures. */
unsigned int **VirtualMachine::procedures() const
{
return impl->procedures;
}

/*! Returns the array of functions (block implementation function pointers). */
const BlockFunc *VirtualMachine::functions() const
{
return impl->functions;
}

/*! Returns the array of constant values. */
const Value *VirtualMachine::constValues() const
{
return impl->constValues;
}

/*! Returns the array of Value pointers of variables. */
Value **VirtualMachine::variables() const
{
return impl->variables;
}

/*! Returns the array of lists. */
List **VirtualMachine::lists() const
{
return impl->lists;
}

/*! Returns the bytecode array. */
unsigned int *VirtualMachine::bytecode() const
{
Expand Down
2 changes: 1 addition & 1 deletion src/engine/virtualmachine_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ struct VirtualMachinePrivate
bool updatePos = false;

unsigned int **procedures = nullptr;
BlockFunc *functions;
BlockFunc *functions = nullptr;
const Value *constValues = nullptr;
Value **variables = nullptr;
List **lists = nullptr;
Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ add_subdirectory(target_interfaces)
add_subdirectory(blocks)
add_subdirectory(scratchconfiguration)
add_subdirectory(assets)
add_subdirectory(script)
14 changes: 14 additions & 0 deletions test/script/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
add_executable(
script_test
script_test.cpp
)

target_link_libraries(
script_test
GTest::gtest_main
GTest::gmock_main
scratchcpp
scratchcpp_mocks
)

gtest_discover_tests(script_test)
84 changes: 84 additions & 0 deletions test/script/script_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#include <scratchcpp/script.h>
#include <scratchcpp/virtualmachine.h>
#include <scratchcpp/target.h>
#include <scratchcpp/list.h>
#include <enginemock.h>

#include "../common.h"

using namespace libscratchcpp;

class ScriptTest : public testing::Test
{
public:
Target m_target;
EngineMock m_engine;
};

TEST_F(ScriptTest, Bytecode)
{
Script script(nullptr, nullptr);
ASSERT_EQ(script.bytecode(), nullptr);
ASSERT_TRUE(script.bytecodeVector().empty());

script.setBytecode({ vm::OP_START, vm::OP_HALT });
ASSERT_EQ(script.bytecode()[0], vm::OP_START);
ASSERT_EQ(script.bytecode()[1], vm::OP_HALT);
ASSERT_EQ(script.bytecodeVector(), std::vector<unsigned int>({ vm::OP_START, vm::OP_HALT }));
}

unsigned int testFunction(VirtualMachine *)
{
return 0;
}

TEST_F(ScriptTest, Start)
{
static std::vector<unsigned int> bytecode = { vm::OP_START, vm::OP_HALT };
static std::vector<unsigned int *> procedures = { bytecode.data() };
static std::vector<BlockFunc> functions = { &testFunction };
static std::vector<Value> constValues = { "test" };

std::unique_ptr<Value> var = std::make_unique<Value>();
static std::vector<Value *> variables = { var.get() };

std::unique_ptr<List> list = std::make_unique<List>("", "");
static std::vector<List *> lists = { list.get() };

Script script1(nullptr, nullptr);

std::shared_ptr<VirtualMachine> vm = script1.start();
ASSERT_TRUE(vm);
ASSERT_EQ(vm->target(), nullptr);
ASSERT_EQ(vm->engine(), nullptr);
ASSERT_EQ(vm->bytecode(), nullptr);
ASSERT_EQ(vm->procedures(), nullptr);
ASSERT_EQ(vm->functions(), nullptr);
ASSERT_EQ(vm->constValues(), nullptr);
ASSERT_EQ(vm->variables(), nullptr);
ASSERT_EQ(vm->lists(), nullptr);

Script script2(&m_target, &m_engine);

vm = script2.start();
ASSERT_TRUE(vm);
ASSERT_EQ(vm->target(), &m_target);
ASSERT_EQ(vm->engine(), &m_engine);

Script script3(&m_target, &m_engine);
script3.setBytecode(bytecode);
script3.setProcedures(procedures);
script3.setFunctions(functions);
script3.setConstValues(constValues);
script3.setVariables(variables);
script3.setLists(lists);

vm = script3.start();
ASSERT_TRUE(vm);
ASSERT_EQ(vm->bytecode()[0], bytecode[0]);
ASSERT_EQ(vm->procedures()[0], procedures[0]);
ASSERT_EQ(vm->functions()[0], functions[0]);
ASSERT_EQ(vm->constValues()[0].toString(), constValues[0].toString());
ASSERT_EQ(vm->variables()[0], variables[0]);
ASSERT_EQ(vm->lists()[0], lists[0]);
}
45 changes: 44 additions & 1 deletion test/virtual_machine/virtual_machine_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ TEST(VirtualMachineTest, Constructors)
ASSERT_EQ(vm2.script(), &script);
}

TEST(VirtualMachineTest, Procedures)
{
static unsigned int procedure[] = { OP_START, OP_HALT };
static unsigned int *procedures[] = { procedure };

VirtualMachine vm;
ASSERT_EQ(vm.procedures(), nullptr);
vm.setProcedures(procedures);
ASSERT_EQ(vm.procedures(), procedures);
}

TEST(VirtualMachineTest, ConstValues)
{
static Value constValues[] = { "test1", "test2" };
Expand All @@ -35,6 +46,28 @@ TEST(VirtualMachineTest, ConstValues)
ASSERT_EQ(vm.constValues(), constValues);
}

TEST(VirtualMachineTest, Variables)
{
Value var;
Value *variables[] = { &var };

VirtualMachine vm;
ASSERT_EQ(vm.variables(), nullptr);
vm.setVariables(variables);
ASSERT_EQ(vm.variables(), variables);
}

TEST(VirtualMachineTest, Lists)
{
List list("", "");
List *lists[] = { &list };

VirtualMachine vm;
ASSERT_EQ(vm.lists(), nullptr);
vm.setLists(lists);
ASSERT_EQ(vm.lists(), lists);
}

TEST(VirtualMachineTest, Bytecode)
{
static unsigned int bytecode[] = { OP_START, OP_HALT };
Expand Down Expand Up @@ -1240,7 +1273,17 @@ TEST(VirtualMachineTest, OP_EXEC)
}
}

TEST(VirtualMachineTest, Procedures)
TEST(VirtualMachineTest, Functions)
{
static BlockFunc functions[] = { &testFunction1, &testFunction2 };

VirtualMachine vm;
ASSERT_EQ(vm.functions(), nullptr);
vm.setFunctions(functions);
ASSERT_EQ(vm.functions(), functions);
}

TEST(VirtualMachineTest, RunProcedures)
{
static unsigned int bytecode[] = {
OP_START, OP_INIT_PROCEDURE, OP_CONST, 0, OP_ADD_ARG, OP_CONST, 1, OP_ADD_ARG, OP_CALL_PROCEDURE, 0, OP_NULL, OP_EXEC, 0, OP_INIT_PROCEDURE, OP_CALL_PROCEDURE, 1, OP_HALT
Expand Down