Skip to content

Commit ae7ca5b

Browse files
committed
Implement data_insertatlist
1 parent b976f53 commit ae7ca5b

File tree

3 files changed

+88
-7
lines changed

3 files changed

+88
-7
lines changed

src/dev/blocks/listblocks.cpp

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ void ListBlocks::registerBlocks(IEngine *engine)
2525
engine->addCompileFunction(this, "data_addtolist", &compileAddToList);
2626
engine->addCompileFunction(this, "data_deleteoflist", &compileDeleteOfList);
2727
engine->addCompileFunction(this, "data_deletealloflist", &compileDeleteAllOfList);
28+
engine->addCompileFunction(this, "data_insertatlist", &compileInsertAtList);
2829
}
2930

3031
CompilerValue *ListBlocks::compileAddToList(Compiler *compiler)
@@ -38,24 +39,23 @@ CompilerValue *ListBlocks::compileAddToList(Compiler *compiler)
3839
return nullptr;
3940
}
4041

41-
CompilerValue *ListBlocks::getListIndex(Compiler *compiler, CompilerValue *input, List *list)
42+
CompilerValue *ListBlocks::getListIndex(Compiler *compiler, CompilerValue *input, List *list, CompilerValue *listSize)
4243
{
4344
CompilerLocalVariable *ret = compiler->createLocalVariable(Compiler::StaticType::Number);
44-
CompilerValue *size = compiler->addListSize(list);
4545

4646
CompilerValue *isRandom1 = compiler->createCmpEQ(input, compiler->addConstValue("random"));
4747
CompilerValue *isRandom2 = compiler->createCmpEQ(input, compiler->addConstValue("any"));
4848
CompilerValue *isRandom = compiler->createOr(isRandom1, isRandom2);
4949

5050
compiler->beginIfStatement(isRandom);
5151
{
52-
CompilerValue *random = compiler->createRandomInt(compiler->addConstValue(1), size);
52+
CompilerValue *random = compiler->createRandomInt(compiler->addConstValue(1), listSize);
5353
compiler->createLocalVariableWrite(ret, random);
5454
}
5555
compiler->beginElseBranch();
5656
{
5757
CompilerValue *isLast = compiler->createCmpEQ(input, compiler->addConstValue("last"));
58-
compiler->createLocalVariableWrite(ret, compiler->createSelect(isLast, size, input, Compiler::StaticType::Number));
58+
compiler->createLocalVariableWrite(ret, compiler->createSelect(isLast, listSize, input, Compiler::StaticType::Number));
5959
}
6060
compiler->endIf();
6161

@@ -76,10 +76,10 @@ CompilerValue *ListBlocks::compileDeleteOfList(Compiler *compiler)
7676
}
7777
compiler->beginElseBranch();
7878
{
79-
index = getListIndex(compiler, index, list);
80-
index = compiler->createSub(index, compiler->addConstValue(1));
8179
CompilerValue *min = compiler->addConstValue(-1);
8280
CompilerValue *max = compiler->addListSize(list);
81+
index = getListIndex(compiler, index, list, max);
82+
index = compiler->createSub(index, compiler->addConstValue(1));
8383
cond = compiler->createAnd(compiler->createCmpGT(index, min), compiler->createCmpLT(index, max));
8484
compiler->beginIfStatement(cond);
8585
{
@@ -103,3 +103,26 @@ CompilerValue *ListBlocks::compileDeleteAllOfList(Compiler *compiler)
103103

104104
return nullptr;
105105
}
106+
107+
CompilerValue *ListBlocks::compileInsertAtList(Compiler *compiler)
108+
{
109+
List *list = static_cast<List *>(compiler->field("LIST")->valuePtr().get());
110+
assert(list);
111+
112+
if (list) {
113+
CompilerValue *index = compiler->addInput("INDEX");
114+
CompilerValue *min = compiler->addConstValue(-1);
115+
CompilerValue *max = compiler->createAdd(compiler->addListSize(list), compiler->addConstValue(1));
116+
index = getListIndex(compiler, index, list, max);
117+
index = compiler->createSub(index, compiler->addConstValue(1));
118+
CompilerValue *cond = compiler->createAnd(compiler->createCmpGT(index, min), compiler->createCmpLT(index, max));
119+
compiler->beginIfStatement(cond);
120+
{
121+
CompilerValue *item = compiler->addInput("ITEM");
122+
compiler->createListInsert(list, index, item);
123+
}
124+
compiler->endIf();
125+
}
126+
127+
return nullptr;
128+
}

src/dev/blocks/listblocks.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ class ListBlocks : public IExtension
1919

2020
private:
2121
static CompilerValue *compileAddToList(Compiler *compiler);
22-
static CompilerValue *getListIndex(Compiler *compiler, CompilerValue *input, List *list);
22+
static CompilerValue *getListIndex(Compiler *compiler, CompilerValue *input, List *list, CompilerValue *listSize);
2323
static CompilerValue *compileDeleteOfList(Compiler *compiler);
2424
static CompilerValue *compileDeleteAllOfList(Compiler *compiler);
25+
static CompilerValue *compileInsertAtList(Compiler *compiler);
2526
};
2627

