Skip to content

Commit 96b5e83

Browse files
authored
Merge pull request #600 from scratchcpp/llvm_lists
LLVM: Implement lists
2 parents fedc9e5 + d071783 commit 96b5e83

31 files changed

+1707
-31
lines changed

include/scratchcpp/dev/compiler.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ class LIBSCRATCHCPP_EXPORT Compiler
4646
void addConstValue(const Value &value);
4747
void addVariableValue(Variable *variable);
4848
void addListContents(List *list);
49+
void addListItem(List *list);
50+
void addListItemIndex(List *list);
51+
void addListContains(List *list);
52+
void addListSize(List *list);
4953
void addInput(const std::string &name);
5054

5155
void createAdd();
@@ -80,6 +84,16 @@ class LIBSCRATCHCPP_EXPORT Compiler
8084

8185
void createVariableWrite(Variable *variable);
8286

87+
void createListClear(List *list);
88+
void createListRemove(List *list);
89+
void createListAppend(List *list);
90+
void createListInsert(List *list);
91+
void createListReplace(List *list);
92+
93+
void beginIfStatement();
94+
void beginElseBranch();
95+
void endIf();
96+
8397
void moveToIf(std::shared_ptr<Block> substack);
8498
void moveToIfElse(std::shared_ptr<Block> substack1, std::shared_ptr<Block> substack2);
8599
void moveToRepeatLoop(std::shared_ptr<Block> substack);

include/scratchcpp/list.h

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,21 @@ class LIBSCRATCHCPP_EXPORT List : public Entity
3737
Monitor *monitor() const;
3838
void setMonitor(Monitor *monitor);
3939

40+
/*! Returns a pointer to the raw list data. */
41+
inline ValueData *data() const { return m_dataPtr->data(); }
42+
43+
/*!
44+
* Returns a pointer to the list size.
45+
* \note This is used internally by compiled code for various optimizations.
46+
*/
47+
inline size_t *sizePtr() { return &m_size; }
48+
49+
/*!
50+
* Returns a pointer to the allocated list size.
51+
* \note This is used internally by compiled code for various optimizations.
52+
*/
53+
inline const size_t *allocatedSizePtr() const { return m_dataPtr->sizePtr(); }
54+
4055
/*! Returns the list size. */
4156
inline size_t size() const { return m_size; }
4257

@@ -96,16 +111,19 @@ class LIBSCRATCHCPP_EXPORT List : public Entity
96111
m_size--;
97112
}
98113

99-
/*! Inserts an item at index. */
100-
inline void insert(size_t index, const ValueData &value)
114+
/*! Inserts an empty item at index and returns the reference to it. Can be used for custom initialization. */
115+
inline ValueData &insertEmpty(size_t index)
101116
{
102117
assert(index >= 0 && index <= size());
103118
m_size++;
104119
reserve(getAllocSize(m_size));
105120
std::rotate(m_dataPtr->rbegin() + m_dataPtr->size() - m_size, m_dataPtr->rbegin() + m_dataPtr->size() - m_size + 1, m_dataPtr->rend() - index);
106-
value_assign_copy(&m_dataPtr->operator[](index), &value);
121+
return m_dataPtr->operator[](index);
107122
}
108123

124+
/*! Inserts an item at index. */
125+
inline void insert(size_t index, const ValueData &value) { value_assign_copy(&insertEmpty(index), &value); }
126+
109127
/*! Inserts an item at index. */
110128
inline void insert(size_t index, const Value &value) { insert(index, value.data()); }
111129

include/scratchcpp/target.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ class LIBSCRATCHCPP_EXPORT Target : public Drawable
5353
int findList(const std::string &listName) const;
5454
int findListById(const std::string &id) const;
5555

56+
List **listData();
57+
5658
const std::vector<std::shared_ptr<Block>> &blocks() const;
5759
int addBlock(std::shared_ptr<Block> block);
5860
std::shared_ptr<Block> blockAt(int index) const;

include/scratchcpp/veque.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,11 @@ namespace veque
375375
return _size;
376376
}
377377

