MinitScript  0.9.31 PRE-BETA
MapMethods.cpp
Go to the documentation of this file.
1 #include <span>
2 
7 
8 using std::span;
9 
11 
13 
15 
16 void MapMethods::registerConstants(MinitScript* minitScript) {
17 }
18 
19 void MapMethods::registerMethods(MinitScript* minitScript) {
20  // map
21  {
22  //
23  class MethodMap: public MinitScript::Method {
24  private:
25  MinitScript* minitScript { nullptr };
26  public:
27  MethodMap(MinitScript* minitScript):
29  {},
30  MinitScript::TYPE_MAP
31  ),
32  minitScript(minitScript) {}
33  const string getMethodName() override {
34  return "Map";
35  }
36  void executeMethod(span<MinitScript::Variable>& arguments, MinitScript::Variable& returnValue, const MinitScript::SubStatement& subStatement) override {
37  if (arguments.size() == 0) {
38  returnValue.setType(MinitScript::TYPE_MAP);
39  } else {
40  MINITSCRIPT_METHODUSAGE_COMPLAIN(getMethodName());
41  }
42  }
43  };
44  minitScript->registerMethod(new MethodMap(minitScript));
45  }
46  {
47  //
48  class MethodMapGetSize: public MinitScript::Method {
49  private:
50  MinitScript* minitScript { nullptr };
51  public:
52  MethodMapGetSize(MinitScript* minitScript):
54  {
55  { .type = MinitScript::TYPE_MAP, .name = "map", .optional = false, .reference = false, .nullable = false },
56  },
57  MinitScript::TYPE_INTEGER
58  ),
59  minitScript(minitScript) {}
60  const string getMethodName() override {
61  return "Map::getSize";
62  }
63  void executeMethod(span<MinitScript::Variable>& arguments, MinitScript::Variable& returnValue, const MinitScript::SubStatement& subStatement) override {
64  string key;
65  if (arguments.size() == 1 &&
66  arguments[0].getType() == MinitScript::TYPE_MAP) {
67  returnValue.setValue(static_cast<int64_t>(arguments[0].getMapSize()));
68  } else {
69  MINITSCRIPT_METHODUSAGE_COMPLAIN(getMethodName());
70  }
71  }
72  };
73  minitScript->registerMethod(new MethodMapGetSize(minitScript));
74  }
75  {
76  //
77  class MethodMapIsEmpty: public MinitScript::Method {
78  private:
79  MinitScript* minitScript { nullptr };
80  public:
81  MethodMapIsEmpty(MinitScript* minitScript):
83  {
84  { .type = MinitScript::TYPE_MAP, .name = "map", .optional = false, .reference = false, .nullable = false },
85  },
86  MinitScript::TYPE_BOOLEAN
87  ),
88  minitScript(minitScript) {}
89  const string getMethodName() override {
90  return "Map::isEmpty";
91  }
92  void executeMethod(span<MinitScript::Variable>& arguments, MinitScript::Variable& returnValue, const MinitScript::SubStatement& subStatement) override {
93  string key;
94  if (arguments.size() == 1 &&
95  arguments[0].getType() == MinitScript::TYPE_MAP) {
96  returnValue.setValue(arguments[0].getMapSize() == 0);
97  } else {
98  MINITSCRIPT_METHODUSAGE_COMPLAIN(getMethodName());
99  }
100  }
101  };
102  minitScript->registerMethod(new MethodMapIsEmpty(minitScript));
103  }
104  {
105  //
106  class MethodMapSet: public MinitScript::Method {
107  private:
108  MinitScript* minitScript { nullptr };
109  public:
110  MethodMapSet(MinitScript* minitScript):
112  {
113  { .type = MinitScript::TYPE_MAP, .name = "map", .optional = false, .reference = true, .nullable = false },
114  { .type = MinitScript::TYPE_STRING, .name = "key", .optional = false, .reference = false, .nullable = false },
115  { .type = MinitScript::TYPE_PSEUDO_MIXED, .name = "value", .optional = false, .reference = false, .nullable = false }
116  },
117  MinitScript::TYPE_NULL
118  ),
119  minitScript(minitScript) {}
120  const string getMethodName() override {
121  return "Map::set";
122  }
123  void executeMethod(span<MinitScript::Variable>& arguments, MinitScript::Variable& returnValue, const MinitScript::SubStatement& subStatement) override {
124  //
125  string key;
126  if (arguments.size() == 3 &&
127  arguments[0].getType() == MinitScript::TYPE_MAP &&
128  MinitScript::getStringValue(arguments, 1, key) == true) {
129  arguments[0].setMapEntry(key, arguments[2]);
130  } else {
131  MINITSCRIPT_METHODUSAGE_COMPLAIN(getMethodName());
132  }
133  }
134  };
135  minitScript->registerMethod(new MethodMapSet(minitScript));
136  }
137  {
138  //
139  class MethodMapContains: public MinitScript::Method {
140  private:
141  MinitScript* minitScript { nullptr };
142  public:
143  MethodMapContains(MinitScript* minitScript):
145  {
146  { .type = MinitScript::TYPE_MAP, .name = "map", .optional = false, .reference = false, .nullable = false },
147  { .type = MinitScript::TYPE_STRING, .name = "key", .optional = false, .reference = false, .nullable = false }
148  },
149  MinitScript::TYPE_BOOLEAN
150  ),
151  minitScript(minitScript) {}
152  const string getMethodName() override {
153  return "Map::contains";
154  }
155  void executeMethod(span<MinitScript::Variable>& arguments, MinitScript::Variable& returnValue, const MinitScript::SubStatement& subStatement) override {
156  string key;
157  if (arguments.size() == 2 &&
158  arguments[0].getType() == MinitScript::TYPE_MAP &&
159  MinitScript::getStringValue(arguments, 1, key) == true) {
160  returnValue.setValue(arguments[0].hasMapEntry(key));
161  } else {
162  MINITSCRIPT_METHODUSAGE_COMPLAIN(getMethodName());
163  }
164  }
165  };
166  minitScript->registerMethod(new MethodMapContains(minitScript));
167  }
168  {
169  //
170  class MethodMapGet: public MinitScript::Method {
171  private:
172  MinitScript* minitScript { nullptr };
173  public:
174  MethodMapGet(MinitScript* minitScript):
176  {
177  { .type = MinitScript::TYPE_MAP, .name = "map", .optional = false, .reference = false, .nullable = false },
178  { .type = MinitScript::TYPE_STRING, .name = "key", .optional = false, .reference = false, .nullable = false }
179  },
180  MinitScript::TYPE_PSEUDO_MIXED
181  ),
182  minitScript(minitScript) {}
183  const string getMethodName() override {
184  return "Map::get";
185  }
186  void executeMethod(span<MinitScript::Variable>& arguments, MinitScript::Variable& returnValue, const MinitScript::SubStatement& subStatement) override {
187  string key;
188  if (arguments.size() == 2 &&
189  arguments[0].getType() == MinitScript::TYPE_MAP &&
190  MinitScript::getStringValue(arguments, 1, key) == true) {
191  returnValue.setValue(arguments[0].getMapEntry(key));
192  } else {
193  MINITSCRIPT_METHODUSAGE_COMPLAIN(getMethodName());
194  }
195  }
196  };
197  minitScript->registerMethod(new MethodMapGet(minitScript));
198  }
199  {
200  //
201  class MethodMapGetReference: public MinitScript::Method {
202  private:
203  MinitScript* minitScript { nullptr };
204  public:
205  MethodMapGetReference(MinitScript* minitScript):
207  {
208  { .type = MinitScript::TYPE_MAP, .name = "map", .optional = false, .reference = false, .nullable = false },
209  { .type = MinitScript::TYPE_STRING, .name = "key", .optional = false, .reference = false, .nullable = false }
210  },
211  MinitScript::TYPE_PSEUDO_MIXED
212  ),
213  minitScript(minitScript) {}
214  const string getMethodName() override {
215  return "Map::getReference";
216  }
217  void executeMethod(span<MinitScript::Variable>& arguments, MinitScript::Variable& returnValue, const MinitScript::SubStatement& subStatement) override {
218  string key;
219  if (arguments.size() == 2 &&
220  arguments[0].getType() == MinitScript::TYPE_MAP &&
221  MinitScript::getStringValue(arguments, 1, key) == true) {
222  auto mapEntryPtr = arguments[0].getMapEntryPtr(key);
223  if (mapEntryPtr != nullptr) returnValue = MinitScript::Variable::createReferenceVariable(mapEntryPtr);
224  } else {
225  MINITSCRIPT_METHODUSAGE_COMPLAIN(getMethodName());
226  }
227  }
228  virtual bool isPrivate() const override {
229  return true;
230  }
231  };
232  minitScript->registerMethod(new MethodMapGetReference(minitScript));
233  }
234  {
235  //
236  class MethodMapRemove: public MinitScript::Method {
237  private:
238  MinitScript* minitScript { nullptr };
239  public:
240  MethodMapRemove(MinitScript* minitScript):
242  {
243  { .type = MinitScript::TYPE_MAP, .name = "map", .optional = false, .reference = true, .nullable = false },
244  { .type = MinitScript::TYPE_STRING, .name = "key", .optional = false, .reference = false, .nullable = false }
245  },
246  MinitScript::TYPE_NULL
247  ),
248  minitScript(minitScript) {}
249  const string getMethodName() override {
250  return "Map::remove";
251  }
252  void executeMethod(span<MinitScript::Variable>& arguments, MinitScript::Variable& returnValue, const MinitScript::SubStatement& subStatement) override {
253  string key;
254  if (arguments.size() == 2 &&
255  arguments[0].getType() == MinitScript::TYPE_MAP &&
256  MinitScript::getStringValue(arguments, 1, key) == true) {
257  arguments[0].removeMapEntry(key);
258  } else {
259  MINITSCRIPT_METHODUSAGE_COMPLAIN(getMethodName());
260  }
261  }
262  };
263  minitScript->registerMethod(new MethodMapRemove(minitScript));
264  }
265  {
266  //
267  class MethodMapGetKeys: public MinitScript::Method {
268  private:
269  MinitScript* minitScript { nullptr };
270  public:
271  MethodMapGetKeys(MinitScript* minitScript):
273  {
274  { .type = MinitScript::TYPE_MAP, .name = "map", .optional = false, .reference = false, .nullable = false },
275  },
276  MinitScript::TYPE_ARRAY
277  ),
278  minitScript(minitScript) {}
279  const string getMethodName() override {
280  return "Map::getKeys";
281  }
282  void executeMethod(span<MinitScript::Variable>& arguments, MinitScript::Variable& returnValue, const MinitScript::SubStatement& subStatement) override {
283  if (arguments.size() == 1 &&
284  arguments[0].getType() == MinitScript::TYPE_MAP) {
285  auto keys = arguments[0].getMapKeys();
286  returnValue.setType(MinitScript::TYPE_ARRAY);
287  for (const auto& key: keys) {
288  returnValue.pushArrayEntry(key);
289  }
290  } else {
291  MINITSCRIPT_METHODUSAGE_COMPLAIN(getMethodName());
292  }
293  }
294  };
295  minitScript->registerMethod(new MethodMapGetKeys(minitScript));
296  }
297  {
298  //
299  class MethodMapGetValues: public MinitScript::Method {
300  private:
301  MinitScript* minitScript { nullptr };
302  public:
303  MethodMapGetValues(MinitScript* minitScript):
305  {
306  { .type = MinitScript::TYPE_MAP, .name = "map", .optional = false, .reference = false, .nullable = false },
307  },
308  MinitScript::TYPE_ARRAY
309  ),
310  minitScript(minitScript) {}
311  const string getMethodName() override {
312  return "Map::getValues";
313  }
314  void executeMethod(span<MinitScript::Variable>& arguments, MinitScript::Variable& returnValue, const MinitScript::SubStatement& subStatement) override {
315  if (arguments.size() == 1 &&
316  arguments[0].getType() == MinitScript::TYPE_MAP) {
317  auto values = arguments[0].getMapValues();
318  returnValue.setType(MinitScript::TYPE_ARRAY);
319  for (const auto value: values) {
320  returnValue.pushArrayEntry(*value);
321  }
322  } else {
323  MINITSCRIPT_METHODUSAGE_COMPLAIN(getMethodName());
324  }
325  }
326  };
327  minitScript->registerMethod(new MethodMapGetValues(minitScript));
328  }
329  {
330  //
331  class MethodMapClear: public MinitScript::Method {
332  private:
333  MinitScript* minitScript { nullptr };
334  public:
335  MethodMapClear(MinitScript* minitScript):
337  {
338  { .type = MinitScript::TYPE_MAP, .name = "map", .optional = false, .reference = true, .nullable = false }
339  },
340  MinitScript::TYPE_NULL
341  ),
342  minitScript(minitScript) {}
343  const string getMethodName() override {
344  return "Map::clear";
345  }
346  void executeMethod(span<MinitScript::Variable>& arguments, MinitScript::Variable& returnValue, const MinitScript::SubStatement& subStatement) override {
347  if (arguments.size() == 1 &&
348  arguments[0].getType() == MinitScript::TYPE_MAP) {
349  arguments[0].clearMap();
350  } else {
351  MINITSCRIPT_METHODUSAGE_COMPLAIN(getMethodName());
352  }
353  }
354  };
355  minitScript->registerMethod(new MethodMapClear(minitScript));
356  }
357  {
358  //
359  class MethodMapForEach: public MinitScript::Method {
360  private:
361  MinitScript* minitScript { nullptr };
362  public:
363  MethodMapForEach(MinitScript* minitScript):
365  {
366  { .type = MinitScript::TYPE_MAP, .name = "map", .optional = false, .reference = false, .nullable = false },
367  { .type = MinitScript::TYPE_FUNCTION_ASSIGNMENT, .name = "callbackFunction", .optional = false, .reference = false, .nullable = false },
368  { .type = MinitScript::TYPE_PSEUDO_MIXED, .name = "cookie", .optional = true, .reference = true, .nullable = false }
369  },
370  MinitScript::TYPE_NULL
371  ),
372  minitScript(minitScript) {}
373  const string getMethodName() override {
374  return "Map::forEach";
375  }
376  void executeMethod(span<MinitScript::Variable>& arguments, MinitScript::Variable& returnValue, const MinitScript::SubStatement& subStatement) override {
377  string callbackFunction;
378  int callbackFunctionScriptIdx;
379  if ((arguments.size() == 2 || arguments.size() == 3) &&
380  arguments[0].getType() == MinitScript::TYPE_MAP &&
381  MinitScript::getFunctionValue(arguments, 1, callbackFunction, callbackFunctionScriptIdx) == true) {
382  auto mapPtr = arguments[0].getMapPointer();
383  if (mapPtr != nullptr) {
384  if (callbackFunction.empty() == false && callbackFunctionScriptIdx == MinitScript::SCRIPTIDX_NONE) {
385  callbackFunctionScriptIdx = minitScript->getFunctionScriptIdx(callbackFunction);
386  }
387  if (callbackFunctionScriptIdx == MinitScript::SCRIPTIDX_NONE) {
388  MINITSCRIPT_METHODUSAGE_COMPLAINM(getMethodName(), "Function not found: " + callbackFunction);
389  } else {
390  for (const auto& [mapKey, mapValue]: *mapPtr) {
391  vector<MinitScript::Variable> functionArguments { MinitScript::Variable(mapKey), MinitScript::Variable::createReferenceVariable(mapValue) };
392  if (arguments.size() == 3) functionArguments.push_back(arguments[2]);
393  span functionArgumentsSpan(functionArguments);
394  MinitScript::Variable functionReturnValue;
395  minitScript->call(callbackFunctionScriptIdx, functionArgumentsSpan, functionReturnValue);
396  // exit condition
397  bool result = false;
398  functionReturnValue.getBooleanValue(result, false);
399  if (result == true) break;
400  }
401  }
402  }
403  } else {
404  MINITSCRIPT_METHODUSAGE_COMPLAIN(getMethodName());
405  }
406  }
407  };
408  minitScript->registerMethod(new MethodMapForEach(minitScript));
409  }
410 }
#define MINITSCRIPT_METHODUSAGE_COMPLAINM(methodName, message)
Definition: MinitScript.h:60
#define MINITSCRIPT_METHODUSAGE_COMPLAIN(methodName)
Definition: MinitScript.h:59
MinitScript script map methods.
Definition: MapMethods.h:12
void pushArrayEntry(const Variable &value)
Push entry to array.
Definition: MinitScript.h:1892
bool getBooleanValue(bool &value, bool optional=false) const
Get boolean value from given variable.
Definition: MinitScript.h:1405
void setType(VariableType newType)
Set type.
Definition: MinitScript.h:1253
void setValue(const Variable &variable)
Set value from given variable into variable.
Definition: MinitScript.h:1618
void registerMethod(Method *method)
Register method.
int getFunctionScriptIdx(const string &function)
Return function script index by function name.
Definition: MinitScript.h:5204
bool call(int scriptIdx, span< Variable > &arguments, Variable &returnValue, bool pushScriptState)
Call function.