2728
} // namespace libscratchcpp

test/dev/blocks/list_blocks_test.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,60 @@ TEST_F(ListBlocksTest, DeleteAllOfList)
154154
builder.run();
155155
ASSERT_TRUE(list->empty());
156156
}
157+
158+
TEST_F(ListBlocksTest, InsertAtList)
159+
{
160+
auto target = std::make_shared<Sprite>();
161+
162+
auto list1 = std::make_shared<List>("", "");
163+
list1->append("Lorem");
164+
list1->append("ipsum");
165+
list1->append("dolor");
166+
list1->append(123);
167+
list1->append(true);
168+
target->addList(list1);
169+
170+
auto list2 = std::make_shared<List>("", "");
171+
list2->append("Hello");
172+
list2->append("world");
173+
list2->append(false);
174+
list2->append(-543.5);
175+
list2->append("abc");
176+
list2->append(52.4);
177+
target->addList(list2);
178+
179+
ScriptBuilder builder(m_extension.get(), m_engine, target);
180+
181+
auto addTest = [&builder](const Value &item, const Value &index, std::shared_ptr<List> list) {
182+
builder.addBlock("data_insertatlist");
183+
builder.addValueInput("ITEM", item);
184+
builder.addValueInput("INDEX", index);
185+
builder.addEntityField("LIST", list);
186+
return builder.currentBlock();
187+
};
188+
189+
auto block = addTest("sit", 4, list1);
190+
addTest(false, 7, list1);
191+
addTest("test", 0, list1);
192+
addTest("test", 9, list1);
193+
194+
addTest("lorem", "last", list2);
195+
addTest("ipsum", "random", list2);
196+
addTest("dolor", "any", list2);
197+
198+
builder.build();
199+
200+
Compiler compiler(&m_engineMock, target.get());
201+
auto code = compiler.compile(block);
202+
Script script(target.get(), block, &m_engineMock);
203+
script.setCode(code);
204+
Thread thread(target.get(), &m_engineMock, &script);
205+
auto ctx = code->createExecutionContext(&thread);
206+
ctx->setRng(&m_rng);
207+
208+
EXPECT_CALL(m_rng, randint(1, 8)).WillOnce(Return(8));
209+
EXPECT_CALL(m_rng, randint(1, 9)).WillOnce(Return(3));
210+
code->run(ctx.get());
211+
ASSERT_EQ(list1->toString(), "Lorem ipsum dolor sit 123 true false");
212+
ASSERT_EQ(list2->toString(), "Hello world dolor false -543.5 abc 52.4 lorem ipsum");
213+
}

0 commit comments

Comments
 (0)