Skip to content

Commit 06f551e

Browse files
committed
Compiler: Add custom if statement methods
1 parent 6ad13ee commit 06f551e

File tree

4 files changed

+64
-2
lines changed

4 files changed

+64
-2
lines changed

include/scratchcpp/dev/compiler.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ class LIBSCRATCHCPP_EXPORT Compiler
8080

8181
void createVariableWrite(Variable *variable);
8282

83+
void beginIfStatement();
84+
void beginElseBranch();
85+
void endIf();
86+
8387
void moveToIf(std::shared_ptr<Block> substack);
8488
void moveToIfElse(std::shared_ptr<Block> substack1, std::shared_ptr<Block> substack2);
8589
void moveToRepeatLoop(std::shared_ptr<Block> substack);

src/dev/engine/compiler.cpp

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,15 @@ std::shared_ptr<ExecutableCode> Compiler::compile(std::shared_ptr<Block> startBl
4545
impl->block = startBlock;
4646

4747
while (impl->block) {
48-
if (impl->block->compileFunction())
48+
if (impl->block->compileFunction()) {
49+
assert(impl->customIfStatementCount == 0);
4950
impl->block->compile(this);
50-
else {
51+
52+
if (impl->customIfStatementCount > 0) {
53+
std::cerr << "error: if statement created by block '" << impl->block->opcode() << "' not terminated" << std::endl;
54+
assert(false);
55+
}
56+
} else {
5157
std::cout << "warning: unsupported block: " << impl->block->opcode() << std::endl;
5258
impl->unsupportedBlocks.insert(impl->block->opcode());
5359
}
@@ -262,6 +268,35 @@ void Compiler::createVariableWrite(Variable *variable)
262268
impl->builder->createVariableWrite(variable);
263269
}
264270

271+
/*!
272+
* Starts a custom if statement.
273+
* \note The if statement must be terminated using endIf() after compiling your block.
274+
*/
275+
void Compiler::beginIfStatement()
276+
{
277+
impl->builder->beginIfStatement();
278+
impl->customIfStatementCount++;
279+
}
280+
281+
/*! Starts the else branch of custom if statement. */
282+
void Compiler::beginElseBranch()
283+
{
284+
impl->builder->beginElseBranch();
285+
}
286+
287+
/*! Ends custom if statement. */
288+
void Compiler::endIf()
289+
{
290+
if (impl->customIfStatementCount == 0) {
291+
std::cerr << "error: called Compiler::endIf() without an if statement";
292+
assert(false);
293+
return;
294+
}
295+
296+
impl->builder->endIf();
297+
impl->customIfStatementCount--;
298+
}
299+
265300
/*! Jumps to the given if substack. */
266301
void Compiler::moveToIf(std::shared_ptr<Block> substack)
267302
{

src/dev/engine/compiler_p.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ struct CompilerPrivate
3131
Target *target = nullptr;
3232

3333
std::shared_ptr<Block> block;
34+
int customIfStatementCount = 0;
3435
std::vector<std::pair<std::pair<std::shared_ptr<Block>, std::shared_ptr<Block>>, SubstackType>> substackTree;
3536
bool substackHit = false;
3637
bool warp = false;

test/dev/compiler/compiler_test.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,28 @@ TEST_F(CompilerTest, CreateVariableWrite)
571571
compile(compiler, block);
572572
}
573573

574+
TEST_F(CompilerTest, CustomIfStatement)
575+
{
576+
Compiler compiler(&m_engine, &m_target);
577+
auto block = std::make_shared<Block>("", "");
578+
579+
block->setCompileFunction([](Compiler *compiler) {
580+
EXPECT_CALL(*m_builder, beginIfStatement());
581+
compiler->beginIfStatement();
582+
EXPECT_CALL(*m_builder, endIf());
583+
compiler->endIf();
584+
585+
EXPECT_CALL(*m_builder, beginIfStatement());
586+
compiler->beginIfStatement();
587+
EXPECT_CALL(*m_builder, beginElseBranch());
588+
compiler->beginElseBranch();
589+
EXPECT_CALL(*m_builder, endIf());
590+
compiler->endIf();
591+
});
592+
593+
compile(compiler, block);
594+
}
595+
574596
TEST_F(CompilerTest, MoveToIf)
575597
{
576598
Compiler compiler(&m_engine, &m_target);

0 commit comments

Comments
 (0)