Skip to content

Commit e97b27c

Browse files
committed
Compiler: Implement repeat loop
1 parent 24333c7 commit e97b27c

File tree

4 files changed

+84
-5
lines changed

4 files changed

+84
-5
lines changed

include/scratchcpp/dev/compiler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class LIBSCRATCHCPP_EXPORT Compiler
4040

4141
void moveToIf(std::shared_ptr<Block> substack);
4242
void moveToIfElse(std::shared_ptr<Block> substack1, std::shared_ptr<Block> substack2);
43-
void moveToLoop(std::shared_ptr<Block> substack);
43+
void moveToRepeatLoop(std::shared_ptr<Block> substack);
4444
void warp();
4545

4646
Input *input(const std::string &name) const;

src/dev/engine/compiler.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,13 @@ void Compiler::moveToIfElse(std::shared_ptr<Block> substack1, std::shared_ptr<Bl
129129
impl->substackEnd();
130130
}
131131

132-
/*! Jumps to the given loop substack. */
133-
void Compiler::moveToLoop(std::shared_ptr<Block> substack)
132+
/*! Jumps to the given repeat loop substack. */
133+
void Compiler::moveToRepeatLoop(std::shared_ptr<Block> substack)
134134
{
135135
impl->substackHit = true;
136136
impl->substackTree.push_back({ { impl->block, nullptr }, CompilerPrivate::SubstackType::Loop });
137137
impl->block = substack;
138+
impl->builder->beginRepeatLoop();
138139

139140
if (!impl->block)
140141
impl->substackEnd();

src/dev/engine/compiler_p.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ void CompilerPrivate::substackEnd()
2424
switch (parent.second) {
2525
case SubstackType::Loop:
2626
// Yield at loop end if not running without screen refresh
27-
if (!warp)
28-
builder->yield();
27+
/*if (!warp)
28+
builder->yield();*/
2929

3030
builder->endLoop();
3131
break;

test/dev/compiler/compiler_test.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,84 @@ TEST_F(CompilerTest, MoveToIfElse)
401401
compile(compiler, if1);
402402
}
403403

404+
TEST_F(CompilerTest, MoveToRepeatLoop)
405+
{
406+
Compiler compiler(&m_engine, &m_target);
407+
408+
auto l1 = std::make_shared<Block>("", "loop");
409+
l1->setCompileFunction([](Compiler *compiler) {
410+
EXPECT_CALL(*m_builder, beginRepeatLoop());
411+
EXPECT_CALL(*m_builder, endLoop());
412+
compiler->moveToRepeatLoop(nullptr);
413+
});
414+
415+
auto l2 = std::make_shared<Block>("", "loop");
416+
l1->setNext(l2);
417+
l2->setParent(l1);
418+
l2->setCompileFunction([](Compiler *compiler) {
419+
EXPECT_CALL(*m_builder, beginRepeatLoop());
420+
EXPECT_CALL(*m_builder, addConstValue(Value(2)));
421+
EXPECT_CALL(*m_builder, endLoop());
422+
compiler->moveToRepeatLoop(compiler->input("SUBSTACK")->valueBlock());
423+
});
424+
425+
auto substack = std::make_shared<Block>("", "substack");
426+
substack->setParent(l2);
427+
substack->setCompileFunction([](Compiler *compiler) { compiler->addConstValue(2); });
428+
429+
auto input = std::make_shared<Input>("SUBSTACK", Input::Type::NoShadow);
430+
input->setValueBlock(substack);
431+
l2->addInput(input);
432+
433+
// Nested
434+
auto l3 = std::make_shared<Block>("", "loop");
435+
l2->setNext(l3);
436+
l3->setParent(l2);
437+
l3->setCompileFunction([](Compiler *compiler) {
438+
EXPECT_CALL(*m_builder, beginRepeatLoop()).Times(2);
439+
EXPECT_CALL(*m_builder, endLoop()).Times(2);
440+
EXPECT_CALL(*m_builder, addConstValue(Value(1)));
441+
compiler->moveToRepeatLoop(compiler->input("SUBSTACK")->valueBlock());
442+
});
443+
444+
// Begin loop
445+
auto loopSubstack = std::make_shared<Block>("", "loop");
446+
loopSubstack->setParent(l3);
447+
loopSubstack->setCompileFunction([](Compiler *compiler) { compiler->moveToRepeatLoop(compiler->input("SUBSTACK")->valueBlock()); });
448+
449+
substack = std::make_shared<Block>("", "substack");
450+
substack->setParent(loopSubstack);
451+
substack->setCompileFunction([](Compiler *compiler) { compiler->addConstValue(1); });
452+
453+
input = std::make_shared<Input>("SUBSTACK", Input::Type::NoShadow);
454+
input->setValueBlock(substack);
455+
loopSubstack->addInput(input);
456+
457+
// End loop
458+
input = std::make_shared<Input>("SUBSTACK", Input::Type::NoShadow);
459+
input->setValueBlock(loopSubstack);
460+
l3->addInput(input);
461+
462+
// Empty loop body
463+
auto l4 = std::make_shared<Block>("", "loop");
464+
l3->setNext(l4);
465+
l4->setParent(l3);
466+
l4->setCompileFunction([](Compiler *compiler) {
467+
EXPECT_CALL(*m_builder, beginRepeatLoop());
468+
EXPECT_CALL(*m_builder, endLoop());
469+
compiler->moveToRepeatLoop(nullptr);
470+
});
471+
472+
// Code after the loop
473+
auto block = std::make_shared<Block>("", "");
474+
block->setParent(l4);
475+
l4->setNext(block);
476+
block->setCompileFunction([](Compiler *compiler) { compiler->addConstValue("after"); });
477+
478+
EXPECT_CALL(*m_builder, addConstValue(Value("after")));
479+
compile(compiler, l1);
480+
}
481+
404482
TEST_F(CompilerTest, Input)
405483
{
406484
Compiler compiler(&m_engine, &m_target);

0 commit comments

Comments
 (0)