1
1
// SPDX-License-Identifier: Apache-2.0
2
2
3
+ #include < scratchcpp/iengine.h>
4
+ #include < scratchcpp/dev/compiler.h>
5
+ #include < scratchcpp/dev/compilerconstant.h>
6
+ #include < scratchcpp/field.h>
7
+ #include < scratchcpp/list.h>
8
+
3
9
#include " listblocks.h"
4
10
5
11
using namespace libscratchcpp ;
@@ -16,4 +22,191 @@ std::string ListBlocks::description() const
16
22
17
23
void ListBlocks::registerBlocks (IEngine *engine)
18
24
{
25
+ engine->addCompileFunction (this , " data_addtolist" , &compileAddToList);
26
+ engine->addCompileFunction (this , " data_deleteoflist" , &compileDeleteOfList);
27
+ engine->addCompileFunction (this , " data_deletealloflist" , &compileDeleteAllOfList);
28
+ engine->addCompileFunction (this , " data_insertatlist" , &compileInsertAtList);
29
+ engine->addCompileFunction (this , " data_replaceitemoflist" , &compileReplaceItemOfList);
30
+ engine->addCompileFunction (this , " data_itemoflist" , &compileItemOfList);
31
+ engine->addCompileFunction (this , " data_itemnumoflist" , &compileItemNumOfList);
32
+ engine->addCompileFunction (this , " data_lengthoflist" , &compileLengthOfList);
33
+ engine->addCompileFunction (this , " data_listcontainsitem" , &compileListContainsItem);
34
+ }
35
+
36
+ CompilerValue *ListBlocks::compileAddToList (Compiler *compiler)
37
+ {
38
+ auto list = compiler->field (" LIST" )->valuePtr ();
39
+ assert (list);
40
+
41
+ if (list)
42
+ compiler->createListAppend (static_cast <List *>(list.get ()), compiler->addInput (" ITEM" ));
43
+
44
+ return nullptr ;
45
+ }
46
+
47
+ CompilerValue *ListBlocks::getListIndex (Compiler *compiler, CompilerValue *input, List *list, CompilerValue *listSize)
48
+ {
49
+ CompilerLocalVariable *ret = compiler->createLocalVariable (Compiler::StaticType::Number);
50
+
51
+ CompilerValue *isRandom1 = compiler->createCmpEQ (input, compiler->addConstValue (" random" ));
52
+ CompilerValue *isRandom2 = compiler->createCmpEQ (input, compiler->addConstValue (" any" ));
53
+ CompilerValue *isRandom = compiler->createOr (isRandom1, isRandom2);
54
+
55
+ compiler->beginIfStatement (isRandom);
56
+ {
57
+ CompilerValue *random = compiler->createRandomInt (compiler->addConstValue (1 ), listSize);
58
+ compiler->createLocalVariableWrite (ret, random);
59
+ }
60
+ compiler->beginElseBranch ();
61
+ {
62
+ CompilerValue *isLast = compiler->createCmpEQ (input, compiler->addConstValue (" last" ));
63
+ compiler->createLocalVariableWrite (ret, compiler->createSelect (isLast, listSize, input, Compiler::StaticType::Number));
64
+ }
65
+ compiler->endIf ();
66
+
67
+ return compiler->addLocalVariableValue (ret);
68
+ }
69
+
70
+ CompilerValue *ListBlocks::compileDeleteOfList (Compiler *compiler)
71
+ {
72
+ List *list = static_cast <List *>(compiler->field (" LIST" )->valuePtr ().get ());
73
+ assert (list);
74
+
75
+ if (list) {
76
+ CompilerValue *index = compiler->addInput (" INDEX" );
77
+ CompilerValue *cond = compiler->createCmpEQ (index, compiler->addConstValue (" all" ));
78
+ compiler->beginIfStatement (cond);
79
+ {
80
+ compiler->createListClear (list);
81
+ }
82
+ compiler->beginElseBranch ();
83
+ {
84
+ CompilerValue *min = compiler->addConstValue (-1 );
85
+ CompilerValue *max = compiler->addListSize (list);
86
+ index = getListIndex (compiler, index, list, max);
87
+ index = compiler->createSub (index, compiler->addConstValue (1 ));
88
+ cond = compiler->createAnd (compiler->createCmpGT (index, min), compiler->createCmpLT (index, max));
89
+ compiler->beginIfStatement (cond);
90
+ {
91
+ compiler->createListRemove (list, index);
92
+ }
93
+ compiler->endIf ();
94
+ }
95
+ compiler->endIf ();
96
+ }
97
+
98
+ return nullptr ;
99
+ }
100
+
101
+ CompilerValue *ListBlocks::compileDeleteAllOfList (Compiler *compiler)
102
+ {
103
+ auto list = compiler->field (" LIST" )->valuePtr ();
104
+ assert (list);
105
+
106
+ if (list)
107
+ compiler->createListClear (static_cast <List *>(list.get ()));
108
+
109
+ return nullptr ;
110
+ }
111
+
112
+ CompilerValue *ListBlocks::compileInsertAtList (Compiler *compiler)
113
+ {
114
+ List *list = static_cast <List *>(compiler->field (" LIST" )->valuePtr ().get ());
115
+ assert (list);
116
+
117
+ if (list) {
118
+ CompilerValue *index = compiler->addInput (" INDEX" );
119
+ CompilerValue *min = compiler->addConstValue (-1 );
120
+ CompilerValue *max = compiler->createAdd (compiler->addListSize (list), compiler->addConstValue (1 ));
121
+ index = getListIndex (compiler, index, list, max);
122
+ index = compiler->createSub (index, compiler->addConstValue (1 ));
123
+ CompilerValue *cond = compiler->createAnd (compiler->createCmpGT (index, min), compiler->createCmpLT (index, max));
124
+ compiler->beginIfStatement (cond);
125
+ {
126
+ CompilerValue *item = compiler->addInput (" ITEM" );
127
+ compiler->createListInsert (list, index, item);
128
+ }
129
+ compiler->endIf ();
130
+ }
131
+
132
+ return nullptr ;
133
+ }
134
+
135
+ CompilerValue *ListBlocks::compileReplaceItemOfList (Compiler *compiler)
136
+ {
137
+ List *list = static_cast <List *>(compiler->field (" LIST" )->valuePtr ().get ());
138
+ assert (list);
139
+
140
+ if (list) {
141
+ CompilerValue *index = compiler->addInput (" INDEX" );
142
+ CompilerValue *min = compiler->addConstValue (-1 );
143
+ CompilerValue *max = compiler->addListSize (list);
144
+ index = getListIndex (compiler, index, list, max);
145
+ index = compiler->createSub (index, compiler->addConstValue (1 ));
146
+ CompilerValue *cond = compiler->createAnd (compiler->createCmpGT (index, min), compiler->createCmpLT (index, max));
147
+ compiler->beginIfStatement (cond);
148
+ {
149
+ CompilerValue *item = compiler->addInput (" ITEM" );
150
+ compiler->createListReplace (list, index, item);
151
+ }
152
+ compiler->endIf ();
153
+ }
154
+
155
+ return nullptr ;
156
+ }
157
+
158
+ CompilerValue *ListBlocks::compileItemOfList (Compiler *compiler)
159
+ {
160
+ List *list = static_cast <List *>(compiler->field (" LIST" )->valuePtr ().get ());
161
+ assert (list);
162
+
163
+ if (list) {
164
+ CompilerValue *index = compiler->addInput (" INDEX" );
165
+ CompilerValue *min = compiler->addConstValue (-1 );
166
+ CompilerValue *max = compiler->addListSize (list);
167
+ index = getListIndex (compiler, index, list, max);
168
+ index = compiler->createSub (index, compiler->addConstValue (1 ));
169
+ CompilerValue *cond = compiler->createAnd (compiler->createCmpGT (index, min), compiler->createCmpLT (index, max));
170
+ CompilerValue *item = compiler->addListItem (list, index);
171
+ return compiler->createSelect (cond, item, compiler->addConstValue (Value ()), Compiler::StaticType::Unknown);
172
+ }
173
+
174
+ return nullptr ;
175
+ }
176
+
177
+ CompilerValue *ListBlocks::compileItemNumOfList (Compiler *compiler)
178
+ {
179
+ List *list = static_cast <List *>(compiler->field (" LIST" )->valuePtr ().get ());
180
+ assert (list);
181
+
182
+ if (list) {
183
+ CompilerValue *item = compiler->addInput (" ITEM" );
184
+ return compiler->createAdd (compiler->addListItemIndex (list, item), compiler->addConstValue (1 ));
185
+ }
186
+
187
+ return nullptr ;
188
+ }
189
+
190
+ CompilerValue *ListBlocks::compileLengthOfList (Compiler *compiler)
191
+ {
192
+ List *list = static_cast <List *>(compiler->field (" LIST" )->valuePtr ().get ());
193
+ assert (list);
194
+
195
+ if (list)
196
+ return compiler->addListSize (list);
197
+
198
+ return nullptr ;
199
+ }
200
+
201
+ CompilerValue *ListBlocks::compileListContainsItem (Compiler *compiler)
202
+ {
203
+ List *list = static_cast <List *>(compiler->field (" LIST" )->valuePtr ().get ());
204
+ assert (list);
205
+
206
+ if (list) {
207
+ CompilerValue *item = compiler->addInput (" ITEM" );
208
+ return compiler->addListContains (list, item);
209
+ }
210
+
211
+ return nullptr ;
19
212
}
0 commit comments