Skip to content

Commit 676cc83

Browse files
committed
Implement operator_letter_of
1 parent f66699f commit 676cc83

File tree

3 files changed

+72
-0
lines changed

3 files changed

+72
-0
lines changed

src/dev/blocks/operatorblocks.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <scratchcpp/iengine.h>
44
#include <scratchcpp/dev/compiler.h>
55
#include <scratchcpp/dev/compilervalue.h>
6+
#include <utf8.h>
67

78
#include "operatorblocks.h"
89

@@ -32,6 +33,7 @@ void OperatorBlocks::registerBlocks(IEngine *engine)
3233
engine->addCompileFunction(this, "operator_or", &compileOr);
3334
engine->addCompileFunction(this, "operator_not", &compileNot);
3435
engine->addCompileFunction(this, "operator_join", &compileJoin);
36+
engine->addCompileFunction(this, "operator_letter_of", &compileLetterOf);
3537
}
3638

3739
CompilerValue *OperatorBlocks::compileAdd(Compiler *compiler)
@@ -98,6 +100,13 @@ CompilerValue *OperatorBlocks::compileJoin(Compiler *compiler)
98100
return compiler->addFunctionCall("operator_join", Compiler::StaticType::String, { Compiler::StaticType::String, Compiler::StaticType::String }, { string1, string2 });
99101
}
100102

103+
CompilerValue *OperatorBlocks::compileLetterOf(Compiler *compiler)
104+
{
105+
auto letter = compiler->addInput("LETTER");
106+
auto string = compiler->addInput("STRING");
107+
return compiler->addFunctionCall("operator_letter_of", Compiler::StaticType::String, { Compiler::StaticType::Number, Compiler::StaticType::String }, { letter, string });
108+
}
109+
101110
extern "C" char *operator_join(const char *string1, const char *string2)
102111
{
103112
const size_t len1 = strlen(string1);
@@ -114,3 +123,22 @@ extern "C" char *operator_join(const char *string1, const char *string2)
114123

115124
return ret;
116125
}
126+
127+
extern "C" char *operator_letter_of(double letter, const char *string)
128+
{
129+
const size_t len = strlen(string);
130+
131+
if (letter < 1 || letter > len) {
132+
char *ret = (char *)malloc(sizeof(char));
133+
ret[0] = '\0';
134+
return ret;
135+
}
136+
137+
// TODO: Rewrite this
138+
std::u16string u16 = utf8::utf8to16(std::string(string));
139+
std::string str = utf8::utf16to8(std::u16string({ u16[(size_t)letter - 1] }));
140+
char *ret = (char *)malloc((str.size() + 1) * sizeof(char));
141+
strcpy(ret, str.c_str());
142+
143+
return ret;
144+
}

src/dev/blocks/operatorblocks.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class OperatorBlocks : public IExtension
3030
static CompilerValue *compileOr(Compiler *compiler);
3131
static CompilerValue *compileNot(Compiler *compiler);
3232
static CompilerValue *compileJoin(Compiler *compiler);
33+
static CompilerValue *compileLetterOf(Compiler *compiler);
3334
};
3435

3536
} // namespace libscratchcpp

test/dev/blocks/operator_blocks_test.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,3 +378,46 @@ TEST_F(OperatorBlocksTest, Join)
378378
ASSERT_EQ(Value(values[0]), "abcdef");
379379
ASSERT_EQ(Value(values[1]), "Hello world");
380380
}
381+
382+
TEST_F(OperatorBlocksTest, LetterOf)
383+
{
384+
auto target = std::make_shared<Sprite>();
385+
ScriptBuilder builder(m_extension.get(), m_engine, target);
386+
387+
builder.addBlock("operator_letter_of");
388+
builder.addValueInput("LETTER", 2);
389+
builder.addValueInput("STRING", "abc");
390+
builder.captureBlockReturnValue();
391+
392+
builder.addBlock("operator_letter_of");
393+
builder.addValueInput("LETTER", 7);
394+
builder.addValueInput("STRING", "Hello world");
395+
builder.captureBlockReturnValue();
396+
397+
builder.addBlock("operator_letter_of");
398+
builder.addValueInput("LETTER", 0);
399+
builder.addValueInput("STRING", "Hello world");
400+
builder.captureBlockReturnValue();
401+
402+
builder.addBlock("operator_letter_of");
403+
builder.addValueInput("LETTER", 12);
404+
builder.addValueInput("STRING", "Hello world");
405+
builder.captureBlockReturnValue();
406+
407+
builder.addBlock("operator_letter_of");
408+
builder.addValueInput("LETTER", 1);
409+
builder.addValueInput("STRING", "Ábč");
410+
builder.captureBlockReturnValue();
411+
412+
builder.build();
413+
builder.run();
414+
415+
List *valueList = builder.capturedValues();
416+
ValueData *values = valueList->data();
417+
ASSERT_EQ(valueList->size(), 5);
418+
ASSERT_EQ(Value(values[0]), "b");
419+
ASSERT_EQ(Value(values[1]), "w");
420+
ASSERT_EQ(Value(values[2]), "");
421+
ASSERT_EQ(Value(values[3]), "");
422+
ASSERT_EQ(Value(values[4]), "Á");
423+
}

0 commit comments

Comments
 (0)