/[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 2965 by schoenebeck, Mon Jul 18 09:42:28 2016 UTC revision 3557 by schoenebeck, Sun Aug 18 00:06:04 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    
# Line 99  VMFnResult* CoreVMFunction_exit::exec(VM Line 127  VMFnResult* CoreVMFunction_exit::exec(VM
127  VMFnResult* CoreVMFunction_wait::exec(VMFnArgs* args) {  VMFnResult* CoreVMFunction_wait::exec(VMFnArgs* args) {
128      ExecContext* ctx = dynamic_cast<ExecContext*>(vm->currentVMExecContext());      ExecContext* ctx = dynamic_cast<ExecContext*>(vm->currentVMExecContext());
129      VMIntExpr* expr = dynamic_cast<VMIntExpr*>(args->arg(0));      VMIntExpr* expr = dynamic_cast<VMIntExpr*>(args->arg(0));
130      ctx->suspendMicroseconds = expr->evalInt();      vmint us = expr->evalInt();
131      this->result.flags = STMT_SUSPEND_SIGNALLED;      if (us < 0) {
132            wrnMsg("wait(): argument may not be negative! Aborting script!");
133            this->result.flags = STMT_ABORT_SIGNALLED;
134        } else if (us == 0) {
135            wrnMsg("wait(): argument may not be zero! Aborting script!");
136            this->result.flags = STMT_ABORT_SIGNALLED;
137        } else {
138            ctx->suspendMicroseconds = us;
139            this->result.flags = STMT_SUSPEND_SIGNALLED;
140        }
141      return &result;      return &result;
142  }  }
143    
144  ///////////////////////////////////////////////////////////////////////////  ///////////////////////////////////////////////////////////////////////////
145  // built-in script function:  abs()  // built-in script function:  abs()
146    
147  bool CoreVMFunction_abs::acceptsArgType(int iArg, ExprType_t type) const {  bool CoreVMFunction_abs::acceptsArgType(vmint iArg, ExprType_t type) const {
148      return type == INT_EXPR;      return type == INT_EXPR;
149  }  }
150    
# Line 118  VMFnResult* CoreVMFunction_abs::exec(VMF Line 155  VMFnResult* CoreVMFunction_abs::exec(VMF
155  ///////////////////////////////////////////////////////////////////////////  ///////////////////////////////////////////////////////////////////////////
156  // built-in script function:  random()  // built-in script function:  random()
157    
158  bool CoreVMFunction_random::acceptsArgType(int iArg, ExprType_t type) const {  bool CoreVMFunction_random::acceptsArgType(vmint iArg, ExprType_t type) const {
159      return type == INT_EXPR;      return type == INT_EXPR;
160  }  }
161    
162  VMFnResult* CoreVMFunction_random::exec(VMFnArgs* args) {  VMFnResult* CoreVMFunction_random::exec(VMFnArgs* args) {
163      int iMin = args->arg(0)->asInt()->evalInt();      vmint iMin = args->arg(0)->asInt()->evalInt();
164      int iMax = args->arg(1)->asInt()->evalInt();      vmint iMax = args->arg(1)->asInt()->evalInt();
165      float f = float(::rand()) / float(RAND_MAX);      float f = float(::rand()) / float(RAND_MAX);
166      return successResult(      return successResult(
167          iMin + roundf( f * float(iMax - iMin) )          iMin + roundf( f * float(iMax - iMin) )
# Line 134  VMFnResult* CoreVMFunction_random::exec( Line 171  VMFnResult* CoreVMFunction_random::exec(
171  ///////////////////////////////////////////////////////////////////////////  ///////////////////////////////////////////////////////////////////////////
172  // built-in script function:  num_elements()  // built-in script function:  num_elements()
173    
174  bool CoreVMFunction_num_elements::acceptsArgType(int iArg, ExprType_t type) const {  bool CoreVMFunction_num_elements::acceptsArgType(vmint iArg, ExprType_t type) const {
175      return type == INT_ARR_EXPR;      return type == INT_ARR_EXPR;
176  }  }
177    
# Line 150  VMFnResult* CoreVMFunction_inc::exec(VMF Line 187  VMFnResult* CoreVMFunction_inc::exec(VMF
187      VMIntExpr* in = dynamic_cast<VMIntExpr*>(arg);      VMIntExpr* in = dynamic_cast<VMIntExpr*>(arg);
188      VMVariable* out = dynamic_cast<VMVariable*>(arg);      VMVariable* out = dynamic_cast<VMVariable*>(arg);
189      if (!in || !out) successResult(0);      if (!in || !out) successResult(0);
190      int i = in->evalInt() + 1;      vmint i = in->evalInt() + 1;
191      IntLiteral tmp(i);      IntLiteral tmp(i);
192      out->assignExpr(&tmp);      out->assignExpr(&tmp);
193      return successResult(i);      return successResult(i);
# Line 164  VMFnResult* CoreVMFunction_dec::exec(VMF Line 201  VMFnResult* CoreVMFunction_dec::exec(VMF
201      VMIntExpr* in = dynamic_cast<VMIntExpr*>(arg);      VMIntExpr* in = dynamic_cast<VMIntExpr*>(arg);
202      VMVariable* out = dynamic_cast<VMVariable*>(arg);      VMVariable* out = dynamic_cast<VMVariable*>(arg);
203      if (!in || !out) successResult(0);      if (!in || !out) successResult(0);
204      int i = in->evalInt() - 1;      vmint i = in->evalInt() - 1;
205      IntLiteral tmp(i);      IntLiteral tmp(i);
206      out->assignExpr(&tmp);      out->assignExpr(&tmp);
207      return successResult(i);      return successResult(i);
208  }  }
209    
210  ///////////////////////////////////////////////////////////////////////////  ///////////////////////////////////////////////////////////////////////////
211    // built-in script function:  in_range()
212    
213    VMFnResult* CoreVMFunction_in_range::exec(VMFnArgs* args) {
214        vmint i  = args->arg(0)->asInt()->evalInt();
215        vmint lo = args->arg(1)->asInt()->evalInt();
216        vmint hi = args->arg(2)->asInt()->evalInt();
217        if (lo > hi) { // swap lo and hi
218            vmint tmp = lo;
219            lo = hi;
220            hi = tmp;
221        }
222        return successResult(i >= lo && i <= hi);
223    }
224    
225    ///////////////////////////////////////////////////////////////////////////
226  // built-in script function:  sh_left()  // built-in script function:  sh_left()
227    
228  VMFnResult* CoreVMFunction_sh_left::exec(VMFnArgs* args) {  VMFnResult* CoreVMFunction_sh_left::exec(VMFnArgs* args) {
229      int i = args->arg(0)->asInt()->evalInt();      vmint i = args->arg(0)->asInt()->evalInt();
230      int n = args->arg(1)->asInt()->evalInt();      vmint n = args->arg(1)->asInt()->evalInt();
231      return successResult(i << n);      return successResult(i << n);
232  }  }
233    
# Line 183  VMFnResult* CoreVMFunction_sh_left::exec Line 235  VMFnResult* CoreVMFunction_sh_left::exec
235  // built-in script function:  sh_right()  // built-in script function:  sh_right()
236    
237  VMFnResult* CoreVMFunction_sh_right::exec(VMFnArgs* args) {  VMFnResult* CoreVMFunction_sh_right::exec(VMFnArgs* args) {
238      int i = args->arg(0)->asInt()->evalInt();      vmint i = args->arg(0)->asInt()->evalInt();
239      int n = args->arg(1)->asInt()->evalInt();      vmint n = args->arg(1)->asInt()->evalInt();
240      return successResult(i >> n);      return successResult(i >> n);
241  }  }
242    
243    ///////////////////////////////////////////////////////////////////////////
244    // built-in script function:  min()
245    
246    VMFnResult* CoreVMFunction_min::exec(VMFnArgs* args) {
247        vmint l = args->arg(0)->asInt()->evalInt();
248        vmint r = args->arg(1)->asInt()->evalInt();
249        return successResult(l < r ? l : r);
250    }
251    
252    ///////////////////////////////////////////////////////////////////////////
253    // built-in script function:  max()
254    
255    VMFnResult* CoreVMFunction_max::exec(VMFnArgs* args) {
256        vmint l = args->arg(0)->asInt()->evalInt();
257        vmint r = args->arg(1)->asInt()->evalInt();
258        return successResult(l > r ? l : r);
259    }
260    
261    ///////////////////////////////////////////////////////////////////////////
262    // built-in script function:  array_equal()
263    
264    VMFnResult* CoreVMFunction_array_equal::exec(VMFnArgs* args) {
265        VMIntArrayExpr* l = args->arg(0)->asIntArray();
266        VMIntArrayExpr* r = args->arg(1)->asIntArray();
267        if (l->arraySize() != r->arraySize()) {
268            wrnMsg("array_equal(): the two arrays differ in size");
269            return successResult(0); // false
270        }
271        const vmint n = l->arraySize();
272        for (vmint i = 0; i < n; ++i)
273            if (l->evalIntElement(i) != r->evalIntElement(i))
274                return successResult(0); // false
275        return successResult(1); // true
276    }
277    
278    ///////////////////////////////////////////////////////////////////////////
279    // built-in script function:  search()
280    
281    ExprType_t CoreVMFunction_search::argType(vmint iArg) const {
282        return (iArg == 0) ? INT_ARR_EXPR : INT_EXPR;
283    }
284    
285    bool CoreVMFunction_search::acceptsArgType(vmint 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    VMFnResult* CoreVMFunction_search::exec(VMFnArgs* args) {
293        VMIntArrayExpr* a = args->arg(0)->asIntArray();
294        const vmint needle = args->arg(1)->asInt()->evalInt();
295        const vmint n = a->arraySize();
296        for (vmint i = 0; i < n; ++i)
297            if (a->evalIntElement(i) == needle)
298                return successResult(i);
299        return successResult(-1); // not found
300    }
301    
302    ///////////////////////////////////////////////////////////////////////////
303    // built-in script function:  sort()
304    
305    ExprType_t CoreVMFunction_sort::argType(vmint iArg) const {
306        return (iArg == 0) ? INT_ARR_EXPR : INT_EXPR;
307    }
308    
309    bool CoreVMFunction_sort::acceptsArgType(vmint iArg, ExprType_t type) const {
310        if (iArg == 0)
311            return type == INT_ARR_EXPR;
312        else
313            return type == INT_EXPR;
314    }
315    
316    struct ArrElemPOD {
317        VMIntArrayExpr* m_array;
318        vmint m_index;
319    };
320    
321    static inline void swap(class ArrElemRef a, class ArrElemRef b);
322    
323    class ArrElemRef : protected ArrElemPOD {
324    public:
325        ArrElemRef() {
326            m_array = NULL;
327            m_index = 0;
328        }
329        ArrElemRef(VMIntArrayExpr* a, vmint index) {
330            m_array = a;
331            m_index = index;
332        }
333        inline ArrElemRef& operator=(const ArrElemRef& e) {
334            setValue(e.getValue());
335            return *this;
336        }
337        inline ArrElemRef& operator=(vmint val) {
338            setValue(val);
339            return *this;
340        }
341        inline bool operator==(const ArrElemRef& e) const {
342            if (m_index == e.m_index)
343                return true;
344            return getValue() == e.getValue();
345        }
346        inline bool operator==(vmint val) const {
347            return getValue() == val;
348        }
349        inline bool operator!=(const ArrElemRef& e) const {
350            return !(operator==(e));
351        }
352        inline bool operator!=(vmint val) const {
353            return !(operator==(val));
354        }
355        inline bool operator<(const ArrElemRef& e) const {
356            if (m_index == e.m_index)
357                return false;
358            return getValue() < e.getValue();
359        }
360        inline bool operator<(vmint val) const {
361            return getValue() < val;
362        }
363        inline bool operator>(const ArrElemRef& e) const {
364            if (m_index == e.m_index)
365                return false;
366            return getValue() > e.getValue();
367        }
368        inline bool operator>(vmint val) const {
369            return getValue() > val;
370        }
371        inline bool operator<=(const ArrElemRef& e) const {
372            if (m_index == e.m_index)
373                return true;
374            return getValue() <= e.getValue();
375        }
376        inline bool operator<=(vmint val) const {
377            return getValue() <= val;
378        }
379        inline bool operator>=(const ArrElemRef& e) const {
380            if (m_index == e.m_index)
381                return true;
382            return getValue() >= e.getValue();
383        }
384        inline bool operator>=(vmint val) const {
385            return getValue() >= val;
386        }
387        inline operator vmint() const {
388            return getValue();
389        }
390    protected:
391        inline vmint getValue() const {
392            return m_array->evalIntElement(m_index);
393        }
394        inline void setValue(vmint value) {
395            m_array->assignIntElement(m_index, value);
396        }
397    
398        friend void swap(class ArrElemRef a, class ArrElemRef b);
399    };
400    
401    class ArrElemPtr : protected ArrElemPOD {
402    public:
403        ArrElemPtr() {
404            m_array = NULL;
405            m_index = 0;
406        }
407        ArrElemPtr(VMIntArrayExpr* a, vmint index) {
408            m_array = a;
409            m_index = index;
410        }
411        inline ArrElemRef operator*() {
412            return *(ArrElemRef*)this;
413        }
414    };
415    
416    static inline void swap(ArrElemRef a, ArrElemRef b) {
417        vmint valueA = a.getValue();
418        vmint valueB = b.getValue();
419        a.setValue(valueB);
420        b.setValue(valueA);
421    }
422    
423    class ArrExprIter : public ArrElemPOD {
424    public:
425        typedef std::random_access_iterator_tag iterator_category;
426        typedef vmint value_type;
427        typedef ssize_t difference_type;
428        typedef ArrElemPtr pointer;
429        typedef ArrElemRef reference;
430    
431        ArrExprIter(VMIntArrayExpr* a, vmint index) {
432            m_array = a;
433            m_index = index;
434        }
435        inline ArrElemRef operator*() {
436            return *(ArrElemRef*)this;
437        }
438        inline ArrExprIter& operator++() { // prefix increment
439            ++m_index;
440            return *this;
441        }
442        inline ArrExprIter& operator--() { // prefix decrement
443            --m_index;
444            return *this;
445        }
446        inline ArrExprIter operator++(int) { // postfix increment
447            ArrExprIter it = *this;
448            ++m_index;
449            return it;
450        }
451        inline ArrExprIter operator--(int) { // postfix decrement
452            ArrExprIter it = *this;
453            --m_index;
454            return it;
455        }
456        inline ArrExprIter& operator+=(difference_type d) {
457            m_index += d;
458            return *this;
459        }
460        inline ArrExprIter& operator-=(difference_type d) {
461            m_index -= d;
462            return *this;
463        }
464        inline bool operator==(const ArrExprIter& other) const {
465            return m_index == other.m_index;
466        }
467        inline bool operator!=(const ArrExprIter& other) const {
468            return m_index != other.m_index;
469        }
470        inline bool operator<(const ArrExprIter& other) const {
471            return m_index < other.m_index;
472        }
473        inline bool operator>(const ArrExprIter& other) const {
474            return m_index > other.m_index;
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 difference_type operator+(const ArrExprIter& other) const {
483            return m_index + other.m_index;
484        }
485        inline difference_type operator-(const ArrExprIter& other) const {
486            return m_index - other.m_index;
487        }
488        inline ArrExprIter operator-(difference_type d) const {
489            return ArrExprIter(m_array, m_index - d);
490        }
491        inline ArrExprIter operator+(difference_type d) const {
492            return ArrExprIter(m_array, m_index + d);
493        }
494        inline ArrExprIter operator*(difference_type factor) const {
495            return ArrExprIter(m_array, m_index * factor);
496        }
497    };
498    
499    struct DescArrExprSorter {
500        inline bool operator()(const vmint& a, const vmint& b) const {
501            return a > b;
502        }
503    };
504    
505    VMFnResult* CoreVMFunction_sort::exec(VMFnArgs* args) {
506        VMIntArrayExpr* a = args->arg(0)->asIntArray();
507        bool bAscending =
508            (args->argsCount() < 2) ? true : !args->arg(1)->asInt()->evalInt();
509        vmint n = a->arraySize();
510        ArrExprIter itBegin(a, 0);
511        ArrExprIter itEnd(a, n);
512        if (bAscending) {
513            std::sort(itBegin, itEnd);
514        } else {
515            DescArrExprSorter sorter;
516            std::sort(itBegin, itEnd, sorter);
517        }
518        return successResult();
519    }
520    
521  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.2965  
changed lines
  Added in v.3557

  ViewVC Help
Powered by ViewVC