378+
// For libscratchcpp List
379+
inline const size_type *sizePtr() const noexcept {
380+
return &_size;
381+
}
382+
378383
size_type max_size() const noexcept
379384
{
380385
constexpr auto compile_time_limit = std::min(

src/dev/engine/compiler.cpp

Lines changed: 94 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,15 @@ std::shared_ptr<ExecutableCode> Compiler::compile(std::shared_ptr<Block> startBl
4545
impl->block = startBlock;
4646

4747
while (impl->block) {
48-
if (impl->block->compileFunction())
48+
if (impl->block->compileFunction()) {
49+
assert(impl->customIfStatementCount == 0);
4950
impl->block->compile(this);
50-
else {
51+
52+
if (impl->customIfStatementCount > 0) {
53+
std::cerr << "error: if statement created by block '" << impl->block->opcode() << "' not terminated" << std::endl;
54+
assert(false);
55+
}
56+
} else {
5157
std::cout << "warning: unsupported block: " << impl->block->opcode() << std::endl;
5258
impl->unsupportedBlocks.insert(impl->block->opcode());
5359
}
@@ -94,6 +100,30 @@ void Compiler::addListContents(List *list)
94100
impl->builder->addListContents(list);
95101
}
96102

103+
/*! Adds the item with index from the last value of the given list to the code. */
104+
void Compiler::addListItem(List *list)
105+
{
106+
impl->builder->addListItem(list);
107+
}
108+
109+
/*! Adds the index of the item from the last value of the given list to the code. */
110+
void Compiler::addListItemIndex(List *list)
111+
{
112+
impl->builder->addListItemIndex(list);
113+
}
114+
115+
/*! Adds the result of a list contains item from the check to the code. */
116+
void Compiler::addListContains(List *list)
117+
{
118+
impl->builder->addListContains(list);
119+
}
120+
121+
/*! Adds the length of the given list to the code. */
122+
void Compiler::addListSize(List *list)
123+
{
124+
impl->builder->addListSize(list);
125+
}
126+
97127
/*! Compiles the given input (resolved by name) and adds it to the compiled code. */
98128
void Compiler::addInput(const std::string &name)
99129
{
@@ -262,6 +292,68 @@ void Compiler::createVariableWrite(Variable *variable)
262292
impl->builder->createVariableWrite(variable);
263293
}
264294

295+
/*! Creates a clear list operation. */
296+
void Compiler::createListClear(List *list)
297+
{
298+
impl->builder->createListClear(list);
299+
}
300+
301+
/*!
302+
* Creates a remove item from list operation.
303+
* \note The index starts with 0 and is cast to number, special strings like "last" are not handled.
304+
*/
305+
void Compiler::createListRemove(List *list)
306+
{
307+
impl->builder->createListRemove(list);
308+
}
309+
310+
/*! Creates a list append operation using the last value. */
311+
void Compiler::createListAppend(List *list)
312+
{
313+
impl->builder->createListAppend(list);
314+
}
315+
316+
/*! Creates a list insert operation using the last 2 values (index, value). */
317+
void Compiler::createListInsert(List *list)
318+
{
319+
impl->builder->createListInsert(list);
320+
}
321+
322+
/*! Creates a list replace operation using the last 2 values (index, value). */
323+
void Compiler::createListReplace(List *list)
324+
{
325+
impl->builder->createListReplace(list);
326+
}
327+
328+
/*!
329+
* Starts a custom if statement.
330+
* \note The if statement must be terminated using endIf() after compiling your block.
331+
*/
332+
void Compiler::beginIfStatement()
333+
{
334+
impl->builder->beginIfStatement();
335+
impl->customIfStatementCount++;
336+
}
337+
338+
/*! Starts the else branch of custom if statement. */
339+
void Compiler::beginElseBranch()
340+
{
341+
impl->builder->beginElseBranch();
342+
}
343+
344+
/*! Ends custom if statement. */
345+
void Compiler::endIf()
346+
{
347+
if (impl->customIfStatementCount == 0) {
348+
std::cerr << "error: called Compiler::endIf() without an if statement";
349+
assert(false);
350+
return;
351+
}
352+
353+
impl->builder->endIf();
354+
impl->customIfStatementCount--;
355+
}
356+
265357
/*! Jumps to the given if substack. */
266358
void Compiler::moveToIf(std::shared_ptr<Block> substack)
267359
{

src/dev/engine/compiler_p.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ struct CompilerPrivate
3131
Target *target = nullptr;
3232

3333
std::shared_ptr<Block> block;
34+
int customIfStatementCount = 0;
3435
std::vector<std::pair<std::pair<std::shared_ptr<Block>, std::shared_ptr<Block>>, SubstackType>> substackTree;
3536
bool substackHit = false;
3637
bool warp = false;

src/dev/engine/internal/icodebuilder.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ class ICodeBuilder
2323
virtual void addConstValue(const Value &value) = 0;
2424
virtual void addVariableValue(Variable *variable) = 0;
2525
virtual void addListContents(List *list) = 0;
26+
virtual void addListItem(List *list) = 0;
27+
virtual void addListItemIndex(List *list) = 0;
28+
virtual void addListContains(List *list) = 0;
29+
virtual void addListSize(List *list) = 0;
2630

2731
virtual void createAdd() = 0;
2832
virtual void createSub() = 0;
@@ -56,6 +60,12 @@ class ICodeBuilder
5660

5761
virtual void createVariableWrite(Variable *variable) = 0;
5862

63+
virtual void createListClear(List *list) = 0;
64+
virtual void createListRemove(List *list) = 0;
65+
virtual void createListAppend(List *list) = 0;
66+
virtual void createListInsert(List *list) = 0;
67+
virtual void createListReplace(List *list) = 0;
68+
5969
virtual void beginIfStatement() = 0;
6070
virtual void beginElseBranch() = 0;
6171
virtual void endIf() = 0;

src/dev/engine/internal/llvm/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ target_sources(scratchcpp
99
llvmcoroutine.cpp
1010
llvmcoroutine.h
1111
llvmvariableptr.h
12+
llvmlistptr.h
1213
llvmprocedure.h
1314
llvmtypes.cpp
1415
llvmtypes.h

0 commit comments

Comments
 (0)