/[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 3345 - (hide annotations) (download)
Thu Aug 10 13:18:06 2017 UTC (6 years, 8 months ago) by schoenebeck
File size: 14958 byte(s)
* Fixed compilation error with clang libc++.

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

  ViewVC Help
Powered by ViewVC