/[svn]/linuxsampler/trunk/src/scriptvm/CoreVMFunctions.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/scriptvm/CoreVMFunctions.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3221 - (show annotations) (download)
Fri May 26 18:30:42 2017 UTC (6 years, 10 months ago) by schoenebeck
File size: 14622 byte(s)
* NKSP Fix: Never suspend "init" event handlers.
* NKSP: Implemented built-in script function "array_equal()".
* NKSP: Implemented built-in script function "search()".
* NKSP: Implemented built-in script function "sort()".
* Bumped version (2.0.0.svn52).

1 /*
2 * Copyright (c) 2014-2017 Christian Schoenebeck
3 *
4 * http://www.linuxsampler.org
5 *
6 * This file is part of LinuxSampler and released under the same terms.
7 * See README file for details.
8 */
9
10 #include "CoreVMFunctions.h"
11
12 #include <iostream>
13 #include <algorithm> // for std::sort()
14 #include <math.h>
15 #include <stdlib.h>
16 #include "tree.h"
17 #include "ScriptVM.h"
18
19 namespace LinuxSampler {
20
21 ///////////////////////////////////////////////////////////////////////////
22 // class VMEmptyResultFunction
23
24 VMFnResult* VMEmptyResultFunction::errorResult() {
25 result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
26 return &result;
27 }
28
29 VMFnResult* VMEmptyResultFunction::successResult() {
30 result.flags = STMT_SUCCESS;
31 return &result;
32 }
33
34 ///////////////////////////////////////////////////////////////////////////
35 // class VMIntResultFunction
36
37 VMFnResult* VMIntResultFunction::errorResult(int i) {
38 result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
39 result.value = i;
40 return &result;
41 }
42
43 VMFnResult* VMIntResultFunction::successResult(int i) {
44 result.flags = STMT_SUCCESS;
45 result.value = i;
46 return &result;
47 }
48
49 ///////////////////////////////////////////////////////////////////////////
50 // class VMStringResultFunction
51
52 VMFnResult* VMStringResultFunction::errorResult(const String& s) {
53 result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
54 result.value = s;
55 return &result;
56 }
57
58 VMFnResult* VMStringResultFunction::successResult(const String& s) {
59 result.flags = STMT_SUCCESS;
60 result.value = s;
61 return &result;
62 }
63
64 ///////////////////////////////////////////////////////////////////////////
65 // built-in script function: message()
66
67 bool CoreVMFunction_message::acceptsArgType(int iArg, ExprType_t type) const {
68 return type == INT_EXPR || type == STRING_EXPR;
69 }
70
71 VMFnResult* CoreVMFunction_message::exec(VMFnArgs* args) {
72 if (!args->argsCount()) return errorResult();
73
74 VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(args->arg(0));
75 if (strExpr) {
76 std::cout << "[ScriptVM] " << strExpr->evalStr() << "\n";
77 return successResult();
78 }
79
80 VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(args->arg(0));
81 if (intExpr) {
82 std::cout << "[ScriptVM] " << intExpr->evalInt() << "\n";
83 return successResult();
84 }
85
86 return errorResult();
87 }
88
89 ///////////////////////////////////////////////////////////////////////////
90 // built-in script function: exit()
91
92 VMFnResult* CoreVMFunction_exit::exec(VMFnArgs* args) {
93 this->result.flags = STMT_ABORT_SIGNALLED;
94 return &result;
95 }
96
97 ///////////////////////////////////////////////////////////////////////////
98 // built-in script function: wait()
99
100 VMFnResult* CoreVMFunction_wait::exec(VMFnArgs* args) {
101 ExecContext* ctx = dynamic_cast<ExecContext*>(vm->currentVMExecContext());
102 VMIntExpr* expr = dynamic_cast<VMIntExpr*>(args->arg(0));
103 int us = expr->evalInt();
104 if (us < 0) {
105 wrnMsg("wait(): argument may not be negative! Aborting script!");
106 this->result.flags = STMT_ABORT_SIGNALLED;
107 } else if (us == 0) {
108 wrnMsg("wait(): argument may not be zero! Aborting script!");
109 this->result.flags = STMT_ABORT_SIGNALLED;
110 } else {
111 ctx->suspendMicroseconds = us;
112 this->result.flags = STMT_SUSPEND_SIGNALLED;
113 }
114 return &result;
115 }
116
117 ///////////////////////////////////////////////////////////////////////////
118 // built-in script function: abs()
119
120 bool CoreVMFunction_abs::acceptsArgType(int iArg, ExprType_t type) const {
121 return type == INT_EXPR;
122 }
123
124 VMFnResult* CoreVMFunction_abs::exec(VMFnArgs* args) {
125 return successResult( ::abs(args->arg(0)->asInt()->evalInt()) );
126 }
127
128 ///////////////////////////////////////////////////////////////////////////
129 // built-in script function: random()
130
131 bool CoreVMFunction_random::acceptsArgType(int iArg, ExprType_t type) const {
132 return type == INT_EXPR;
133 }
134
135 VMFnResult* CoreVMFunction_random::exec(VMFnArgs* args) {
136 int iMin = args->arg(0)->asInt()->evalInt();
137 int iMax = args->arg(1)->asInt()->evalInt();
138 float f = float(::rand()) / float(RAND_MAX);
139 return successResult(
140 iMin + roundf( f * float(iMax - iMin) )
141 );
142 }
143
144 ///////////////////////////////////////////////////////////////////////////
145 // built-in script function: num_elements()
146
147 bool CoreVMFunction_num_elements::acceptsArgType(int iArg, ExprType_t type) const {
148 return type == INT_ARR_EXPR;
149 }
150
151 VMFnResult* CoreVMFunction_num_elements::exec(VMFnArgs* args) {
152 return successResult( args->arg(0)->asIntArray()->arraySize() );
153 }
154
155 ///////////////////////////////////////////////////////////////////////////
156 // built-in script function: inc()
157
158 VMFnResult* CoreVMFunction_inc::exec(VMFnArgs* args) {
159 VMExpr* arg = args->arg(0);
160 VMIntExpr* in = dynamic_cast<VMIntExpr*>(arg);
161 VMVariable* out = dynamic_cast<VMVariable*>(arg);
162 if (!in || !out) successResult(0);
163 int i = in->evalInt() + 1;
164 IntLiteral tmp(i);
165 out->assignExpr(&tmp);
166 return successResult(i);
167 }
168
169 ///////////////////////////////////////////////////////////////////////////
170 // built-in script function: dec()
171
172 VMFnResult* CoreVMFunction_dec::exec(VMFnArgs* args) {
173 VMExpr* arg = args->arg(0);
174 VMIntExpr* in = dynamic_cast<VMIntExpr*>(arg);
175 VMVariable* out = dynamic_cast<VMVariable*>(arg);
176 if (!in || !out) successResult(0);
177 int i = in->evalInt() - 1;
178 IntLiteral tmp(i);
179 out->assignExpr(&tmp);
180 return successResult(i);
181 }
182
183 ///////////////////////////////////////////////////////////////////////////
184 // built-in script function: in_range()
185
186 VMFnResult* CoreVMFunction_in_range::exec(VMFnArgs* args) {
187 int i = args->arg(0)->asInt()->evalInt();
188 int lo = args->arg(1)->asInt()->evalInt();
189 int hi = args->arg(2)->asInt()->evalInt();
190 if (lo > hi) { // swap lo and hi
191 int tmp = lo;
192 lo = hi;
193 hi = tmp;
194 }
195 return successResult(i >= lo && i <= hi);
196 }
197
198 ///////////////////////////////////////////////////////////////////////////
199 // built-in script function: sh_left()
200
201 VMFnResult* CoreVMFunction_sh_left::exec(VMFnArgs* args) {
202 int i = args->arg(0)->asInt()->evalInt();
203 int n = args->arg(1)->asInt()->evalInt();
204 return successResult(i << n);
205 }
206
207 ///////////////////////////////////////////////////////////////////////////
208 // built-in script function: sh_right()
209
210 VMFnResult* CoreVMFunction_sh_right::exec(VMFnArgs* args) {
211 int i = args->arg(0)->asInt()->evalInt();
212 int n = args->arg(1)->asInt()->evalInt();
213 return successResult(i >> n);
214 }
215
216 ///////////////////////////////////////////////////////////////////////////
217 // built-in script function: min()
218
219 VMFnResult* CoreVMFunction_min::exec(VMFnArgs* args) {
220 int l = args->arg(0)->asInt()->evalInt();
221 int r = args->arg(1)->asInt()->evalInt();
222 return successResult(l < r ? l : r);
223 }
224
225 ///////////////////////////////////////////////////////////////////////////
226 // built-in script function: max()
227
228 VMFnResult* CoreVMFunction_max::exec(VMFnArgs* args) {
229 int l = args->arg(0)->asInt()->evalInt();
230 int r = args->arg(1)->asInt()->evalInt();
231 return successResult(l > r ? l : r);
232 }
233
234 ///////////////////////////////////////////////////////////////////////////
235 // built-in script function: array_equal()
236
237 VMFnResult* CoreVMFunction_array_equal::exec(VMFnArgs* args) {
238 VMIntArrayExpr* l = args->arg(0)->asIntArray();
239 VMIntArrayExpr* r = args->arg(1)->asIntArray();
240 if (l->arraySize() != r->arraySize()) {
241 wrnMsg("array_equal(): the two arrays differ in size");
242 return successResult(0); // false
243 }
244 const int n = l->arraySize();
245 for (int i = 0; i < n; ++i)
246 if (l->evalIntElement(i) != r->evalIntElement(i))
247 return successResult(0); // false
248 return successResult(1); // true
249 }
250
251 ///////////////////////////////////////////////////////////////////////////
252 // built-in script function: search()
253
254 ExprType_t CoreVMFunction_search::argType(int iArg) const {
255 return (iArg == 0) ? INT_ARR_EXPR : INT_EXPR;
256 }
257
258 bool CoreVMFunction_search::acceptsArgType(int iArg, ExprType_t type) const {
259 if (iArg == 0)
260 return type == INT_ARR_EXPR;
261 else
262 return type == INT_EXPR;
263 }
264
265 VMFnResult* CoreVMFunction_search::exec(VMFnArgs* args) {
266 VMIntArrayExpr* a = args->arg(0)->asIntArray();
267 const int needle = args->arg(1)->asInt()->evalInt();
268 const int n = a->arraySize();
269 for (int i = 0; i < n; ++i)
270 if (a->evalIntElement(i) == needle)
271 return successResult(i);
272 return successResult(-1); // not found
273 }
274
275 ///////////////////////////////////////////////////////////////////////////
276 // built-in script function: sort()
277
278 ExprType_t CoreVMFunction_sort::argType(int iArg) const {
279 return (iArg == 0) ? INT_ARR_EXPR : INT_EXPR;
280 }
281
282 bool CoreVMFunction_sort::acceptsArgType(int iArg, ExprType_t type) const {
283 if (iArg == 0)
284 return type == INT_ARR_EXPR;
285 else
286 return type == INT_EXPR;
287 }
288
289 struct ArrElemPOD {
290 VMIntArrayExpr* m_array;
291 int m_index;
292 };
293
294 static inline void swap(class ArrElemRef& a, class ArrElemRef& b);
295
296 class ArrElemRef : protected ArrElemPOD {
297 public:
298 ArrElemRef() {
299 m_array = NULL;
300 m_index = 0;
301 }
302 ArrElemRef(VMIntArrayExpr* a, int index) {
303 m_array = a;
304 m_index = index;
305 }
306 inline ArrElemRef& operator=(const ArrElemRef& e) {
307 setValue(e.getValue());
308 return *this;
309 }
310 inline ArrElemRef& operator=(int val) {
311 setValue(val);
312 return *this;
313 }
314 inline bool operator==(const ArrElemRef& e) const {
315 if (m_index == e.m_index)
316 return true;
317 return getValue() == e.getValue();
318 }
319 inline bool operator==(int val) const {
320 return getValue() == val;
321 }
322 inline bool operator!=(const ArrElemRef& e) const {
323 return !(operator==(e));
324 }
325 inline bool operator!=(int val) const {
326 return !(operator==(val));
327 }
328 inline bool operator<(const ArrElemRef& e) const {
329 if (m_index == e.m_index)
330 return false;
331 return getValue() < e.getValue();
332 }
333 inline bool operator<(int val) const {
334 return getValue() < val;
335 }
336 inline bool operator>(const ArrElemRef& e) const {
337 if (m_index == e.m_index)
338 return false;
339 return getValue() > e.getValue();
340 }
341 inline bool operator>(int val) const {
342 return getValue() > val;
343 }
344 inline bool operator<=(const ArrElemRef& e) const {
345 if (m_index == e.m_index)
346 return true;
347 return getValue() <= e.getValue();
348 }
349 inline bool operator<=(int val) const {
350 return getValue() <= val;
351 }
352 inline bool operator>=(const ArrElemRef& e) const {
353 if (m_index == e.m_index)
354 return true;
355 return getValue() >= e.getValue();
356 }
357 inline bool operator>=(int val) const {
358 return getValue() >= val;
359 }
360 inline operator int() const {
361 return getValue();
362 }
363 protected:
364 inline int getValue() const {
365 return m_array->evalIntElement(m_index);
366 }
367 inline void setValue(int value) {
368 m_array->assignIntElement(m_index, value);
369 }
370
371 friend void swap(class ArrElemRef& a, class ArrElemRef& b);
372 };
373
374 class ArrElemPtr : protected ArrElemPOD {
375 public:
376 ArrElemPtr() {
377 m_array = NULL;
378 m_index = 0;
379 }
380 ArrElemPtr(VMIntArrayExpr* a, int index) {
381 m_array = a;
382 m_index = index;
383 }
384 inline ArrElemRef operator*() {
385 return *(ArrElemRef*)this;
386 }
387 };
388
389 static inline void swap(ArrElemRef& a, ArrElemRef& b) {
390 int valueA = a.getValue();
391 int valueB = b.getValue();
392 a.setValue(valueB);
393 b.setValue(valueA);
394 }
395
396 class ArrExprIter : public ArrElemPOD {
397 public:
398 typedef std::random_access_iterator_tag iterator_category;
399 typedef int value_type;
400 typedef ssize_t difference_type;
401 typedef ArrElemPtr pointer;
402 typedef ArrElemRef reference;
403
404 ArrExprIter(VMIntArrayExpr* a, int index) {
405 m_array = a;
406 m_index = index;
407 }
408 inline ArrElemRef operator*() {
409 return *(ArrElemRef*)this;
410 }
411 inline ArrExprIter& operator++() { // prefix increment
412 ++m_index;
413 return *this;
414 }
415 inline ArrExprIter& operator--() { // prefix decrement
416 --m_index;
417 return *this;
418 }
419 inline ArrExprIter operator++(int) { // postfix increment
420 ArrExprIter it = *this;
421 ++m_index;
422 return it;
423 }
424 inline ArrExprIter operator--(int) { // postfix decrement
425 ArrExprIter it = *this;
426 --m_index;
427 return it;
428 }
429 inline bool operator==(const ArrExprIter& other) const {
430 return m_index == other.m_index;
431 }
432 inline bool operator!=(const ArrExprIter& other) const {
433 return m_index != other.m_index;
434 }
435 inline bool operator<(const ArrExprIter& other) const {
436 return m_index < other.m_index;
437 }
438 inline bool operator>(const ArrExprIter& other) const {
439 return m_index > other.m_index;
440 }
441 inline bool operator<=(const ArrExprIter& other) const {
442 return m_index <= other.m_index;
443 }
444 inline bool operator>=(const ArrExprIter& other) const {
445 return m_index >= other.m_index;
446 }
447 inline difference_type operator+(const ArrExprIter& other) const {
448 return m_index + other.m_index;
449 }
450 inline difference_type operator-(const ArrExprIter& other) const {
451 return m_index - other.m_index;
452 }
453 inline ArrExprIter operator-(difference_type d) const {
454 return ArrExprIter(m_array, m_index - d);
455 }
456 inline ArrExprIter operator+(difference_type d) const {
457 return ArrExprIter(m_array, m_index + d);
458 }
459 inline ArrExprIter operator*(difference_type factor) const {
460 return ArrExprIter(m_array, m_index * factor);
461 }
462 };
463
464 struct DescArrExprSorter {
465 inline bool operator()(const int& a, const int& b) const {
466 return a > b;
467 }
468 };
469
470 VMFnResult* CoreVMFunction_sort::exec(VMFnArgs* args) {
471 VMIntArrayExpr* a = args->arg(0)->asIntArray();
472 bool bAscending =
473 (args->argsCount() < 2) ? true : !args->arg(1)->asInt()->evalInt();
474 int n = a->arraySize();
475 ArrExprIter itBegin(a, 0);
476 ArrExprIter itEnd(a, n);
477 if (bAscending) {
478 std::sort(itBegin, itEnd);
479 } else {
480 DescArrExprSorter sorter;
481 std::sort(itBegin, itEnd, sorter);
482 }
483 return successResult();
484 }
485
486 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC