/[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 3345 by schoenebeck, Thu Aug 10 13:18:06 2017 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (c) 2014-2015 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"
17  #include "ScriptVM.h"  #include "ScriptVM.h"
18    #include "../common/RTMath.h"
19    
20  namespace LinuxSampler {  namespace LinuxSampler {
21    
# Line 70  bool CoreVMFunction_message::acceptsArgT Line 72  bool CoreVMFunction_message::acceptsArgT
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] %d\n", usecs/1000000.f, intExpr->evalInt());
86          return successResult();          return successResult();
87      }      }
88    
# Line 99  VMFnResult* CoreVMFunction_exit::exec(VM Line 103  VMFnResult* CoreVMFunction_exit::exec(VM
103  VMFnResult* CoreVMFunction_wait::exec(VMFnArgs* args) {  VMFnResult* CoreVMFunction_wait::exec(VMFnArgs* args) {
104      ExecContext* ctx = dynamic_cast<ExecContext*>(vm->currentVMExecContext());      ExecContext* ctx = dynamic_cast<ExecContext*>(vm->currentVMExecContext());
105      VMIntExpr* expr = dynamic_cast<VMIntExpr*>(args->arg(0));      VMIntExpr* expr = dynamic_cast<VMIntExpr*>(args->arg(0));
106      ctx->suspendMicroseconds = expr->evalInt();      int us = expr->evalInt();
107      this->result.flags = STMT_SUSPEND_SIGNALLED;      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      return &result;      return &result;
118  }  }
119    
# Line 171  VMFnResult* CoreVMFunction_dec::exec(VMF Line 184  VMFnResult* CoreVMFunction_dec::exec(VMF
184  }  }
185    
186  ///////////////////////////////////////////////////////////////////////////  ///////////////////////////////////////////////////////////////////////////
187    // 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  // built-in script function:  sh_left()  // built-in script function:  sh_left()
203    
204  VMFnResult* CoreVMFunction_sh_left::exec(VMFnArgs* args) {  VMFnResult* CoreVMFunction_sh_left::exec(VMFnArgs* args) {
# Line 188  VMFnResult* CoreVMFunction_sh_right::exe Line 216  VMFnResult* CoreVMFunction_sh_right::exe
216      return successResult(i >> n);      return successResult(i >> n);
217  }  }
218    
219    ///////////////////////////////////////////////////////////////////////////
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    ///////////////////////////////////////////////////////////////////////////
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    static inline void swap(class ArrElemRef a, class ArrElemRef b);
298    
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        friend void swap(class ArrElemRef a, class ArrElemRef b);
375    };
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    static inline void swap(ArrElemRef a, ArrElemRef b) {
393        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        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        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  } // namespace LinuxSampler  } // namespace LinuxSampler

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

  ViewVC Help
Powered by ViewVC