/[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 2972 by schoenebeck, Fri Jul 22 14:37:34 2016 UTC revision 3564 by schoenebeck, Sat Aug 24 09:18:57 2019 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (c) 2014-2015 Christian Schoenebeck   * Copyright (c) 2014-2019 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"
17  #include "ScriptVM.h"  #include "ScriptVM.h"
18    #include "../common/RTMath.h"
19    
20  namespace LinuxSampler {  namespace LinuxSampler {
21    
# Line 33  VMFnResult* VMEmptyResultFunction::succe Line 35  VMFnResult* VMEmptyResultFunction::succe
35  ///////////////////////////////////////////////////////////////////////////  ///////////////////////////////////////////////////////////////////////////
36  // class VMIntResultFunction  // class VMIntResultFunction
37    
38  VMFnResult* VMIntResultFunction::errorResult(int i) {  VMFnResult* VMIntResultFunction::errorResult(vmint i) {
39      result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);      result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
40      result.value = i;      result.value = i;
41      return &result;      return &result;
42  }  }
43    
44  VMFnResult* VMIntResultFunction::successResult(int i) {  VMFnResult* VMIntResultFunction::successResult(vmint i) {
45      result.flags = STMT_SUCCESS;      result.flags = STMT_SUCCESS;
46      result.value = i;      result.value = i;
47      return &result;      return &result;
# Line 63  VMFnResult* VMStringResultFunction::succ Line 65  VMFnResult* VMStringResultFunction::succ
65  ///////////////////////////////////////////////////////////////////////////  ///////////////////////////////////////////////////////////////////////////
66  // built-in script function:  message()  // built-in script function:  message()
67    
68  bool CoreVMFunction_message::acceptsArgType(int iArg, ExprType_t type) const {  bool CoreVMFunction_message::acceptsArgType(vmint iArg, ExprType_t type) const {
69      return type == INT_EXPR || type == STRING_EXPR;      return type == INT_EXPR || type == STRING_EXPR;
70  }  }
71    
72  VMFnResult* CoreVMFunction_message::exec(VMFnArgs* args) {  VMFnResult* CoreVMFunction_message::exec(VMFnArgs* args) {
73      if (!args->argsCount()) return errorResult();      if (!args->argsCount()) return errorResult();
74    
75        uint64_t usecs = RTMath::unsafeMicroSeconds(RTMath::real_clock);
76    
77      VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(args->arg(0));      VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(args->arg(0));
78      if (strExpr) {      if (strExpr) {
79          std::cout << "[ScriptVM] " << strExpr->evalStr() << "\n";          printf("[ScriptVM %.3f] %s\n", usecs/1000000.f, strExpr->evalStr().c_str());
80          return successResult();          return successResult();
81      }      }
82    
83      VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(args->arg(0));      VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(args->arg(0));
84      if (intExpr) {      if (intExpr) {
85          std::cout << "[ScriptVM] " << intExpr->evalInt() << "\n";          printf("[ScriptVM %.3f] %lld\n", usecs/1000000.f, (int64_t)intExpr->evalInt());
86          return successResult();          return successResult();
87      }      }
88    
# Line 88  VMFnResult* CoreVMFunction_message::exec Line 92  VMFnResult* CoreVMFunction_message::exec
92  ///////////////////////////////////////////////////////////////////////////  ///////////////////////////////////////////////////////////////////////////
93  // built-in script function:  exit()  // built-in script function:  exit()
94    
95    vmint CoreVMFunction_exit::maxAllowedArgs() const {
96        return (vm->isExitResultEnabled()) ? 1 : 0;
97    }
98    
99    bool CoreVMFunction_exit::acceptsArgType(vmint iArg, ExprType_t type) const {
100        if (!vm->isExitResultEnabled()) return false;
101        return type == INT_EXPR || type == STRING_EXPR;
102    }
103    
104  VMFnResult* CoreVMFunction_exit::exec(VMFnArgs* args) {  VMFnResult* CoreVMFunction_exit::exec(VMFnArgs* args) {
105      this->result.flags = STMT_ABORT_SIGNALLED;      this->result.flags = STMT_ABORT_SIGNALLED;
106        if (vm->isExitResultEnabled() && args->argsCount()) {
107            ExecContext* ctx = dynamic_cast<ExecContext*>(vm->currentVMExecContext());
108            switch (args->arg(0)->exprType()) {
109                case INT_EXPR:
110                    ctx->exitRes.intLiteral.value = args->arg(0)->asInt()->evalInt();
111                    ctx->exitRes.value = &ctx->exitRes.intLiteral;
112                    break;
113                case STRING_EXPR:
114                    ctx->exitRes.stringLiteral.value = args->arg(0)->asString()->evalStr();
115                    ctx->exitRes.value = &ctx->exitRes.stringLiteral;
116                    break;
117                default:
118                    ; // noop - just to shut up the compiler
119            }
120        }
121      return &result;      return &result;
122  }  }
123    
124  ///////////////////////////////////////////////////////////////////////////  ///////////////////////////////////////////////////////////////////////////
125  // built-in script function:  wait()  // built-in script function:  wait()
126    
127    bool CoreVMFunction_wait::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {
128        if (iArg == 0)
129            return type == VM_NO_UNIT || type == VM_SECOND;
130        else
131            return type == VM_NO_UNIT;
132    }
133    
134    bool CoreVMFunction_wait::acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const {
135        return iArg == 0 && type == VM_SECOND;
136    }
137    
138  VMFnResult* CoreVMFunction_wait::exec(VMFnArgs* args) {  VMFnResult* CoreVMFunction_wait::exec(VMFnArgs* args) {
139      ExecContext* ctx = dynamic_cast<ExecContext*>(vm->currentVMExecContext());      ExecContext* ctx = dynamic_cast<ExecContext*>(vm->currentVMExecContext());
140      VMIntExpr* expr = dynamic_cast<VMIntExpr*>(args->arg(0));      VMIntExpr* expr = dynamic_cast<VMIntExpr*>(args->arg(0));
141      int us = expr->evalInt();      StdUnit_t unit = expr->unitType();
142        vmint us = (unit) ? expr->evalInt(VM_MICRO) : expr->evalInt();
143      if (us < 0) {      if (us < 0) {
144          wrnMsg("wait(): argument may not be negative! Aborting script!");          wrnMsg("wait(): argument may not be negative! Aborting script!");
145          this->result.flags = STMT_ABORT_SIGNALLED;          this->result.flags = STMT_ABORT_SIGNALLED;
# Line 116  VMFnResult* CoreVMFunction_wait::exec(VM Line 156  VMFnResult* CoreVMFunction_wait::exec(VM
156  ///////////////////////////////////////////////////////////////////////////  ///////////////////////////////////////////////////////////////////////////
157  // built-in script function:  abs()  // built-in script function:  abs()
158    
159  bool CoreVMFunction_abs::acceptsArgType(int iArg, ExprType_t type) const {  bool CoreVMFunction_abs::acceptsArgType(vmint iArg, ExprType_t type) const {
160      return type == INT_EXPR;      return type == INT_EXPR;
161  }  }
162    
# Line 127  VMFnResult* CoreVMFunction_abs::exec(VMF Line 167  VMFnResult* CoreVMFunction_abs::exec(VMF
167  ///////////////////////////////////////////////////////////////////////////  ///////////////////////////////////////////////////////////////////////////
168  // built-in script function:  random()  // built-in script function:  random()
169    
170  bool CoreVMFunction_random::acceptsArgType(int iArg, ExprType_t type) const {  bool CoreVMFunction_random::acceptsArgType(vmint iArg, ExprType_t type) const {
171      return type == INT_EXPR;      return type == INT_EXPR;
172  }  }
173    
174  VMFnResult* CoreVMFunction_random::exec(VMFnArgs* args) {  VMFnResult* CoreVMFunction_random::exec(VMFnArgs* args) {
175      int iMin = args->arg(0)->asInt()->evalInt();      vmint iMin = args->arg(0)->asInt()->evalInt();
176      int iMax = args->arg(1)->asInt()->evalInt();      vmint iMax = args->arg(1)->asInt()->evalInt();
177      float f = float(::rand()) / float(RAND_MAX);      float f = float(::rand()) / float(RAND_MAX);
178      return successResult(      return successResult(
179          iMin + roundf( f * float(iMax - iMin) )          iMin + roundf( f * float(iMax - iMin) )
# Line 143  VMFnResult* CoreVMFunction_random::exec( Line 183  VMFnResult* CoreVMFunction_random::exec(
183  ///////////////////////////////////////////////////////////////////////////  ///////////////////////////////////////////////////////////////////////////
184  // built-in script function:  num_elements()  // built-in script function:  num_elements()
185    
186  bool CoreVMFunction_num_elements::acceptsArgType(int iArg, ExprType_t type) const {  bool CoreVMFunction_num_elements::acceptsArgType(vmint iArg, ExprType_t type) const {
187      return type == INT_ARR_EXPR;      return type == INT_ARR_EXPR;
188  }  }
189    
# Line 159  VMFnResult* CoreVMFunction_inc::exec(VMF Line 199  VMFnResult* CoreVMFunction_inc::exec(VMF
199      VMIntExpr* in = dynamic_cast<VMIntExpr*>(arg);      VMIntExpr* in = dynamic_cast<VMIntExpr*>(arg);
200      VMVariable* out = dynamic_cast<VMVariable*>(arg);      VMVariable* out = dynamic_cast<VMVariable*>(arg);
201      if (!in || !out) successResult(0);      if (!in || !out) successResult(0);
202      int i = in->evalInt() + 1;      vmint i = in->evalInt() + 1;
203      IntLiteral tmp(i);      IntLiteral tmp(i);
204      out->assignExpr(&tmp);      out->assignExpr(&tmp);
205      return successResult(i);      return successResult(i);
# Line 173  VMFnResult* CoreVMFunction_dec::exec(VMF Line 213  VMFnResult* CoreVMFunction_dec::exec(VMF
213      VMIntExpr* in = dynamic_cast<VMIntExpr*>(arg);      VMIntExpr* in = dynamic_cast<VMIntExpr*>(arg);
214      VMVariable* out = dynamic_cast<VMVariable*>(arg);      VMVariable* out = dynamic_cast<VMVariable*>(arg);
215      if (!in || !out) successResult(0);      if (!in || !out) successResult(0);
216      int i = in->evalInt() - 1;      vmint i = in->evalInt() - 1;
217      IntLiteral tmp(i);      IntLiteral tmp(i);
218      out->assignExpr(&tmp);      out->assignExpr(&tmp);
219      return successResult(i);      return successResult(i);
220  }  }
221    
222  ///////////////////////////////////////////////////////////////////////////  ///////////////////////////////////////////////////////////////////////////
223    // built-in script function:  in_range()
224    
225    VMFnResult* CoreVMFunction_in_range::exec(VMFnArgs* args) {
226        vmint i  = args->arg(0)->asInt()->evalInt();
227        vmint lo = args->arg(1)->asInt()->evalInt();
228        vmint hi = args->arg(2)->asInt()->evalInt();
229        if (lo > hi) { // swap lo and hi
230            vmint tmp = lo;
231            lo = hi;
232            hi = tmp;
233        }
234        return successResult(i >= lo && i <= hi);
235    }
236    
237    ///////////////////////////////////////////////////////////////////////////
238  // built-in script function:  sh_left()  // built-in script function:  sh_left()
239    
240  VMFnResult* CoreVMFunction_sh_left::exec(VMFnArgs* args) {  VMFnResult* CoreVMFunction_sh_left::exec(VMFnArgs* args) {
241      int i = args->arg(0)->asInt()->evalInt();      vmint i = args->arg(0)->asInt()->evalInt();
242      int n = args->arg(1)->asInt()->evalInt();      vmint n = args->arg(1)->asInt()->evalInt();
243      return successResult(i << n);      return successResult(i << n);
244  }  }
245    
# Line 192  VMFnResult* CoreVMFunction_sh_left::exec Line 247  VMFnResult* CoreVMFunction_sh_left::exec
247  // built-in script function:  sh_right()  // built-in script function:  sh_right()
248    
249  VMFnResult* CoreVMFunction_sh_right::exec(VMFnArgs* args) {  VMFnResult* CoreVMFunction_sh_right::exec(VMFnArgs* args) {
250      int i = args->arg(0)->asInt()->evalInt();      vmint i = args->arg(0)->asInt()->evalInt();
251      int n = args->arg(1)->asInt()->evalInt();      vmint n = args->arg(1)->asInt()->evalInt();
252      return successResult(i >> n);      return successResult(i >> n);
253  }  }
254    
# Line 201  VMFnResult* CoreVMFunction_sh_right::exe Line 256  VMFnResult* CoreVMFunction_sh_right::exe
256  // built-in script function:  min()  // built-in script function:  min()
257    
258  VMFnResult* CoreVMFunction_min::exec(VMFnArgs* args) {  VMFnResult* CoreVMFunction_min::exec(VMFnArgs* args) {
259      int l = args->arg(0)->asInt()->evalInt();      vmint l = args->arg(0)->asInt()->evalInt();
260      int r = args->arg(1)->asInt()->evalInt();      vmint r = args->arg(1)->asInt()->evalInt();
261      return successResult(l < r ? l : r);      return successResult(l < r ? l : r);
262  }  }
263    
# Line 210  VMFnResult* CoreVMFunction_min::exec(VMF Line 265  VMFnResult* CoreVMFunction_min::exec(VMF
265  // built-in script function:  max()  // built-in script function:  max()
266    
267  VMFnResult* CoreVMFunction_max::exec(VMFnArgs* args) {  VMFnResult* CoreVMFunction_max::exec(VMFnArgs* args) {
268      int l = args->arg(0)->asInt()->evalInt();      vmint l = args->arg(0)->asInt()->evalInt();
269      int r = args->arg(1)->asInt()->evalInt();      vmint r = args->arg(1)->asInt()->evalInt();
270      return successResult(l > r ? l : r);      return successResult(l > r ? l : r);
271  }  }
272    
273    ///////////////////////////////////////////////////////////////////////////
274    // built-in script function:  array_equal()
275    
276    VMFnResult* CoreVMFunction_array_equal::exec(VMFnArgs* args) {
277        VMIntArrayExpr* l = args->arg(0)->asIntArray();
278        VMIntArrayExpr* r = args->arg(1)->asIntArray();
279        if (l->arraySize() != r->arraySize()) {
280            wrnMsg("array_equal(): the two arrays differ in size");
281            return successResult(0); // false
282        }
283        const vmint n = l->arraySize();
284        for (vmint i = 0; i < n; ++i)
285            if (l->evalIntElement(i) != r->evalIntElement(i))
286                return successResult(0); // false
287        return successResult(1); // true
288    }
289    
290    ///////////////////////////////////////////////////////////////////////////
291    // built-in script function:  search()
292    
293    ExprType_t CoreVMFunction_search::argType(vmint iArg) const {
294        return (iArg == 0) ? INT_ARR_EXPR : INT_EXPR;
295    }
296    
297    bool CoreVMFunction_search::acceptsArgType(vmint iArg, ExprType_t type) const {
298        if (iArg == 0)
299            return type == INT_ARR_EXPR;
300        else
301            return type == INT_EXPR;
302    }
303    
304    VMFnResult* CoreVMFunction_search::exec(VMFnArgs* args) {
305        VMIntArrayExpr* a = args->arg(0)->asIntArray();
306        const vmint needle = args->arg(1)->asInt()->evalInt();
307        const vmint n = a->arraySize();
308        for (vmint i = 0; i < n; ++i)
309            if (a->evalIntElement(i) == needle)
310                return successResult(i);
311        return successResult(-1); // not found
312    }
313    
314    ///////////////////////////////////////////////////////////////////////////
315    // built-in script function:  sort()
316    
317    ExprType_t CoreVMFunction_sort::argType(vmint iArg) const {
318        return (iArg == 0) ? INT_ARR_EXPR : INT_EXPR;
319    }
320    
321    bool CoreVMFunction_sort::acceptsArgType(vmint iArg, ExprType_t type) const {
322        if (iArg == 0)
323            return type == INT_ARR_EXPR;
324        else
325            return type == INT_EXPR;
326    }
327    
328    struct ArrElemPOD {
329        VMIntArrayExpr* m_array;
330        vmint m_index;
331    };
332    
333    static inline void swap(class ArrElemRef a, class ArrElemRef b);
334    
335    class ArrElemRef : protected ArrElemPOD {
336    public:
337        ArrElemRef() {
338            m_array = NULL;
339            m_index = 0;
340        }
341        ArrElemRef(VMIntArrayExpr* a, vmint index) {
342            m_array = a;
343            m_index = index;
344        }
345        inline ArrElemRef& operator=(const ArrElemRef& e) {
346            setValue(e.getValue());
347            return *this;
348        }
349        inline ArrElemRef& operator=(vmint val) {
350            setValue(val);
351            return *this;
352        }
353        inline bool operator==(const ArrElemRef& e) const {
354            if (m_index == e.m_index)
355                return true;
356            return getValue() == e.getValue();
357        }
358        inline bool operator==(vmint val) const {
359            return getValue() == val;
360        }
361        inline bool operator!=(const ArrElemRef& e) const {
362            return !(operator==(e));
363        }
364        inline bool operator!=(vmint val) const {
365            return !(operator==(val));
366        }
367        inline bool operator<(const ArrElemRef& e) const {
368            if (m_index == e.m_index)
369                return false;
370            return getValue() < e.getValue();
371        }
372        inline bool operator<(vmint val) const {
373            return getValue() < val;
374        }
375        inline bool operator>(const ArrElemRef& e) const {
376            if (m_index == e.m_index)
377                return false;
378            return getValue() > e.getValue();
379        }
380        inline bool operator>(vmint val) const {
381            return getValue() > val;
382        }
383        inline bool operator<=(const ArrElemRef& e) const {
384            if (m_index == e.m_index)
385                return true;
386            return getValue() <= e.getValue();
387        }
388        inline bool operator<=(vmint val) const {
389            return getValue() <= val;
390        }
391        inline bool operator>=(const ArrElemRef& e) const {
392            if (m_index == e.m_index)
393                return true;
394            return getValue() >= e.getValue();
395        }
396        inline bool operator>=(vmint val) const {
397            return getValue() >= val;
398        }
399        inline operator vmint() const {
400            return getValue();
401        }
402    protected:
403        inline vmint getValue() const {
404            return m_array->evalIntElement(m_index);
405        }
406        inline void setValue(vmint value) {
407            m_array->assignIntElement(m_index, value);
408        }
409    
410        friend void swap(class ArrElemRef a, class ArrElemRef b);
411    };
412    
413    class ArrElemPtr : protected ArrElemPOD {
414    public:
415        ArrElemPtr() {
416            m_array = NULL;
417            m_index = 0;
418        }
419        ArrElemPtr(VMIntArrayExpr* a, vmint index) {
420            m_array = a;
421            m_index = index;
422        }
423        inline ArrElemRef operator*() {
424            return *(ArrElemRef*)this;
425        }
426    };
427    
428    static inline void swap(ArrElemRef a, ArrElemRef b) {
429        vmint valueA = a.getValue();
430        vmint valueB = b.getValue();
431        a.setValue(valueB);
432        b.setValue(valueA);
433    }
434    
435    class ArrExprIter : public ArrElemPOD {
436    public:
437        typedef std::random_access_iterator_tag iterator_category;
438        typedef vmint value_type;
439        typedef ssize_t difference_type;
440        typedef ArrElemPtr pointer;
441        typedef ArrElemRef reference;
442    
443        ArrExprIter(VMIntArrayExpr* a, vmint index) {
444            m_array = a;
445            m_index = index;
446        }
447        inline ArrElemRef operator*() {
448            return *(ArrElemRef*)this;
449        }
450        inline ArrExprIter& operator++() { // prefix increment
451            ++m_index;
452            return *this;
453        }
454        inline ArrExprIter& operator--() { // prefix decrement
455            --m_index;
456            return *this;
457        }
458        inline ArrExprIter operator++(int) { // postfix increment
459            ArrExprIter it = *this;
460            ++m_index;
461            return it;
462        }
463        inline ArrExprIter operator--(int) { // postfix decrement
464            ArrExprIter it = *this;
465            --m_index;
466            return it;
467        }
468        inline ArrExprIter& operator+=(difference_type d) {
469            m_index += d;
470            return *this;
471        }
472        inline ArrExprIter& operator-=(difference_type d) {
473            m_index -= d;
474            return *this;
475        }
476        inline bool operator==(const ArrExprIter& other) const {
477            return m_index == other.m_index;
478        }
479        inline bool operator!=(const ArrExprIter& other) const {
480            return m_index != other.m_index;
481        }
482        inline bool operator<(const ArrExprIter& other) const {
483            return m_index < other.m_index;
484        }
485        inline bool operator>(const ArrExprIter& other) const {
486            return m_index > other.m_index;
487        }
488        inline bool operator<=(const ArrExprIter& other) const {
489            return m_index <= other.m_index;
490        }
491        inline bool operator>=(const ArrExprIter& other) const {
492            return m_index >= other.m_index;
493        }
494        inline difference_type operator+(const ArrExprIter& other) const {
495            return m_index + other.m_index;
496        }
497        inline difference_type operator-(const ArrExprIter& other) const {
498            return m_index - other.m_index;
499        }
500        inline ArrExprIter operator-(difference_type d) const {
501            return ArrExprIter(m_array, m_index - d);
502        }
503        inline ArrExprIter operator+(difference_type d) const {
504            return ArrExprIter(m_array, m_index + d);
505        }
506        inline ArrExprIter operator*(difference_type factor) const {
507            return ArrExprIter(m_array, m_index * factor);
508        }
509    };
510    
511    struct DescArrExprSorter {
512        inline bool operator()(const vmint& a, const vmint& b) const {
513            return a > b;
514        }
515    };
516    
517    VMFnResult* CoreVMFunction_sort::exec(VMFnArgs* args) {
518        VMIntArrayExpr* a = args->arg(0)->asIntArray();
519        bool bAscending =
520            (args->argsCount() < 2) ? true : !args->arg(1)->asInt()->evalInt();
521        vmint n = a->arraySize();
522        ArrExprIter itBegin(a, 0);
523        ArrExprIter itEnd(a, n);
524        if (bAscending) {
525            std::sort(itBegin, itEnd);
526        } else {
527            DescArrExprSorter sorter;
528            std::sort(itBegin, itEnd, sorter);
529        }
530        return successResult();
531    }
532    
533  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.2972  
changed lines
  Added in v.3564

  ViewVC Help
Powered by ViewVC