@@ -39,6 +39,8 @@ std::shared_ptr<libscratchcpp::Block> Compiler::block() const
3939std::shared_ptr<ExecutableCode> Compiler::compile (std::shared_ptr<Block> startBlock)
4040{
4141 impl->builder = impl->builderFactory ->create (startBlock->id ());
42+ impl->substackTree .clear ();
43+ impl->substackHit = false ;
4244 impl->warp = false ;
4345 impl->block = startBlock;
4446
@@ -52,10 +54,13 @@ std::shared_ptr<ExecutableCode> Compiler::compile(std::shared_ptr<Block> startBl
5254 impl->unsupportedBlocks .insert (impl->block ->opcode ());
5355 }
5456
55- if (substacks != impl->substackTree .size ())
57+ if (impl->substackHit ) {
58+ impl->substackHit = false ;
5659 continue ;
60+ }
5761
58- impl->block = impl->block ->next ();
62+ if (impl->block )
63+ impl->block = impl->block ->next ();
5964
6065 if (!impl->block && !impl->substackTree .empty ())
6166 impl->substackEnd ();
@@ -100,39 +105,84 @@ void Compiler::addInput(const std::string &name)
100105/* ! Jumps to the given if substack. */
101106void Compiler::moveToIf (std::shared_ptr<Block> substack)
102107{
108+ if (!substack)
109+ return ; // ignore empty if statements
110+
111+ impl->substackHit = true ;
103112 impl->substackTree .push_back ({ { impl->block , nullptr }, CompilerPrivate::SubstackType::IfStatement });
104113 impl->block = substack;
105-
106- if (!impl->block )
107- impl->substackEnd ();
114+ impl->builder ->beginIfStatement ();
108115}
109116
110117/* ! Jumps to the given if/else substack. The second substack is used for the else branch. */
111118void Compiler::moveToIfElse (std::shared_ptr<Block> substack1, std::shared_ptr<Block> substack2)
112119{
120+ if (!substack1 && !substack2)
121+ return ; // ignore empty if statements
122+
123+ impl->substackHit = true ;
113124 impl->substackTree .push_back ({ { impl->block , substack2 }, CompilerPrivate::SubstackType::IfStatement });
114125 impl->block = substack1;
126+ impl->builder ->beginIfStatement ();
115127
116128 if (!impl->block )
117129 impl->substackEnd ();
118130}
119131
120- /* ! Jumps to the given loop substack. */
121- 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)
122134{
135+ impl->substackHit = true ;
123136 impl->substackTree .push_back ({ { impl->block , nullptr }, CompilerPrivate::SubstackType::Loop });
124137 impl->block = substack;
138+ impl->builder ->beginRepeatLoop ();
125139
126140 if (!impl->block )
127141 impl->substackEnd ();
128142}
129143
144+ /* ! Jumps to the given while loop substack. */
145+ void Compiler::moveToWhileLoop (std::shared_ptr<Block> substack)
146+ {
147+ impl->substackHit = true ;
148+ impl->substackTree .push_back ({ { impl->block , nullptr }, CompilerPrivate::SubstackType::Loop });
149+ impl->block = substack;
150+ impl->builder ->beginWhileLoop ();
151+
152+ if (!impl->block )
153+ impl->substackEnd ();
154+ }
155+
156+ /* ! Jumps to the given until loop substack. */
157+ void Compiler::moveToRepeatUntilLoop (std::shared_ptr<Block> substack)
158+ {
159+ impl->substackHit = true ;
160+ impl->substackTree .push_back ({ { impl->block , nullptr }, CompilerPrivate::SubstackType::Loop });
161+ impl->block = substack;
162+ impl->builder ->beginRepeatUntilLoop ();
163+
164+ if (!impl->block )
165+ impl->substackEnd ();
166+ }
167+
168+ /* ! Begins a while/until loop condition. */
169+ void Compiler::beginLoopCondition ()
170+ {
171+ impl->builder ->beginLoopCondition ();
172+ }
173+
130174/* ! Makes current script run without screen refresh. */
131175void Compiler::warp ()
132176{
133177 impl->warp = true ;
134178}
135179
180+ /* ! Convenience method which returns the field with the given name. */
181+ Input *Compiler::input (const std::string &name) const
182+ {
183+ return impl->block ->inputAt (impl->block ->findInput (name)).get ();
184+ }
185+
136186/* ! Convenience method which returns the field with the given name. */
137187Field *Compiler::field (const std::string &name) const
138188{
0 commit comments