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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3577 - (hide annotations) (download)
Wed Aug 28 15:23:23 2019 UTC (4 years, 7 months ago) by schoenebeck
File size: 20983 byte(s)
NKSP: Introducing variable return type for built-in functions.

* Changed method signature VMFunction::returnType() ->
  VMFunction::returnType(VMFnArgs* args) to allow built-in
  functions to proclaim a different result value type depending
  on the arguments to be passed to the function.

* Built-in script function abs() optionally accepts and returns
  real number.

* Built-in script functions min() and max() optionally accept
  real number arguments and return real number as result in that
  case.

* Added real number test cases for the built-in abs(), min() and
  max() functions.

* Bumped version (2.1.1.svn7).

1 schoenebeck 2581 /*
2 schoenebeck 3551 * Copyright (c) 2014-2019 Christian Schoenebeck
3 schoenebeck 2581 *
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 schoenebeck 3221 #include <algorithm> // for std::sort()
14 schoenebeck 2619 #include <math.h>
15     #include <stdlib.h>
16 schoenebeck 2581 #include "tree.h"
17     #include "ScriptVM.h"
18 schoenebeck 3285 #include "../common/RTMath.h"
19 schoenebeck 2581
20     namespace LinuxSampler {
21    
22 schoenebeck 2727 ///////////////////////////////////////////////////////////////////////////
23     // class VMEmptyResultFunction
24    
25 schoenebeck 2581 VMFnResult* VMEmptyResultFunction::errorResult() {
26     result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
27     return &result;
28     }
29    
30 schoenebeck 2598 VMFnResult* VMEmptyResultFunction::successResult() {
31     result.flags = STMT_SUCCESS;
32     return &result;
33 schoenebeck 2596 }
34    
35 schoenebeck 2727 ///////////////////////////////////////////////////////////////////////////
36     // class VMIntResultFunction
37    
38 schoenebeck 3557 VMFnResult* VMIntResultFunction::errorResult(vmint i) {
39 schoenebeck 2598 result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
40     result.value = i;
41     return &result;
42 schoenebeck 2596 }
43    
44 schoenebeck 3557 VMFnResult* VMIntResultFunction::successResult(vmint i) {
45 schoenebeck 2581 result.flags = STMT_SUCCESS;
46 schoenebeck 2598 result.value = i;
47 schoenebeck 2581 return &result;
48     }
49    
50 schoenebeck 2727 ///////////////////////////////////////////////////////////////////////////
51 schoenebeck 3573 // class VMRealResultFunction
52    
53     VMFnResult* VMRealResultFunction::errorResult(vmfloat f) {
54     result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
55     result.value = f;
56     return &result;
57     }
58    
59     VMFnResult* VMRealResultFunction::successResult(vmfloat f) {
60     result.flags = STMT_SUCCESS;
61     result.value = f;
62     return &result;
63     }
64    
65     ///////////////////////////////////////////////////////////////////////////
66 schoenebeck 2727 // class VMStringResultFunction
67    
68 schoenebeck 2581 VMFnResult* VMStringResultFunction::errorResult(const String& s) {
69     result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
70     result.value = s;
71     return &result;
72     }
73    
74     VMFnResult* VMStringResultFunction::successResult(const String& s) {
75     result.flags = STMT_SUCCESS;
76     result.value = s;
77     return &result;
78     }
79    
80 schoenebeck 2727 ///////////////////////////////////////////////////////////////////////////
81 schoenebeck 3577 // class VMScalarNumberResultFunction
82    
83     VMFnResult* VMScalarNumberResultFunction::errorResult(vmint i) {
84     intResult.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
85     intResult.value = i;
86     return &intResult;
87     }
88    
89     VMFnResult* VMScalarNumberResultFunction::errorResult(vmfloat f) {
90     realResult.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
91     realResult.value = f;
92     return &realResult;
93     }
94    
95     VMFnResult* VMScalarNumberResultFunction::successResult(vmint i) {
96     intResult.flags = STMT_SUCCESS;
97     intResult.value = i;
98     return &intResult;
99     }
100    
101     VMFnResult* VMScalarNumberResultFunction::successResult(vmfloat f) {
102     realResult.flags = STMT_SUCCESS;
103     realResult.value = f;
104     return &realResult;
105     }
106    
107     ///////////////////////////////////////////////////////////////////////////
108 schoenebeck 2727 // built-in script function: message()
109    
110 schoenebeck 3557 bool CoreVMFunction_message::acceptsArgType(vmint iArg, ExprType_t type) const {
111 schoenebeck 3573 return type == INT_EXPR || type == REAL_EXPR || type == STRING_EXPR;
112 schoenebeck 2581 }
113    
114     VMFnResult* CoreVMFunction_message::exec(VMFnArgs* args) {
115     if (!args->argsCount()) return errorResult();
116    
117 schoenebeck 3285 uint64_t usecs = RTMath::unsafeMicroSeconds(RTMath::real_clock);
118    
119 schoenebeck 2581 VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(args->arg(0));
120     if (strExpr) {
121 schoenebeck 3285 printf("[ScriptVM %.3f] %s\n", usecs/1000000.f, strExpr->evalStr().c_str());
122 schoenebeck 2581 return successResult();
123     }
124    
125 schoenebeck 3573 VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(args->arg(0));
126     if (realExpr) {
127     printf("[ScriptVM %.3f] %f\n", usecs/1000000.f, realExpr->evalReal());
128     return successResult();
129     }
130    
131 schoenebeck 2581 VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(args->arg(0));
132     if (intExpr) {
133 schoenebeck 3557 printf("[ScriptVM %.3f] %lld\n", usecs/1000000.f, (int64_t)intExpr->evalInt());
134 schoenebeck 2581 return successResult();
135     }
136    
137     return errorResult();
138     }
139    
140 schoenebeck 2727 ///////////////////////////////////////////////////////////////////////////
141     // built-in script function: exit()
142    
143 schoenebeck 3557 vmint CoreVMFunction_exit::maxAllowedArgs() const {
144 schoenebeck 3551 return (vm->isExitResultEnabled()) ? 1 : 0;
145     }
146    
147 schoenebeck 3557 bool CoreVMFunction_exit::acceptsArgType(vmint iArg, ExprType_t type) const {
148 schoenebeck 3551 if (!vm->isExitResultEnabled()) return false;
149 schoenebeck 3575 return type == INT_EXPR || type == REAL_EXPR || type == STRING_EXPR;
150 schoenebeck 3551 }
151    
152 schoenebeck 2581 VMFnResult* CoreVMFunction_exit::exec(VMFnArgs* args) {
153     this->result.flags = STMT_ABORT_SIGNALLED;
154 schoenebeck 3551 if (vm->isExitResultEnabled() && args->argsCount()) {
155     ExecContext* ctx = dynamic_cast<ExecContext*>(vm->currentVMExecContext());
156     switch (args->arg(0)->exprType()) {
157     case INT_EXPR:
158     ctx->exitRes.intLiteral.value = args->arg(0)->asInt()->evalInt();
159     ctx->exitRes.value = &ctx->exitRes.intLiteral;
160     break;
161 schoenebeck 3575 case REAL_EXPR:
162     ctx->exitRes.realLiteral.value = args->arg(0)->asReal()->evalReal();
163     ctx->exitRes.value = &ctx->exitRes.realLiteral;
164     break;
165 schoenebeck 3551 case STRING_EXPR:
166     ctx->exitRes.stringLiteral.value = args->arg(0)->asString()->evalStr();
167     ctx->exitRes.value = &ctx->exitRes.stringLiteral;
168     break;
169     default:
170     ; // noop - just to shut up the compiler
171     }
172     }
173 schoenebeck 2581 return &result;
174     }
175    
176 schoenebeck 2727 ///////////////////////////////////////////////////////////////////////////
177     // built-in script function: wait()
178    
179 schoenebeck 3561 bool CoreVMFunction_wait::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {
180     if (iArg == 0)
181     return type == VM_NO_UNIT || type == VM_SECOND;
182     else
183     return type == VM_NO_UNIT;
184     }
185    
186 schoenebeck 3564 bool CoreVMFunction_wait::acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const {
187     return iArg == 0 && type == VM_SECOND;
188 schoenebeck 3561 }
189    
190 schoenebeck 2581 VMFnResult* CoreVMFunction_wait::exec(VMFnArgs* args) {
191     ExecContext* ctx = dynamic_cast<ExecContext*>(vm->currentVMExecContext());
192     VMIntExpr* expr = dynamic_cast<VMIntExpr*>(args->arg(0));
193 schoenebeck 3564 StdUnit_t unit = expr->unitType();
194     vmint us = (unit) ? expr->evalInt(VM_MICRO) : expr->evalInt();
195 schoenebeck 2972 if (us < 0) {
196     wrnMsg("wait(): argument may not be negative! Aborting script!");
197     this->result.flags = STMT_ABORT_SIGNALLED;
198     } else if (us == 0) {
199     wrnMsg("wait(): argument may not be zero! Aborting script!");
200     this->result.flags = STMT_ABORT_SIGNALLED;
201     } else {
202     ctx->suspendMicroseconds = us;
203     this->result.flags = STMT_SUSPEND_SIGNALLED;
204     }
205 schoenebeck 2581 return &result;
206     }
207    
208 schoenebeck 2727 ///////////////////////////////////////////////////////////////////////////
209     // built-in script function: abs()
210    
211 schoenebeck 3577 ExprType_t CoreVMFunction_abs::returnType(VMFnArgs* args) {
212     return args->arg(0)->exprType();
213     }
214    
215 schoenebeck 3557 bool CoreVMFunction_abs::acceptsArgType(vmint iArg, ExprType_t type) const {
216 schoenebeck 3577 return type == INT_EXPR || type == REAL_EXPR;
217 schoenebeck 2619 }
218    
219     VMFnResult* CoreVMFunction_abs::exec(VMFnArgs* args) {
220 schoenebeck 3577 VMExpr* arg = args->arg(0);
221     if (arg->exprType() == REAL_EXPR)
222     return successResult( ::fabs(arg->asReal()->evalReal()) );
223     else
224     return successResult( ::abs(arg->asInt()->evalInt()) );
225 schoenebeck 2619 }
226    
227 schoenebeck 2727 ///////////////////////////////////////////////////////////////////////////
228     // built-in script function: random()
229    
230 schoenebeck 3557 bool CoreVMFunction_random::acceptsArgType(vmint iArg, ExprType_t type) const {
231 schoenebeck 2619 return type == INT_EXPR;
232     }
233    
234     VMFnResult* CoreVMFunction_random::exec(VMFnArgs* args) {
235 schoenebeck 3557 vmint iMin = args->arg(0)->asInt()->evalInt();
236     vmint iMax = args->arg(1)->asInt()->evalInt();
237 schoenebeck 2620 float f = float(::rand()) / float(RAND_MAX);
238 schoenebeck 2619 return successResult(
239     iMin + roundf( f * float(iMax - iMin) )
240     );
241     }
242    
243 schoenebeck 2727 ///////////////////////////////////////////////////////////////////////////
244     // built-in script function: num_elements()
245    
246 schoenebeck 3557 bool CoreVMFunction_num_elements::acceptsArgType(vmint iArg, ExprType_t type) const {
247 schoenebeck 2619 return type == INT_ARR_EXPR;
248     }
249    
250     VMFnResult* CoreVMFunction_num_elements::exec(VMFnArgs* args) {
251     return successResult( args->arg(0)->asIntArray()->arraySize() );
252     }
253    
254 schoenebeck 2945 ///////////////////////////////////////////////////////////////////////////
255     // built-in script function: inc()
256    
257     VMFnResult* CoreVMFunction_inc::exec(VMFnArgs* args) {
258     VMExpr* arg = args->arg(0);
259     VMIntExpr* in = dynamic_cast<VMIntExpr*>(arg);
260     VMVariable* out = dynamic_cast<VMVariable*>(arg);
261     if (!in || !out) successResult(0);
262 schoenebeck 3557 vmint i = in->evalInt() + 1;
263 schoenebeck 2945 IntLiteral tmp(i);
264     out->assignExpr(&tmp);
265     return successResult(i);
266     }
267    
268     ///////////////////////////////////////////////////////////////////////////
269     // built-in script function: dec()
270    
271     VMFnResult* CoreVMFunction_dec::exec(VMFnArgs* args) {
272     VMExpr* arg = args->arg(0);
273     VMIntExpr* in = dynamic_cast<VMIntExpr*>(arg);
274     VMVariable* out = dynamic_cast<VMVariable*>(arg);
275     if (!in || !out) successResult(0);
276 schoenebeck 3557 vmint i = in->evalInt() - 1;
277 schoenebeck 2945 IntLiteral tmp(i);
278     out->assignExpr(&tmp);
279     return successResult(i);
280     }
281    
282 schoenebeck 2965 ///////////////////////////////////////////////////////////////////////////
283 schoenebeck 3076 // built-in script function: in_range()
284    
285     VMFnResult* CoreVMFunction_in_range::exec(VMFnArgs* args) {
286 schoenebeck 3557 vmint i = args->arg(0)->asInt()->evalInt();
287     vmint lo = args->arg(1)->asInt()->evalInt();
288     vmint hi = args->arg(2)->asInt()->evalInt();
289 schoenebeck 3076 if (lo > hi) { // swap lo and hi
290 schoenebeck 3557 vmint tmp = lo;
291 schoenebeck 3076 lo = hi;
292     hi = tmp;
293     }
294     return successResult(i >= lo && i <= hi);
295     }
296    
297     ///////////////////////////////////////////////////////////////////////////
298 schoenebeck 2965 // built-in script function: sh_left()
299    
300     VMFnResult* CoreVMFunction_sh_left::exec(VMFnArgs* args) {
301 schoenebeck 3557 vmint i = args->arg(0)->asInt()->evalInt();
302     vmint n = args->arg(1)->asInt()->evalInt();
303 schoenebeck 2965 return successResult(i << n);
304     }
305    
306     ///////////////////////////////////////////////////////////////////////////
307     // built-in script function: sh_right()
308    
309     VMFnResult* CoreVMFunction_sh_right::exec(VMFnArgs* args) {
310 schoenebeck 3557 vmint i = args->arg(0)->asInt()->evalInt();
311     vmint n = args->arg(1)->asInt()->evalInt();
312 schoenebeck 2965 return successResult(i >> n);
313     }
314    
315 schoenebeck 2970 ///////////////////////////////////////////////////////////////////////////
316     // built-in script function: min()
317    
318 schoenebeck 3577 ExprType_t CoreVMFunction_min::returnType(VMFnArgs* args) {
319     return (args->arg(0)->exprType() == REAL_EXPR ||
320     args->arg(1)->exprType() == REAL_EXPR) ? REAL_EXPR : INT_EXPR;
321     }
322    
323     bool CoreVMFunction_min::acceptsArgType(vmint iArg, ExprType_t type) const {
324     return type == INT_EXPR || type == REAL_EXPR;
325     }
326    
327 schoenebeck 2970 VMFnResult* CoreVMFunction_min::exec(VMFnArgs* args) {
328 schoenebeck 3577 VMExpr* a = args->arg(0);
329     VMExpr* b = args->arg(1);
330     if (a->exprType() == REAL_EXPR && b->exprType() == REAL_EXPR) {
331     vmfloat l = a->asReal()->evalReal();
332     vmfloat r = b->asReal()->evalReal();
333     return successResult(l < r ? l : r);
334     } else if (a->exprType() == REAL_EXPR && b->exprType() == INT_EXPR) {
335     vmfloat l = a->asReal()->evalReal();
336     vmint r = b->asInt()->evalInt();
337     return successResult(l < r ? l : r);
338     } else if (a->exprType() == INT_EXPR && b->exprType() == REAL_EXPR) {
339     vmint l = a->asInt()->evalInt();
340     vmfloat r = b->asReal()->evalReal();
341     return successResult(l < r ? l : r);
342     } else {
343     vmint l = a->asInt()->evalInt();
344     vmint r = b->asInt()->evalInt();
345     return successResult(l < r ? l : r);
346     }
347 schoenebeck 2970 }
348    
349     ///////////////////////////////////////////////////////////////////////////
350     // built-in script function: max()
351    
352 schoenebeck 3577 ExprType_t CoreVMFunction_max::returnType(VMFnArgs* args) {
353     return (args->arg(0)->exprType() == REAL_EXPR ||
354     args->arg(1)->exprType() == REAL_EXPR) ? REAL_EXPR : INT_EXPR;
355     }
356    
357     bool CoreVMFunction_max::acceptsArgType(vmint iArg, ExprType_t type) const {
358     return type == INT_EXPR || type == REAL_EXPR;
359     }
360    
361 schoenebeck 2970 VMFnResult* CoreVMFunction_max::exec(VMFnArgs* args) {
362 schoenebeck 3577 VMExpr* a = args->arg(0);
363     VMExpr* b = args->arg(1);
364     if (a->exprType() == REAL_EXPR && b->exprType() == REAL_EXPR) {
365     vmfloat l = a->asReal()->evalReal();
366     vmfloat r = b->asReal()->evalReal();
367     return successResult(l > r ? l : r);
368     } else if (a->exprType() == REAL_EXPR && b->exprType() == INT_EXPR) {
369     vmfloat l = a->asReal()->evalReal();
370     vmint r = b->asInt()->evalInt();
371     return successResult(l > r ? l : r);
372     } else if (a->exprType() == INT_EXPR && b->exprType() == REAL_EXPR) {
373     vmint l = a->asInt()->evalInt();
374     vmfloat r = b->asReal()->evalReal();
375     return successResult(l > r ? l : r);
376     } else {
377     vmint l = a->asInt()->evalInt();
378     vmint r = b->asInt()->evalInt();
379     return successResult(l > r ? l : r);
380     }
381 schoenebeck 2970 }
382    
383 schoenebeck 3221 ///////////////////////////////////////////////////////////////////////////
384     // built-in script function: array_equal()
385    
386     VMFnResult* CoreVMFunction_array_equal::exec(VMFnArgs* args) {
387     VMIntArrayExpr* l = args->arg(0)->asIntArray();
388     VMIntArrayExpr* r = args->arg(1)->asIntArray();
389     if (l->arraySize() != r->arraySize()) {
390     wrnMsg("array_equal(): the two arrays differ in size");
391     return successResult(0); // false
392     }
393 schoenebeck 3557 const vmint n = l->arraySize();
394     for (vmint i = 0; i < n; ++i)
395 schoenebeck 3221 if (l->evalIntElement(i) != r->evalIntElement(i))
396     return successResult(0); // false
397     return successResult(1); // true
398     }
399    
400     ///////////////////////////////////////////////////////////////////////////
401     // built-in script function: search()
402    
403 schoenebeck 3557 ExprType_t CoreVMFunction_search::argType(vmint iArg) const {
404 schoenebeck 3221 return (iArg == 0) ? INT_ARR_EXPR : INT_EXPR;
405     }
406    
407 schoenebeck 3557 bool CoreVMFunction_search::acceptsArgType(vmint iArg, ExprType_t type) const {
408 schoenebeck 3221 if (iArg == 0)
409     return type == INT_ARR_EXPR;
410     else
411     return type == INT_EXPR;
412     }
413    
414     VMFnResult* CoreVMFunction_search::exec(VMFnArgs* args) {
415     VMIntArrayExpr* a = args->arg(0)->asIntArray();
416 schoenebeck 3557 const vmint needle = args->arg(1)->asInt()->evalInt();
417     const vmint n = a->arraySize();
418     for (vmint i = 0; i < n; ++i)
419 schoenebeck 3221 if (a->evalIntElement(i) == needle)
420     return successResult(i);
421     return successResult(-1); // not found
422     }
423    
424     ///////////////////////////////////////////////////////////////////////////
425     // built-in script function: sort()
426    
427 schoenebeck 3557 ExprType_t CoreVMFunction_sort::argType(vmint iArg) const {
428 schoenebeck 3221 return (iArg == 0) ? INT_ARR_EXPR : INT_EXPR;
429     }
430    
431 schoenebeck 3557 bool CoreVMFunction_sort::acceptsArgType(vmint iArg, ExprType_t type) const {
432 schoenebeck 3221 if (iArg == 0)
433     return type == INT_ARR_EXPR;
434     else
435     return type == INT_EXPR;
436     }
437    
438     struct ArrElemPOD {
439     VMIntArrayExpr* m_array;
440 schoenebeck 3557 vmint m_index;
441 schoenebeck 3221 };
442    
443 schoenebeck 3222 static inline void swap(class ArrElemRef a, class ArrElemRef b);
444 schoenebeck 3221
445     class ArrElemRef : protected ArrElemPOD {
446     public:
447     ArrElemRef() {
448     m_array = NULL;
449     m_index = 0;
450     }
451 schoenebeck 3557 ArrElemRef(VMIntArrayExpr* a, vmint index) {
452 schoenebeck 3221 m_array = a;
453     m_index = index;
454     }
455     inline ArrElemRef& operator=(const ArrElemRef& e) {
456     setValue(e.getValue());
457     return *this;
458     }
459 schoenebeck 3557 inline ArrElemRef& operator=(vmint val) {
460 schoenebeck 3221 setValue(val);
461     return *this;
462     }
463     inline bool operator==(const ArrElemRef& e) const {
464     if (m_index == e.m_index)
465     return true;
466     return getValue() == e.getValue();
467     }
468 schoenebeck 3557 inline bool operator==(vmint val) const {
469 schoenebeck 3221 return getValue() == val;
470     }
471     inline bool operator!=(const ArrElemRef& e) const {
472     return !(operator==(e));
473     }
474 schoenebeck 3557 inline bool operator!=(vmint val) const {
475 schoenebeck 3221 return !(operator==(val));
476     }
477     inline bool operator<(const ArrElemRef& e) const {
478     if (m_index == e.m_index)
479     return false;
480     return getValue() < e.getValue();
481     }
482 schoenebeck 3557 inline bool operator<(vmint val) const {
483 schoenebeck 3221 return getValue() < val;
484     }
485     inline bool operator>(const ArrElemRef& e) const {
486     if (m_index == e.m_index)
487     return false;
488     return getValue() > e.getValue();
489     }
490 schoenebeck 3557 inline bool operator>(vmint val) const {
491 schoenebeck 3221 return getValue() > val;
492     }
493     inline bool operator<=(const ArrElemRef& e) const {
494     if (m_index == e.m_index)
495     return true;
496     return getValue() <= e.getValue();
497     }
498 schoenebeck 3557 inline bool operator<=(vmint val) const {
499 schoenebeck 3221 return getValue() <= val;
500     }
501     inline bool operator>=(const ArrElemRef& e) const {
502     if (m_index == e.m_index)
503     return true;
504     return getValue() >= e.getValue();
505     }
506 schoenebeck 3557 inline bool operator>=(vmint val) const {
507 schoenebeck 3221 return getValue() >= val;
508     }
509 schoenebeck 3557 inline operator vmint() const {
510 schoenebeck 3221 return getValue();
511     }
512     protected:
513 schoenebeck 3557 inline vmint getValue() const {
514 schoenebeck 3221 return m_array->evalIntElement(m_index);
515     }
516 schoenebeck 3557 inline void setValue(vmint value) {
517 schoenebeck 3221 m_array->assignIntElement(m_index, value);
518     }
519    
520 schoenebeck 3222 friend void swap(class ArrElemRef a, class ArrElemRef b);
521 schoenebeck 3221 };
522    
523     class ArrElemPtr : protected ArrElemPOD {
524     public:
525     ArrElemPtr() {
526     m_array = NULL;
527     m_index = 0;
528     }
529 schoenebeck 3557 ArrElemPtr(VMIntArrayExpr* a, vmint index) {
530 schoenebeck 3221 m_array = a;
531     m_index = index;
532     }
533     inline ArrElemRef operator*() {
534     return *(ArrElemRef*)this;
535     }
536     };
537    
538 schoenebeck 3222 static inline void swap(ArrElemRef a, ArrElemRef b) {
539 schoenebeck 3557 vmint valueA = a.getValue();
540     vmint valueB = b.getValue();
541 schoenebeck 3221 a.setValue(valueB);
542     b.setValue(valueA);
543     }
544    
545     class ArrExprIter : public ArrElemPOD {
546     public:
547     typedef std::random_access_iterator_tag iterator_category;
548 schoenebeck 3557 typedef vmint value_type;
549 schoenebeck 3221 typedef ssize_t difference_type;
550     typedef ArrElemPtr pointer;
551     typedef ArrElemRef reference;
552    
553 schoenebeck 3557 ArrExprIter(VMIntArrayExpr* a, vmint index) {
554 schoenebeck 3221 m_array = a;
555     m_index = index;
556     }
557     inline ArrElemRef operator*() {
558     return *(ArrElemRef*)this;
559     }
560     inline ArrExprIter& operator++() { // prefix increment
561     ++m_index;
562     return *this;
563     }
564     inline ArrExprIter& operator--() { // prefix decrement
565     --m_index;
566     return *this;
567     }
568     inline ArrExprIter operator++(int) { // postfix increment
569     ArrExprIter it = *this;
570     ++m_index;
571     return it;
572     }
573     inline ArrExprIter operator--(int) { // postfix decrement
574     ArrExprIter it = *this;
575     --m_index;
576     return it;
577     }
578 schoenebeck 3345 inline ArrExprIter& operator+=(difference_type d) {
579     m_index += d;
580     return *this;
581     }
582     inline ArrExprIter& operator-=(difference_type d) {
583     m_index -= d;
584     return *this;
585     }
586 schoenebeck 3221 inline bool operator==(const ArrExprIter& other) const {
587     return m_index == other.m_index;
588     }
589     inline bool operator!=(const ArrExprIter& other) const {
590     return m_index != other.m_index;
591     }
592     inline bool operator<(const ArrExprIter& other) const {
593     return m_index < other.m_index;
594     }
595     inline bool operator>(const ArrExprIter& other) const {
596     return m_index > other.m_index;
597     }
598     inline bool operator<=(const ArrExprIter& other) const {
599     return m_index <= other.m_index;
600     }
601     inline bool operator>=(const ArrExprIter& other) const {
602     return m_index >= other.m_index;
603     }
604     inline difference_type operator+(const ArrExprIter& other) const {
605     return m_index + other.m_index;
606     }
607     inline difference_type operator-(const ArrExprIter& other) const {
608     return m_index - other.m_index;
609     }
610     inline ArrExprIter operator-(difference_type d) const {
611     return ArrExprIter(m_array, m_index - d);
612     }
613     inline ArrExprIter operator+(difference_type d) const {
614     return ArrExprIter(m_array, m_index + d);
615     }
616     inline ArrExprIter operator*(difference_type factor) const {
617     return ArrExprIter(m_array, m_index * factor);
618     }
619     };
620    
621     struct DescArrExprSorter {
622 schoenebeck 3557 inline bool operator()(const vmint& a, const vmint& b) const {
623 schoenebeck 3221 return a > b;
624     }
625     };
626    
627     VMFnResult* CoreVMFunction_sort::exec(VMFnArgs* args) {
628     VMIntArrayExpr* a = args->arg(0)->asIntArray();
629     bool bAscending =
630     (args->argsCount() < 2) ? true : !args->arg(1)->asInt()->evalInt();
631 schoenebeck 3557 vmint n = a->arraySize();
632 schoenebeck 3221 ArrExprIter itBegin(a, 0);
633     ArrExprIter itEnd(a, n);
634     if (bAscending) {
635     std::sort(itBegin, itEnd);
636     } else {
637     DescArrExprSorter sorter;
638     std::sort(itBegin, itEnd, sorter);
639     }
640     return successResult();
641     }
642    
643 schoenebeck 3573 ///////////////////////////////////////////////////////////////////////////
644     // built-in script function: real_to_int() and int()
645    
646     VMFnResult* CoreVMFunction_real_to_int::exec(VMFnArgs* args) {
647     vmfloat f = args->arg(0)->asReal()->evalReal();
648     return successResult(vmint(f));
649     }
650    
651     ///////////////////////////////////////////////////////////////////////////
652     // built-in script function: int_to_real() and real()
653    
654     VMFnResult* CoreVMFunction_int_to_real::exec(VMFnArgs* args) {
655     vmint i = args->arg(0)->asInt()->evalInt();
656     return successResult(i);
657     }
658    
659 schoenebeck 2581 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC