Skip to content

Commit 6f43234

Browse files
committed
Add support for compiling function calls
1 parent e3ad40f commit 6f43234

File tree

4 files changed

+23
-0
lines changed

4 files changed

+23
-0
lines changed

src/engine/compiler.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "compiler.h"
44
#include "engine.h"
5+
#include <cassert>
56

67
using namespace libscratchcpp;
78
using namespace vm;
@@ -11,6 +12,8 @@ Compiler::Compiler(Engine *engine, std::shared_ptr<Block> topLevelBlock) :
1112
m_engine(engine),
1213
m_block(topLevelBlock)
1314
{
15+
assert(engine);
16+
assert(topLevelBlock);
1417
}
1518

1619
/*! Compiles the script. Use bytecode() to read the generated bytecode. */
@@ -118,6 +121,12 @@ void Compiler::addInput(Input *input)
118121
}
119122
}
120123

124+
/*! Adds a function call to the bytecode (the OP_EXEC instruction). */
125+
void Compiler::addFunctionCall(BlockFunc f)
126+
{
127+
addInstruction(OP_EXEC, { m_engine->functionIndex(f) });
128+
}
129+
121130
/*! Returns the input with the given ID. */
122131
Input *Compiler::input(int id) const
123132
{

src/engine/compiler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class LIBSCRATCHCPP_EXPORT Compiler
3232

3333
void addInstruction(vm::Opcode opcode, std::initializer_list<unsigned int> args = {});
3434
void addInput(Input *input);
35+
void addFunctionCall(BlockFunc f);
3536

3637
Input *input(int id) const;
3738
Field *field(int id) const;

src/engine/engine.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,16 @@ BlockImpl Engine::resolveBlock(const std::string &opcode) const
307307
return nullptr;
308308
}
309309

310+
/*! Returns the index of the given block function. */
311+
unsigned int Engine::functionIndex(BlockFunc f)
312+
{
313+
auto it = std::find(m_functions.begin(), m_functions.end(), f);
314+
if (it != m_functions.end())
315+
return it - m_functions.begin();
316+
m_functions.push_back(f);
317+
return m_functions.size() - 1;
318+
}
319+
310320
/*! Resolves the block and returns the block section in which it has been registered. */
311321
std::shared_ptr<IBlockSection> Engine::blockSection(const std::string &opcode) const
312322
{

src/engine/engine.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class LIBSCRATCHCPP_EXPORT Engine
4545

4646
void registerSection(std::shared_ptr<IBlockSection> section);
4747
BlockImpl resolveBlock(const std::string &opcode) const;
48+
unsigned int functionIndex(BlockFunc f);
4849
std::shared_ptr<IBlockSection> blockSection(const std::string &opcode) const;
4950

5051
std::vector<std::shared_ptr<Broadcast>> broadcasts() const;
@@ -71,6 +72,8 @@ class LIBSCRATCHCPP_EXPORT Engine
7172
std::vector<std::string> m_extensions;
7273
std::vector<std::shared_ptr<RunningScript>> m_runningScripts;
7374
std::unordered_map<std::shared_ptr<Block>, std::shared_ptr<VirtualMachine>> m_scripts;
75+
std::vector<BlockFunc> m_functions;
76+
7477
bool m_breakFrame = false;
7578
bool m_stayOnCurrentBlock = false;
7679
bool m_atomic = true;

0 commit comments

Comments
 (0)