Skip to content

Commit 6b1a518

Browse files
committed
ControlBlocks: Add compile functions
1 parent 2b11882 commit 6b1a518

File tree

2 files changed

+115
-14
lines changed

2 files changed

+115
-14
lines changed

src/blocks/controlblocks.cpp

Lines changed: 105 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// SPDX-License-Identifier: Apache-2.0
22

33
#include "controlblocks.h"
4+
#include "../engine/compiler.h"
45

56
namespace libscratchcpp
67
{
@@ -10,12 +11,17 @@ std::map<std::pair<RunningScript *, Block *>, std::pair<int, int>> ControlBlocks
1011
ControlBlocks::ControlBlocks()
1112
{
1213
// Blocks
14+
addCompileFunction("control_forever", &ControlBlocks::compileRepeatForever);
15+
addCompileFunction("control_repeat", &ControlBlocks::compileRepeat);
16+
addCompileFunction("control_repeat_until", &ControlBlocks::compileRepeatUntil);
17+
addCompileFunction("control_if", &ControlBlocks::compileIfStatement);
18+
addCompileFunction("control_if_else", &ControlBlocks::compileIfElseStatement);
19+
addCompileFunction("control_stop", &ControlBlocks::compileStop);
1320
addBlock("control_forever", &ControlBlocks::repeatForever);
1421
addBlock("control_repeat", &ControlBlocks::repeat);
1522
addBlock("control_repeat_until", &ControlBlocks::repeatUntil);
1623
addBlock("control_if", &ControlBlocks::ifStatement);
1724
addBlock("control_if_else", &ControlBlocks::ifElseStatement);
18-
addBlock("control_stop", &ControlBlocks::stop);
1925

2026
// Inputs
2127
addInput("SUBSTACK", SUBSTACK);
@@ -37,6 +43,104 @@ std::string ControlBlocks::name() const
3743
return "Control";
3844
}
3945

46+
void ControlBlocks::compileRepeatForever(Compiler *compiler)
47+
{
48+
compiler->addInstruction(vm::OP_FOREVER_LOOP);
49+
compiler->moveToSubstack(compiler->inputBlock(SUBSTACK), Compiler::SubstackType::Loop);
50+
}
51+
52+
void ControlBlocks::compileRepeat(Compiler *compiler)
53+
{
54+
auto substack = compiler->inputBlock(SUBSTACK);
55+
if (substack) {
56+
compiler->addInput(TIMES);
57+
compiler->addInstruction(vm::OP_REPEAT_LOOP);
58+
compiler->moveToSubstack(substack, Compiler::SubstackType::Loop);
59+
}
60+
}
61+
62+
void ControlBlocks::compileRepeatUntil(Compiler *compiler)
63+
{
64+
auto substack = compiler->inputBlock(SUBSTACK);
65+
if (substack) {
66+
compiler->addInstruction(vm::OP_UNTIL_LOOP);
67+
compiler->addInput(CONDITION);
68+
compiler->addInstruction(vm::OP_BEGIN_UNTIL_LOOP);
69+
compiler->moveToSubstack(substack, Compiler::SubstackType::Loop);
70+
}
71+
}
72+
73+
void ControlBlocks::compileRepeatWhile(Compiler *compiler)
74+
{
75+
auto substack = compiler->inputBlock(SUBSTACK);
76+
if (substack) {
77+
compiler->addInstruction(vm::OP_UNTIL_LOOP);
78+
compiler->addInput(CONDITION);
79+
compiler->addInstruction(vm::OP_NOT);
80+
compiler->addInstruction(vm::OP_BEGIN_UNTIL_LOOP);
81+
compiler->moveToSubstack(substack, Compiler::SubstackType::Loop);
82+
}
83+
}
84+
85+
void ControlBlocks::compileIfStatement(Compiler *compiler)
86+
{
87+
auto substack = compiler->inputBlock(SUBSTACK);
88+
if (substack) {
89+
compiler->addInput(CONDITION);
90+
compiler->addInstruction(vm::OP_IF);
91+
compiler->moveToSubstack(substack, Compiler::SubstackType::IfStatement);
92+
}
93+
}
94+
95+
void ControlBlocks::compileIfElseStatement(Compiler *compiler)
96+
{
97+
auto substack1 = compiler->inputBlock(SUBSTACK);
98+
auto substack2 = compiler->inputBlock(SUBSTACK2);
99+
if (substack1 || substack2)
100+
compiler->addInput(CONDITION);
101+
if (substack1 && substack2) {
102+
compiler->addInstruction(vm::OP_IF);
103+
compiler->moveToSubstack(substack1, substack2, Compiler::SubstackType::IfStatement);
104+
} else if (substack1) {
105+
compiler->addInstruction(vm::OP_IF);
106+
compiler->moveToSubstack(substack1, Compiler::SubstackType::IfStatement);
107+
} else if (substack2) {
108+
compiler->addInstruction(vm::OP_NOT);
109+
compiler->addInstruction(vm::OP_IF);
110+
compiler->moveToSubstack(substack2, Compiler::SubstackType::IfStatement);
111+
}
112+
}
113+
114+
void ControlBlocks::compileStop(Compiler *compiler)
115+
{
116+
int option = compiler->field(STOP_OPTION)->specialValueId();
117+
switch (option) {
118+
case StopAll:
119+
compiler->addFunctionCall(&stopAll);
120+
break;
121+
122+
case StopThisScript:
123+
compiler->addInstruction(vm::OP_HALT);
124+
break;
125+
126+
case StopOtherScriptsInSprite:
127+
compiler->addFunctionCall(&stopOtherScriptsInSprite);
128+
break;
129+
}
130+
}
131+
132+
unsigned int ControlBlocks::stopAll(VirtualMachine *vm)
133+
{
134+
vm->engine()->stop();
135+
return 0;
136+
}
137+
138+
unsigned int ControlBlocks::stopOtherScriptsInSprite(VirtualMachine *vm)
139+
{
140+
vm->engine()->stopTarget(vm->target(), vm);
141+
return 0;
142+
}
143+
40144
Value ControlBlocks::repeatForever(const BlockArgs &args)
41145
{
42146
auto script = args.script();
@@ -138,16 +242,4 @@ Value ControlBlocks::ifElseStatement(const BlockArgs &args)
138242
}
139243
}
140244

