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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2619 by schoenebeck, Wed Jun 11 13:24:32 2014 UTC revision 3222 by schoenebeck, Fri May 26 18:55:45 2017 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (c) 2014 Christian Schoenebeck   * Copyright (c) 2014-2017 Christian Schoenebeck
3   *   *
4   * http://www.linuxsampler.org   * http://www.linuxsampler.org
5   *   *
# Line 10  Line 10 
10  #include "CoreVMFunctions.h"  #include "CoreVMFunctions.h"
11    
12  #include <iostream>  #include <iostream>
13    #include <algorithm> // for std::sort()
14  #include <math.h>  #include <math.h>
15  #include <stdlib.h>  #include <stdlib.h>
16  #include "tree.h"  #include "tree.h"
# Line 17  Line 18 
18    
19  namespace LinuxSampler {  namespace LinuxSampler {
20    
21    ///////////////////////////////////////////////////////////////////////////
22    // class VMEmptyResultFunction
23    
24  VMFnResult* VMEmptyResultFunction::errorResult() {  VMFnResult* VMEmptyResultFunction::errorResult() {
25      result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);      result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
26      return &result;      return &result;
# Line 27  VMFnResult* VMEmptyResultFunction::succe Line 31  VMFnResult* VMEmptyResultFunction::succe
31      return &result;      return &result;
32  }  }
33    
34    ///////////////////////////////////////////////////////////////////////////
35    // class VMIntResultFunction
36    
37  VMFnResult* VMIntResultFunction::errorResult(int i) {  VMFnResult* VMIntResultFunction::errorResult(int i) {
38      result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);      result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
39      result.value = i;      result.value = i;
# Line 39  VMFnResult* VMIntResultFunction::success Line 46  VMFnResult* VMIntResultFunction::success
46      return &result;      return &result;
47  }  }
48    
49    ///////////////////////////////////////////////////////////////////////////
50    // class VMStringResultFunction
51    
52  VMFnResult* VMStringResultFunction::errorResult(const String& s) {  VMFnResult* VMStringResultFunction::errorResult(const String& s) {
53      result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);      result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
54      result.value = s;      result.value = s;
# Line 51  VMFnResult* VMStringResultFunction::succ Line 61  VMFnResult* VMStringResultFunction::succ
61      return &result;      return &result;
62  }  }
63    
64    ///////////////////////////////////////////////////////////////////////////
65    // built-in script function:  message()
66    
67  bool CoreVMFunction_message::acceptsArgType(int iArg, ExprType_t type) const {  bool CoreVMFunction_message::acceptsArgType(int iArg, ExprType_t type) const {
68      return type == INT_EXPR || type == STRING_EXPR;      return type == INT_EXPR || type == STRING_EXPR;
69  }  }
# Line 73  VMFnResult* CoreVMFunction_message::exec Line 86  VMFnResult* CoreVMFunction_message::exec
86      return errorResult();      return errorResult();
87  }  }
88    
89    ///////////////////////////////////////////////////////////////////////////
90    // built-in script function:  exit()
91    
92  VMFnResult* CoreVMFunction_exit::exec(VMFnArgs* args) {  VMFnResult* CoreVMFunction_exit::exec(VMFnArgs* args) {
93      this->result.flags = STMT_ABORT_SIGNALLED;      this->result.flags = STMT_ABORT_SIGNALLED;
94      return &result;      return &result;
95  }  }
96    
97    ///////////////////////////////////////////////////////////////////////////
98    // built-in script function:  wait()
99    
100  VMFnResult* CoreVMFunction_wait::exec(VMFnArgs* args) {  VMFnResult* CoreVMFunction_wait::exec(VMFnArgs* args) {
101      ExecContext* ctx = dynamic_cast<ExecContext*>(vm->currentVMExecContext());      ExecContext* ctx = dynamic_cast<ExecContext*>(vm->currentVMExecContext());
102      VMIntExpr* expr = dynamic_cast<VMIntExpr*>(args->arg(0));      VMIntExpr* expr = dynamic_cast<VMIntExpr*>(args->arg(0));
103      ctx->suspendMicroseconds = expr->evalInt();      int us = expr->evalInt();
104      this->result.flags = STMT_SUSPEND_SIGNALLED;      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;      return &result;
115  }  }
116    
117    ///////////////////////////////////////////////////////////////////////////
118    // built-in script function:  abs()
119    
120  bool CoreVMFunction_abs::acceptsArgType(int iArg, ExprType_t type) const {  bool CoreVMFunction_abs::acceptsArgType(int iArg, ExprType_t type) const {
121      return type == INT_EXPR;      return type == INT_EXPR;
122  }  }
# Line 94  VMFnResult* CoreVMFunction_abs::exec(VMF Line 125  VMFnResult* CoreVMFunction_abs::exec(VMF
125      return successResult( ::abs(args->arg(0)->asInt()->evalInt()) );      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 {  bool CoreVMFunction_random::acceptsArgType(int iArg, ExprType_t type) const {
132      return type == INT_EXPR;      return type == INT_EXPR;
133  }  }
# Line 101  bool CoreVMFunction_random::acceptsArgTy Line 135  bool CoreVMFunction_random::acceptsArgTy
135  VMFnResult* CoreVMFunction_random::exec(VMFnArgs* args) {  VMFnResult* CoreVMFunction_random::exec(VMFnArgs* args) {
136      int iMin = args->arg(0)->asInt()->evalInt();      int iMin = args->arg(0)->asInt()->evalInt();
137      int iMax = args->arg(1)->asInt()->evalInt();      int iMax = args->arg(1)->asInt()->evalInt();
138      float f = float(::random()) / float(RAND_MAX);      float f = float(::rand()) / float(RAND_MAX);
139      return successResult(      return successResult(
140          iMin + roundf( f * float(iMax - iMin) )          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 {  bool CoreVMFunction_num_elements::acceptsArgType(int iArg, ExprType_t type) const {
148      return type == INT_ARR_EXPR;      return type == INT_ARR_EXPR;
149  }  }
# Line 115  VMFnResult* CoreVMFunction_num_elements: Line 152  VMFnResult* CoreVMFunction_num_elements:
152      return successResult( args->arg(0)->asIntArray()->arraySize() );      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  } // namespace LinuxSampler

Legend:
Removed from v.2619  
changed lines
  Added in v.3222

  ViewVC Help
Powered by ViewVC