Skip to content

Commit 7d86ce2

Browse files
committed
Add API for unsupported blocks to Compiler
1 parent a62a07c commit 7d86ce2

File tree

4 files changed

+49
-1
lines changed

4 files changed

+49
-1
lines changed

include/scratchcpp/compiler.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include <vector>
66
#include <memory>
7+
#include <unordered_set>
78

89
#include "global.h"
910
#include "spimpl.h"
@@ -82,6 +83,8 @@ class LIBSCRATCHCPP_EXPORT Compiler
8283
BlockPrototype *procedurePrototype() const;
8384
void setProcedurePrototype(BlockPrototype *prototype);
8485

86+
const std::unordered_set<std::string> &unsupportedBlocks() const;
87+
8588
private:
8689
spimpl::unique_impl_ptr<CompilerPrivate> impl;
8790
};

src/engine/compiler.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,10 @@ void Compiler::compile(std::shared_ptr<Block> topLevelBlock)
6666

6767
if (impl->block->compileFunction())
6868
impl->block->compile(this);
69-
else
69+
else {
7070
std::cout << "warning: unsupported block: " << impl->block->opcode() << std::endl;
71+
impl->unsupportedBlocks.insert(impl->block->opcode());
72+
}
7173

7274
if (substacks != impl->substackTree.size())
7375
continue;
@@ -186,6 +188,7 @@ void Compiler::addInput(Input *input)
186188
impl->block->compile(this);
187189
else {
188190
std::cout << "warning: unsupported reporter block: " << impl->block->opcode() << std::endl;
191+
impl->unsupportedBlocks.insert(impl->block->opcode());
189192
addInstruction(OP_NULL);
190193
}
191194
} else
@@ -205,6 +208,7 @@ void Compiler::addInput(Input *input)
205208
impl->block->compile(this);
206209
else {
207210
std::cout << "warning: unsupported reporter block: " << impl->block->opcode() << std::endl;
211+
impl->unsupportedBlocks.insert(impl->block->opcode());
208212
addInstruction(OP_NULL);
209213
}
210214
} else
@@ -356,6 +360,12 @@ void Compiler::setProcedurePrototype(BlockPrototype *prototype)
356360
impl->procedurePrototype = prototype;
357361
}
358362

363+
/*! Returns unsupported block opcodes which were found when compiling. */
364+
const std::unordered_set<std::string> &libscratchcpp::Compiler::unsupportedBlocks() const
365+
{
366+
return impl->unsupportedBlocks;
367+
}
368+
359369
/*! Returns the list of custom block prototypes. */
360370
const std::vector<std::string> &Compiler::procedures() const
361371
{

src/engine/compiler_p.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#pragma once
44

55
#include <unordered_map>
6+
#include <unordered_set>
67
#include <scratchcpp/compiler.h>
78
#include <scratchcpp/inputvalue.h>
89

@@ -38,6 +39,8 @@ struct CompilerPrivate
3839
std::unordered_map<std::string, std::vector<std::string>> procedureArgs;
3940
BlockPrototype *procedurePrototype = nullptr;
4041
bool warp = false;
42+
43+
std::unordered_set<std::string> unsupportedBlocks;
4144
};
4245

4346
} // namespace libscratchcpp

test/compiler/compiler_test.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ TEST_F(CompilerTest, AddObscuredInput)
300300

301301
compiler.addInstruction(vm::OP_HALT);
302302
ASSERT_EQ(compiler.bytecode(), std::vector<unsigned int>({ vm::OP_START, vm::OP_CHECKPOINT, vm::OP_NULL, vm::OP_PRINT, vm::OP_CONST, 0, vm::OP_PRINT, vm::OP_NULL, vm::OP_PRINT, vm::OP_HALT }));
303+
ASSERT_EQ(compiler.unsupportedBlocks(), std::unordered_set<std::string>({ "test_block2" }));
303304
}
304305

305306
TEST_F(CompilerTest, AddNoShadowInput)
@@ -328,6 +329,14 @@ TEST_F(CompilerTest, AddNoShadowInput)
328329
ASSERT_EQ(compiler.bytecode(), std::vector<unsigned int>({ vm::OP_START, vm::OP_CHECKPOINT, vm::OP_NULL, vm::OP_PRINT, vm::OP_CONST, 0, vm::OP_NULL, vm::OP_PRINT, vm::OP_HALT }));
329330
ASSERT_EQ(compiler.constValues().size(), 1);
330331
ASSERT_EQ(compiler.constValues()[0], "test");
332+
ASSERT_EQ(compiler.unsupportedBlocks(), std::unordered_set<std::string>({ "test_block2" }));
333+
334+
Input input4("TEST_INPUT4", Input::Type::NoShadow);
335+
std::shared_ptr<Block> block3 = std::make_shared<Block>("", "test_block3");
336+
input4.setValueBlock(block3);
337+
compiler.addInput(&input4);
338+
compiler.addInstruction(vm::OP_PRINT);
339+
ASSERT_EQ(compiler.unsupportedBlocks(), std::unordered_set<std::string>({ "test_block2", "test_block3" }));
331340
}
332341

333342
TEST_F(CompilerTest, ResolveInput)
@@ -841,3 +850,26 @@ TEST_F(CompilerTest, EdgeActivatedHatPredicate)
841850
ASSERT_EQ(compiler.bytecode(), std::vector<unsigned int>({ vm::OP_START, vm::OP_CONST, 1, vm::OP_PRINT, vm::OP_HALT }));
842851
ASSERT_EQ(compiler.constValues(), std::vector<Value>({ true, "test" }));
843852
}
853+
854+
TEST_F(CompilerTest, UnsupportedBlocks)
855+
{
856+
auto block1 = std::make_shared<Block>("b1", "block1");
857+
858+
auto block2 = std::make_shared<Block>("b2", "block2");
859+
block2->setParent(block1);
860+
block1->setNext(block2);
861+
862+
auto block3 = std::make_shared<Block>("b3", "block3");
863+
block3->setCompileFunction([](Compiler *) {});
864+
block3->setParent(block2);
865+
block2->setNext(block3);
866+
867+
auto block4 = std::make_shared<Block>("b4", "block4");
868+
block4->setParent(block3);
869+
block3->setNext(block4);
870+
871+
INIT_COMPILER(engine, compiler);
872+
compiler.compile(block1);
873+
874+
ASSERT_EQ(compiler.unsupportedBlocks(), std::unordered_set<std::string>({ "block1", "block2", "block4" }));
875+
}

0 commit comments

Comments
 (0)