141-
Value ControlBlocks::stop(const BlockArgs &args)
142-
{
143-
int option = args.field(STOP_OPTION)->specialValueId();
144-
if (option == StopAll)
145-
args.engine()->stop();
146-
else if (option == StopThisScript)
147-
args.engine()->stopScript(args.script());
148-
else if (option == StopOtherScriptsInSprite)
149-
args.engine()->stopTarget(args.target(), args.script());
150-
return Value();
151-
}
152-
153245
} // namespace libscratchcpp

src/blocks/controlblocks.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,22 @@ class LIBSCRATCHCPP_EXPORT ControlBlocks : public IBlockSection
3535

3636
std::string name() const override;
3737

38+
static void compileRepeatForever(Compiler *compiler);
39+
static void compileRepeat(Compiler *compiler);
40+
static void compileRepeatUntil(Compiler *compiler);
41+
static void compileRepeatWhile(Compiler *compiler);
42+
static void compileIfStatement(Compiler *compiler);
43+
static void compileIfElseStatement(Compiler *compiler);
44+
static void compileStop(Compiler *compiler);
45+
46+
static unsigned int stopAll(VirtualMachine *vm);
47+
static unsigned int stopOtherScriptsInSprite(VirtualMachine *vm);
3848
static Value repeatForever(const BlockArgs &args);
3949
static Value repeat(const BlockArgs &args);
4050
static Value repeatUntil(const BlockArgs &args);
4151
static Value repeatWhile(const BlockArgs &args);
4252
static Value ifStatement(const BlockArgs &args);
4353
static Value ifElseStatement(const BlockArgs &args);
44-
static Value stop(const BlockArgs &args);
4554

4655
private:
4756
// pair<script, C mouth>, pair<current index, repeat count>

0 commit comments

Comments
 (0)