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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3678 - (show annotations) (download)
Fri Dec 27 22:46:08 2019 UTC (4 years, 3 months ago) by schoenebeck
File size: 59368 byte(s)
* NKSP: Added built-in script functions "msb()" and "lsb()".

* Bumped version (2.1.1.svn26).

1 /*
2 * Copyright (c) 2014-2019 Christian Schoenebeck
3 *
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 #include <algorithm> // for std::sort()
14 #include <math.h>
15 #include <stdlib.h>
16 #include "tree.h"
17 #include "ScriptVM.h"
18 #include "../common/RTMath.h"
19
20 namespace LinuxSampler {
21
22 inline bool _fEqualX(vmfloat a, vmfloat b) {
23 if (sizeof(vmfloat) == sizeof(float))
24 return RTMath::fEqual32(a, b);
25 else
26 return RTMath::fEqual64(a, b);
27 }
28
29 ///////////////////////////////////////////////////////////////////////////
30 // class VMEmptyResultFunction
31
32 VMFnResult* VMEmptyResultFunction::errorResult() {
33 result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
34 return &result;
35 }
36
37 VMFnResult* VMEmptyResultFunction::successResult() {
38 result.flags = STMT_SUCCESS;
39 return &result;
40 }
41
42 ///////////////////////////////////////////////////////////////////////////
43 // class VMIntResultFunction
44
45 VMFnResult* VMIntResultFunction::errorResult(vmint i) {
46 result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
47 result.value = i;
48 result.unitPrefixFactor = VM_NO_FACTOR;
49 return &result;
50 }
51
52 VMFnResult* VMIntResultFunction::successResult(vmint i) {
53 result.flags = STMT_SUCCESS;
54 result.value = i;
55 result.unitPrefixFactor = VM_NO_FACTOR;
56 return &result;
57 }
58
59 VMFnResult* VMIntResultFunction::errorResult(VMIntFnResDef res) {
60 result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
61 result.value = res.value;
62 result.unitPrefixFactor = res.unitFactor;
63 return &result;
64 }
65
66 VMFnResult* VMIntResultFunction::successResult(VMIntFnResDef res) {
67 result.flags = STMT_SUCCESS;
68 result.value = res.value;
69 result.unitPrefixFactor = res.unitFactor;
70 return &result;
71 }
72
73 ///////////////////////////////////////////////////////////////////////////
74 // class VMRealResultFunction
75
76 VMFnResult* VMRealResultFunction::errorResult(vmfloat f) {
77 result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
78 result.value = f;
79 result.unitPrefixFactor = VM_NO_FACTOR;
80 return &result;
81 }
82
83 VMFnResult* VMRealResultFunction::errorResult(VMRealFnResDef res) {
84 result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
85 result.value = res.value;
86 result.unitPrefixFactor = res.unitFactor;
87 return &result;
88 }
89
90 VMFnResult* VMRealResultFunction::successResult(vmfloat f) {
91 result.flags = STMT_SUCCESS;
92 result.value = f;
93 result.unitPrefixFactor = VM_NO_FACTOR;
94 return &result;
95 }
96
97 VMFnResult* VMRealResultFunction::successResult(VMRealFnResDef res) {
98 result.flags = STMT_SUCCESS;
99 result.value = res.value;
100 result.unitPrefixFactor = res.unitFactor;
101 return &result;
102 }
103
104 ///////////////////////////////////////////////////////////////////////////
105 // class VMStringResultFunction
106
107 VMFnResult* VMStringResultFunction::errorResult(const String& s) {
108 result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
109 result.value = s;
110 return &result;
111 }
112
113 VMFnResult* VMStringResultFunction::successResult(const String& s) {
114 result.flags = STMT_SUCCESS;
115 result.value = s;
116 return &result;
117 }
118
119 ///////////////////////////////////////////////////////////////////////////
120 // class VMNumberResultFunction
121
122 VMFnResult* VMNumberResultFunction::errorResult(vmint i) {
123 intResult.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
124 intResult.value = i;
125 intResult.unitPrefixFactor = VM_NO_FACTOR;
126 return &intResult;
127 }
128
129 VMFnResult* VMNumberResultFunction::errorResult(vmfloat f) {
130 realResult.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
131 realResult.value = f;
132 realResult.unitPrefixFactor = VM_NO_FACTOR;
133 return &realResult;
134 }
135
136 VMFnResult* VMNumberResultFunction::successResult(vmint i) {
137 intResult.flags = STMT_SUCCESS;
138 intResult.value = i;
139 intResult.unitPrefixFactor = VM_NO_FACTOR;
140 return &intResult;
141 }
142
143 VMFnResult* VMNumberResultFunction::successResult(vmfloat f) {
144 realResult.flags = STMT_SUCCESS;
145 realResult.value = f;
146 realResult.unitPrefixFactor = VM_NO_FACTOR;
147 return &realResult;
148 }
149
150 VMFnResult* VMNumberResultFunction::errorIntResult(VMIntFnResDef res) {
151 intResult.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
152 intResult.value = res.value;
153 intResult.unitPrefixFactor = res.unitFactor;
154 return &intResult;
155 }
156
157 VMFnResult* VMNumberResultFunction::errorRealResult(VMRealFnResDef res) {
158 realResult.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
159 realResult.value = res.value;
160 realResult.unitPrefixFactor = res.unitFactor;
161 return &realResult;
162 }
163
164 VMFnResult* VMNumberResultFunction::successIntResult(VMIntFnResDef res) {
165 intResult.flags = STMT_SUCCESS;
166 intResult.value = res.value;
167 intResult.unitPrefixFactor = res.unitFactor;
168 return &intResult;
169 }
170
171 VMFnResult* VMNumberResultFunction::successRealResult(VMRealFnResDef res) {
172 realResult.flags = STMT_SUCCESS;
173 realResult.value = res.value;
174 realResult.unitPrefixFactor = res.unitFactor;
175 return &realResult;
176 }
177
178 ///////////////////////////////////////////////////////////////////////////
179 // built-in script function: message()
180
181 bool CoreVMFunction_message::acceptsArgType(vmint iArg, ExprType_t type) const {
182 return type == INT_EXPR || type == REAL_EXPR || type == STRING_EXPR;
183 }
184
185 VMFnResult* CoreVMFunction_message::exec(VMFnArgs* args) {
186 if (!args->argsCount()) return errorResult();
187
188 uint64_t usecs = RTMath::unsafeMicroSeconds(RTMath::real_clock);
189
190 VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(args->arg(0));
191 if (strExpr) {
192 printf("[ScriptVM %.3f] %s\n", usecs/1000000.f, strExpr->evalStr().c_str());
193 return successResult();
194 }
195
196 VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(args->arg(0));
197 if (realExpr) {
198 printf("[ScriptVM %.3f] %f\n", usecs/1000000.f, realExpr->evalReal());
199 return successResult();
200 }
201
202 VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(args->arg(0));
203 if (intExpr) {
204 printf("[ScriptVM %.3f] %lld\n", usecs/1000000.f, (int64_t)intExpr->evalInt());
205 return successResult();
206 }
207
208 return errorResult();
209 }
210
211 ///////////////////////////////////////////////////////////////////////////
212 // built-in script function: exit()
213
214 vmint CoreVMFunction_exit::maxAllowedArgs() const {
215 return (vm->isExitResultEnabled()) ? 1 : 0;
216 }
217
218 bool CoreVMFunction_exit::acceptsArgType(vmint iArg, ExprType_t type) const {
219 if (!vm->isExitResultEnabled()) return false;
220 return type == INT_EXPR || type == REAL_EXPR || type == STRING_EXPR;
221 }
222
223 bool CoreVMFunction_exit::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {
224 if (!vm->isExitResultEnabled()) return false;
225 return true;
226 }
227
228 bool CoreVMFunction_exit::acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const {
229 if (!vm->isExitResultEnabled()) return false;
230 return true;
231 }
232 bool CoreVMFunction_exit::acceptsArgFinal(vmint iArg) const {
233 if (!vm->isExitResultEnabled()) return false;
234 return true;
235 }
236
237 VMFnResult* CoreVMFunction_exit::exec(VMFnArgs* args) {
238 this->result.flags = STMT_ABORT_SIGNALLED;
239 if (vm->isExitResultEnabled() && args->argsCount()) {
240 ExecContext* ctx = dynamic_cast<ExecContext*>(vm->currentVMExecContext());
241 switch (args->arg(0)->exprType()) {
242 case INT_EXPR: {
243 VMIntExpr* expr = args->arg(0)->asInt();
244 ctx->exitRes.intLiteral = IntLiteral({
245 .value = expr->evalInt(),
246 .unitFactor = expr->unitFactor(),
247 .unitType = expr->unitType(),
248 .isFinal = expr->isFinal()
249 });
250 ctx->exitRes.value = &ctx->exitRes.intLiteral;
251 break;
252 }
253 case REAL_EXPR: {
254 VMRealExpr* expr = args->arg(0)->asReal();
255 ctx->exitRes.realLiteral = RealLiteral({
256 .value = expr->evalReal(),
257 .unitFactor = expr->unitFactor(),
258 .unitType = expr->unitType(),
259 .isFinal = expr->isFinal()
260 });
261 ctx->exitRes.value = &ctx->exitRes.realLiteral;
262 break;
263 }
264 case STRING_EXPR:
265 ctx->exitRes.stringLiteral = StringLiteral(
266 args->arg(0)->asString()->evalStr()
267 );
268 ctx->exitRes.value = &ctx->exitRes.stringLiteral;
269 break;
270 default:
271 ; // noop - just to shut up the compiler
272 }
273 }
274 return &result;
275 }
276
277 ///////////////////////////////////////////////////////////////////////////
278 // built-in script function: wait()
279
280 bool CoreVMFunction_wait::acceptsArgType(vmint iArg, ExprType_t type) const {
281 return type == INT_EXPR || type == REAL_EXPR;
282 }
283
284 bool CoreVMFunction_wait::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {
285 return type == VM_NO_UNIT || type == VM_SECOND;
286 }
287
288 bool CoreVMFunction_wait::acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const {
289 return type == VM_SECOND; // only allow metric prefix(es) if 'seconds' is used as unit type
290 }
291
292 VMFnResult* CoreVMFunction_wait::exec(VMFnArgs* args) {
293 ExecContext* ctx = dynamic_cast<ExecContext*>(vm->currentVMExecContext());
294 VMNumberExpr* expr = args->arg(0)->asNumber();
295 StdUnit_t unit = expr->unitType();
296 vmint us = (unit) ? expr->evalCastInt(VM_MICRO) : expr->evalCastInt();
297 if (us < 0) {
298 wrnMsg("wait(): argument may not be negative! Aborting script!");
299 this->result.flags = STMT_ABORT_SIGNALLED;
300 } else if (us == 0) {
301 wrnMsg("wait(): argument may not be zero! Aborting script!");
302 this->result.flags = STMT_ABORT_SIGNALLED;
303 } else {
304 ctx->suspendMicroseconds = us;
305 this->result.flags = STMT_SUSPEND_SIGNALLED;
306 }
307 return &result;
308 }
309
310 ///////////////////////////////////////////////////////////////////////////
311 // built-in script function: abs()
312
313 ExprType_t CoreVMFunction_abs::returnType(VMFnArgs* args) {
314 return args->arg(0)->exprType();
315 }
316
317 StdUnit_t CoreVMFunction_abs::returnUnitType(VMFnArgs* args) {
318 return args->arg(0)->asNumber()->unitType();
319 }
320
321 bool CoreVMFunction_abs::returnsFinal(VMFnArgs* args) {
322 return args->arg(0)->asNumber()->isFinal();
323 }
324
325 bool CoreVMFunction_abs::acceptsArgType(vmint iArg, ExprType_t type) const {
326 return type == INT_EXPR || type == REAL_EXPR;
327 }
328
329 VMFnResult* CoreVMFunction_abs::exec(VMFnArgs* args) {
330 VMExpr* arg = args->arg(0);
331 if (arg->exprType() == REAL_EXPR) {
332 VMRealExpr* expr = arg->asReal();
333 return successRealResult({
334 .value = static_cast<vmfloat>(::fabs(expr->evalReal())),
335 .unitFactor = expr->unitFactor()
336 });
337 } else {
338 VMIntExpr* expr = arg->asInt();
339 return successIntResult({
340 .value = std::abs(expr->evalInt()),
341 .unitFactor = expr->unitFactor()
342 });
343 }
344 }
345
346 ///////////////////////////////////////////////////////////////////////////
347 // built-in script function: random()
348
349 ExprType_t CoreVMFunction_random::returnType(VMFnArgs* args) {
350 return (args->arg(0)->exprType() == INT_EXPR &&
351 args->arg(1)->exprType() == INT_EXPR) ? INT_EXPR : REAL_EXPR;
352 }
353
354 StdUnit_t CoreVMFunction_random::returnUnitType(VMFnArgs* args) {
355 // we ensure in checkArgs() below (which is called before this method here)
356 // that both arguments must be of same unit type, so either one is fine here
357 return args->arg(0)->asNumber()->unitType();
358 }
359
360 bool CoreVMFunction_random::returnsFinal(VMFnArgs* args) {
361 return args->arg(0)->asNumber()->isFinal() ||
362 args->arg(1)->asNumber()->isFinal();
363 }
364
365 bool CoreVMFunction_random::acceptsArgType(vmint iArg, ExprType_t type) const {
366 return type == INT_EXPR || type == REAL_EXPR;
367 }
368
369 void CoreVMFunction_random::checkArgs(VMFnArgs* args,
370 std::function<void(String)> err,
371 std::function<void(String)> wrn)
372 {
373 // super class checks
374 Super::checkArgs(args, err, wrn);
375
376 // own checks ...
377 if (args->arg(0)->asNumber()->unitType() !=
378 args->arg(1)->asNumber()->unitType())
379 {
380 String a = unitTypeStr(args->arg(0)->asNumber()->unitType());
381 String b = unitTypeStr(args->arg(1)->asNumber()->unitType());
382 err("Argument 1 has unit type " + a + ", whereas argument 2 has unit type " + b + ".");
383 return;
384 }
385 if (args->arg(0)->asNumber()->isFinal() !=
386 args->arg(1)->asNumber()->isFinal())
387 {
388 String a = args->arg(0)->asNumber()->isFinal() ? "'final'" : "not 'final'";
389 String b = args->arg(1)->asNumber()->isFinal() ? "'final'" : "not 'final'";
390 wrn("Argument 1 is " + a + ", whereas argument 2 is " + b + ", function result will be final.");
391 }
392 }
393
394 VMFnResult* CoreVMFunction_random::exec(VMFnArgs* args) {
395 float f = float(::rand()) / float(RAND_MAX);
396
397 VMNumberExpr* arg0 = args->arg(0)->asNumber();
398 VMNumberExpr* arg1 = args->arg(1)->asNumber();
399
400 if (arg0->exprType() == INT_EXPR && arg1->exprType() == INT_EXPR) {
401 vmint iMin = args->arg(0)->asInt()->evalInt();
402 vmint iMax = args->arg(1)->asInt()->evalInt();
403 if (arg0->unitFactor() == arg1->unitFactor()) {
404 return successIntResult({
405 .value = vmint( iMin + roundf( f * float(iMax - iMin) ) ),
406 .unitFactor = arg0->unitFactor()
407 });
408 } else if (arg0->unitFactor() < arg1->unitFactor()) {
409 iMax = Unit::convIntToUnitFactor(iMax, arg1, arg0);
410 return successIntResult({
411 .value = vmint( iMin + roundf( f * float(iMax - iMin) ) ),
412 .unitFactor = arg0->unitFactor()
413 });
414 } else { // arg0->unitFactor() > arg1->unitFactor() ...
415 iMin = Unit::convIntToUnitFactor(iMin, arg0, arg1);
416 return successIntResult({
417 .value = vmint( iMin + roundf( f * float(iMax - iMin) ) ),
418 .unitFactor = arg1->unitFactor()
419 });
420 }
421 } else {
422 vmfloat fMin = arg0->evalCastReal();
423 vmfloat fMax = arg1->evalCastReal();
424 if (arg0->unitFactor() == arg1->unitFactor()) {
425 return successRealResult({
426 .value = fMin + f * (fMax - fMin),
427 .unitFactor = arg0->unitFactor()
428 });
429 } else if (arg0->unitFactor() < arg1->unitFactor()) {
430 fMax = Unit::convRealToUnitFactor(fMax, arg1, arg0);
431 return successRealResult({
432 .value = fMin + f * (fMax - fMin),
433 .unitFactor = arg0->unitFactor()
434 });
435 } else { // arg0->unitFactor() > arg1->unitFactor() ...
436 fMin = Unit::convRealToUnitFactor(fMin, arg0, arg1);
437 return successRealResult({
438 .value = fMin + f * (fMax - fMin),
439 .unitFactor = arg1->unitFactor()
440 });
441 }
442 }
443 }
444
445 ///////////////////////////////////////////////////////////////////////////
446 // built-in script function: num_elements()
447
448 bool CoreVMFunction_num_elements::acceptsArgType(vmint iArg, ExprType_t type) const {
449 return isArray(type);
450 }
451
452 VMFnResult* CoreVMFunction_num_elements::exec(VMFnArgs* args) {
453 return successResult( args->arg(0)->asArray()->arraySize() );
454 }
455
456 ///////////////////////////////////////////////////////////////////////////
457 // built-in script function: inc()
458
459 StdUnit_t CoreVMFunction_inc::returnUnitType(VMFnArgs* args) {
460 return args->arg(0)->asNumber()->unitType();
461 }
462
463 bool CoreVMFunction_inc::returnsFinal(VMFnArgs* args) {
464 return args->arg(0)->asNumber()->isFinal();
465 }
466
467 void CoreVMFunction_inc::checkArgs(VMFnArgs* args,
468 std::function<void(String)> err,
469 std::function<void(String)> wrn)
470 {
471 // super class checks
472 Super::checkArgs(args, err, wrn);
473
474 // own checks ...
475 if (args->arg(0)->asNumber()->unitType()) {
476 String unitType = unitTypeStr(args->arg(0)->asNumber()->unitType());
477 wrn("Argument has a unit type (" + unitType + "), only the number before the unit will be incremented by one.");
478 }
479 }
480
481 VMFnResult* CoreVMFunction_inc::exec(VMFnArgs* args) {
482 VMExpr* arg = args->arg(0);
483 VMIntExpr* in = dynamic_cast<VMIntExpr*>(arg);
484 VMVariable* out = dynamic_cast<VMVariable*>(arg);
485 vmint i = in->evalInt() + 1;
486 IntLiteral tmp({
487 .value = i,
488 .unitFactor = in->unitFactor()
489 });
490 out->assignExpr(&tmp);
491 return successResult({
492 .value = i,
493 .unitFactor = in->unitFactor()
494 });
495 }
496
497 ///////////////////////////////////////////////////////////////////////////
498 // built-in script function: dec()
499
500 StdUnit_t CoreVMFunction_dec::returnUnitType(VMFnArgs* args) {
501 return args->arg(0)->asNumber()->unitType();
502 }
503
504 bool CoreVMFunction_dec::returnsFinal(VMFnArgs* args) {
505 return args->arg(0)->asNumber()->isFinal();
506 }
507
508 void CoreVMFunction_dec::checkArgs(VMFnArgs* args,
509 std::function<void(String)> err,
510 std::function<void(String)> wrn)
511 {
512 // super class checks
513 Super::checkArgs(args, err, wrn);
514
515 // own checks ...
516 if (args->arg(0)->asNumber()->unitType()) {
517 String unitType = unitTypeStr(args->arg(0)->asNumber()->unitType());
518 wrn("Argument has a unit type (" + unitType + "), only the number before the unit will be decremented by one.");
519 }
520 }
521
522 VMFnResult* CoreVMFunction_dec::exec(VMFnArgs* args) {
523 VMExpr* arg = args->arg(0);
524 VMIntExpr* in = dynamic_cast<VMIntExpr*>(arg);
525 VMVariable* out = dynamic_cast<VMVariable*>(arg);
526 vmint i = in->evalInt() - 1;
527 IntLiteral tmp({
528 .value = i,
529 .unitFactor = in->unitFactor()
530 });
531 out->assignExpr(&tmp);
532 return successResult({
533 .value = i,
534 .unitFactor = in->unitFactor()
535 });
536 }
537
538 ///////////////////////////////////////////////////////////////////////////
539 // built-in script function: in_range()
540
541 bool CoreVMFunction_in_range::acceptsArgType(vmint iArg, ExprType_t type) const {
542 return type == INT_EXPR || type == REAL_EXPR;
543 }
544
545 void CoreVMFunction_in_range::checkArgs(VMFnArgs* args,
546 std::function<void(String)> err,
547 std::function<void(String)> wrn)
548 {
549 // super class checks
550 Super::checkArgs(args, err, wrn);
551
552 // own checks ...
553 if (args->arg(0)->asNumber()->unitType() !=
554 args->arg(1)->asNumber()->unitType() ||
555 args->arg(1)->asNumber()->unitType() !=
556 args->arg(2)->asNumber()->unitType())
557 {
558 String a = unitTypeStr(args->arg(0)->asNumber()->unitType());
559 String b = unitTypeStr(args->arg(1)->asNumber()->unitType());
560 String c = unitTypeStr(args->arg(2)->asNumber()->unitType());
561 err("Arguments must all have same unit, however argument 1 is " + a +
562 ", argument 2 is " + b + ", argument 3 is " + c + ".");
563 return;
564 }
565 if (args->arg(0)->exprType() != args->arg(1)->exprType() ||
566 args->arg(1)->exprType() != args->arg(2)->exprType())
567 {
568 String a = typeStr(args->arg(0)->exprType());
569 String b = typeStr(args->arg(1)->exprType());
570 String c = typeStr(args->arg(2)->exprType());
571 String r = typeStr(REAL_EXPR);
572 wrn("Argument 1 is " + a + ", argument 2 is " + b +
573 ", argument 3 is " + c + ", function result will be " + r + ".");
574 }
575 }
576
577 template<class T>
578 inline void _swapByValue(T& a, T& b) {
579 T tmp = a;
580 a = b;
581 b = tmp;
582 }
583
584 VMFnResult* CoreVMFunction_in_range::exec(VMFnArgs* args) {
585 VMNumberExpr* argNeedle = args->arg(0)->asNumber();
586 VMNumberExpr* argLo = args->arg(1)->asNumber();
587 VMNumberExpr* argHi = args->arg(2)->asNumber();
588
589 vmfloat needle = argNeedle->evalCastReal();
590 vmfloat lo = argLo->evalCastReal();
591 vmfloat hi = argHi->evalCastReal();
592
593 needle *= argNeedle->unitFactor();
594 lo *= argLo->unitFactor();
595 hi *= argHi->unitFactor();
596
597 if (lo > hi) _swapByValue(lo, hi);
598
599 return successResult(needle >= lo && needle <= hi);
600 }
601
602 ///////////////////////////////////////////////////////////////////////////
603 // built-in script function: sh_left()
604
605 bool CoreVMFunction_sh_left::returnsFinal(VMFnArgs* args) {
606 return args->arg(0)->asNumber()->isFinal();
607 }
608
609 VMFnResult* CoreVMFunction_sh_left::exec(VMFnArgs* args) {
610 vmint i = args->arg(0)->asInt()->evalInt();
611 vmint n = args->arg(1)->asInt()->evalInt();
612 return successResult(i << n);
613 }
614
615 ///////////////////////////////////////////////////////////////////////////
616 // built-in script function: sh_right()
617
618 bool CoreVMFunction_sh_right::returnsFinal(VMFnArgs* args) {
619 return args->arg(0)->asNumber()->isFinal();
620 }
621
622 VMFnResult* CoreVMFunction_sh_right::exec(VMFnArgs* args) {
623 vmint i = args->arg(0)->asInt()->evalInt();
624 vmint n = args->arg(1)->asInt()->evalInt();
625 return successResult(i >> n);
626 }
627
628 ///////////////////////////////////////////////////////////////////////////
629 // built-in script function: msb()
630
631 VMFnResult* CoreVMFunction_msb::exec(VMFnArgs* args) {
632 vmint i = args->arg(0)->asInt()->evalInt();
633 return successResult((i >> 7) & 127);
634 }
635
636 ///////////////////////////////////////////////////////////////////////////
637 // built-in script function: lsb()
638
639 VMFnResult* CoreVMFunction_lsb::exec(VMFnArgs* args) {
640 vmint i = args->arg(0)->asInt()->evalInt();
641 return successResult(i & 127);
642 }
643
644 ///////////////////////////////////////////////////////////////////////////
645 // built-in script function: min()
646
647 ExprType_t CoreVMFunction_min::returnType(VMFnArgs* args) {
648 return (args->arg(0)->exprType() == REAL_EXPR ||
649 args->arg(1)->exprType() == REAL_EXPR) ? REAL_EXPR : INT_EXPR;
650 }
651
652 StdUnit_t CoreVMFunction_min::returnUnitType(VMFnArgs* args) {
653 return args->arg(0)->asNumber()->unitType();
654 }
655
656 bool CoreVMFunction_min::returnsFinal(VMFnArgs* args) {
657 return args->arg(0)->asNumber()->isFinal() ||
658 args->arg(1)->asNumber()->isFinal();
659 }
660
661 bool CoreVMFunction_min::acceptsArgType(vmint iArg, ExprType_t type) const {
662 return type == INT_EXPR || type == REAL_EXPR;
663 }
664
665 void CoreVMFunction_min::checkArgs(VMFnArgs* args,
666 std::function<void(String)> err,
667 std::function<void(String)> wrn)
668 {
669 // super class checks
670 Super::checkArgs(args, err, wrn);
671
672 // own checks ...
673 if (args->arg(0)->asNumber()->unitType() !=
674 args->arg(1)->asNumber()->unitType())
675 {
676 String a = unitTypeStr(args->arg(0)->asNumber()->unitType());
677 String b = unitTypeStr(args->arg(1)->asNumber()->unitType());
678 err("Argument 1 has unit type " + a + ", whereas argument 2 has unit type " + b + ".");
679 return;
680 }
681 if (args->arg(0)->exprType() != args->arg(1)->exprType()) {
682 String a = typeStr(args->arg(0)->exprType());
683 String b = typeStr(args->arg(1)->exprType());
684 String c = typeStr(REAL_EXPR);
685 wrn("Argument 1 is " + a + ", whereas argument 2 is " + b + ", function result will be " + c + ".");
686 return;
687 }
688 if (args->arg(0)->asNumber()->isFinal() !=
689 args->arg(1)->asNumber()->isFinal())
690 {
691 String a = args->arg(0)->asNumber()->isFinal() ? "'final'" : "not 'final'";
692 String b = args->arg(1)->asNumber()->isFinal() ? "'final'" : "not 'final'";
693 wrn("Argument 1 is " + a + ", whereas argument 2 is " + b + ", function result will be final.");
694 }
695 }
696
697 VMFnResult* CoreVMFunction_min::exec(VMFnArgs* args) {
698 VMNumberExpr* lhs = args->arg(0)->asNumber();
699 VMNumberExpr* rhs = args->arg(1)->asNumber();
700 if (lhs->exprType() == REAL_EXPR && rhs->exprType() == REAL_EXPR) {
701 vmfloat lm = lhs->asReal()->evalReal();
702 vmfloat rm = rhs->asReal()->evalReal();
703 vmfloat lprod = lm * lhs->unitFactor();
704 vmfloat rprod = rm * rhs->unitFactor();
705 return successRealResult({
706 .value = (lprod < rprod) ? lm : rm,
707 .unitFactor = (lprod < rprod) ? lhs->unitFactor() : rhs->unitFactor()
708 });
709 } else if (lhs->exprType() == REAL_EXPR && rhs->exprType() == INT_EXPR) {
710 vmfloat lm = lhs->asReal()->evalReal();
711 vmint rm = rhs->asInt()->evalInt();
712 vmfloat lprod = lm * lhs->unitFactor();
713 vmfloat rprod = rm * rhs->unitFactor();
714 return successRealResult({
715 .value = (lprod < rprod) ? lm : rm,
716 .unitFactor = (lprod < rprod) ? lhs->unitFactor() : rhs->unitFactor()
717 });
718 } else if (lhs->exprType() == INT_EXPR && rhs->exprType() == REAL_EXPR) {
719 vmint lm = lhs->asInt()->evalInt();
720 vmfloat rm = rhs->asReal()->evalReal();
721 vmfloat lprod = lm * lhs->unitFactor();
722 vmfloat rprod = rm * rhs->unitFactor();
723 return successRealResult({
724 .value = (lprod < rprod) ? lm : rm,
725 .unitFactor = (lprod < rprod) ? lhs->unitFactor() : rhs->unitFactor()
726 });
727 } else {
728 vmint lm = lhs->asInt()->evalInt();
729 vmint rm = rhs->asInt()->evalInt();
730 vmfloat lprod = lm * lhs->unitFactor();
731 vmfloat rprod = rm * rhs->unitFactor();
732 return successIntResult({
733 .value = (lprod < rprod) ? lm : rm,
734 .unitFactor = (lprod < rprod) ? lhs->unitFactor() : rhs->unitFactor()
735 });
736 }
737 }
738
739 ///////////////////////////////////////////////////////////////////////////
740 // built-in script function: max()
741
742 ExprType_t CoreVMFunction_max::returnType(VMFnArgs* args) {
743 return (args->arg(0)->exprType() == REAL_EXPR ||
744 args->arg(1)->exprType() == REAL_EXPR) ? REAL_EXPR : INT_EXPR;
745 }
746
747 StdUnit_t CoreVMFunction_max::returnUnitType(VMFnArgs* args) {
748 return args->arg(0)->asNumber()->unitType();
749 }
750
751 bool CoreVMFunction_max::returnsFinal(VMFnArgs* args) {
752 return args->arg(0)->asNumber()->isFinal() ||
753 args->arg(1)->asNumber()->isFinal();
754 }
755
756 bool CoreVMFunction_max::acceptsArgType(vmint iArg, ExprType_t type) const {
757 return type == INT_EXPR || type == REAL_EXPR;
758 }
759
760 void CoreVMFunction_max::checkArgs(VMFnArgs* args,
761 std::function<void(String)> err,
762 std::function<void(String)> wrn)
763 {
764 // super class checks
765 Super::checkArgs(args, err, wrn);
766
767 // own checks ...
768 if (args->arg(0)->asNumber()->unitType() !=
769 args->arg(1)->asNumber()->unitType())
770 {
771 String a = unitTypeStr(args->arg(0)->asNumber()->unitType());
772 String b = unitTypeStr(args->arg(1)->asNumber()->unitType());
773 err("Argument 1 has unit type " + a + ", whereas argument 2 has unit type " + b + ".");
774 return;
775 }
776 if (args->arg(0)->exprType() != args->arg(1)->exprType()) {
777 String a = typeStr(args->arg(0)->exprType());
778 String b = typeStr(args->arg(1)->exprType());
779 String c = typeStr(REAL_EXPR);
780 wrn("Argument 1 is " + a + ", whereas argument 2 is " + b + ", function result will be " + c + ".");
781 return;
782 }
783 if (args->arg(0)->asNumber()->isFinal() !=
784 args->arg(1)->asNumber()->isFinal())
785 {
786 String a = args->arg(0)->asNumber()->isFinal() ? "'final'" : "not 'final'";
787 String b = args->arg(1)->asNumber()->isFinal() ? "'final'" : "not 'final'";
788 wrn("Argument 1 is " + a + ", whereas argument 2 is " + b + ", function result will be final.");
789 }
790 }
791
792 VMFnResult* CoreVMFunction_max::exec(VMFnArgs* args) {
793 VMNumberExpr* lhs = args->arg(0)->asNumber();
794 VMNumberExpr* rhs = args->arg(1)->asNumber();
795 if (lhs->exprType() == REAL_EXPR && rhs->exprType() == REAL_EXPR) {
796 vmfloat lm = lhs->asReal()->evalReal();
797 vmfloat rm = rhs->asReal()->evalReal();
798 vmfloat lprod = lm * lhs->unitFactor();
799 vmfloat rprod = rm * rhs->unitFactor();
800 return successRealResult({
801 .value = (lprod > rprod) ? lm : rm,
802 .unitFactor = (lprod > rprod) ? lhs->unitFactor() : rhs->unitFactor()
803 });
804 } else if (lhs->exprType() == REAL_EXPR && rhs->exprType() == INT_EXPR) {
805 vmfloat lm = lhs->asReal()->evalReal();
806 vmint rm = rhs->asInt()->evalInt();
807 vmfloat lprod = lm * lhs->unitFactor();
808 vmfloat rprod = rm * rhs->unitFactor();
809 return successRealResult({
810 .value = (lprod > rprod) ? lm : rm,
811 .unitFactor = (lprod > rprod) ? lhs->unitFactor() : rhs->unitFactor()
812 });
813 } else if (lhs->exprType() == INT_EXPR && rhs->exprType() == REAL_EXPR) {
814 vmint lm = lhs->asInt()->evalInt();
815 vmfloat rm = rhs->asReal()->evalReal();
816 vmfloat lprod = lm * lhs->unitFactor();
817 vmfloat rprod = rm * rhs->unitFactor();
818 return successRealResult({
819 .value = (lprod > rprod) ? lm : rm,
820 .unitFactor = (lprod > rprod) ? lhs->unitFactor() : rhs->unitFactor()
821 });
822 } else {
823 vmint lm = lhs->asInt()->evalInt();
824 vmint rm = rhs->asInt()->evalInt();
825 vmfloat lprod = lm * lhs->unitFactor();
826 vmfloat rprod = rm * rhs->unitFactor();
827 return successIntResult({
828 .value = (lprod > rprod) ? lm : rm,
829 .unitFactor = (lprod > rprod) ? lhs->unitFactor() : rhs->unitFactor()
830 });
831 }
832 }
833
834 ///////////////////////////////////////////////////////////////////////////
835 // built-in script function: array_equal()
836
837 bool CoreVMFunction_array_equal::acceptsArgType(vmint iArg, ExprType_t type) const {
838 return isArray(type);
839 }
840
841 void CoreVMFunction_array_equal::checkArgs(VMFnArgs* args,
842 std::function<void(String)> err,
843 std::function<void(String)> wrn)
844 {
845 // super class checks
846 Super::checkArgs(args, err, wrn);
847
848 // own checks ...
849 if (args->arg(0)->exprType() != args->arg(1)->exprType()) {
850 String a = typeStr(args->arg(0)->exprType());
851 String b = typeStr(args->arg(1)->exprType());
852 err("Argument 1 is " + a + ", whereas argument 2 is " + b + ".");
853 return;
854 }
855 if (args->arg(0)->asArray()->arraySize() !=
856 args->arg(1)->asArray()->arraySize())
857 {
858 wrn("Result of function call is always false, since the passed two arrays were declared with different array sizes.");
859 }
860 }
861
862 VMFnResult* CoreVMFunction_array_equal::exec(VMFnArgs* args) {
863 VMArrayExpr* l = args->arg(0)->asArray();
864 VMArrayExpr* r = args->arg(1)->asArray();
865 if (l->arraySize() != r->arraySize()) {
866 //wrnMsg("array_equal(): the two arrays differ in size");
867 return successResult(0); // false
868 }
869 const vmint n = l->arraySize();
870 // checkArgs() above ensured that we either have INT_ARR_EXPR on both sides
871 // or REAL_ARR_EXPR on both sides, so we can simplify here (a bit)
872 if (l->exprType() == INT_ARR_EXPR) {
873 VMIntArrayExpr* lia = l->asIntArray();
874 VMIntArrayExpr* ria = r->asIntArray();
875 for (vmint i = 0; i < n; ++i) {
876 vmint lvalue = lia->evalIntElement(i);
877 vmint rvalue = ria->evalIntElement(i);
878 vmfloat lfactor = lia->unitFactorOfElement(i);
879 vmfloat rfactor = ria->unitFactorOfElement(i);
880 if (lfactor == rfactor) {
881 if (lvalue != rvalue)
882 return successResult(0); // false
883 else
884 continue;
885 }
886 if (lfactor < rfactor) {
887 if (lvalue != Unit::convIntToUnitFactor(rvalue, rfactor, lfactor))
888 return successResult(0); // false
889 else
890 continue;
891 } else {
892 if (rvalue != Unit::convIntToUnitFactor(lvalue, lfactor, rfactor))
893 return successResult(0); // false
894 else
895 continue;
896 }
897 }
898 } else {
899 VMRealArrayExpr* lra = l->asRealArray();
900 VMRealArrayExpr* rra = r->asRealArray();
901 for (vmint i = 0; i < n; ++i) {
902 vmfloat lvalue = lra->evalRealElement(i);
903 vmfloat rvalue = rra->evalRealElement(i);
904 vmfloat lfactor = lra->unitFactorOfElement(i);
905 vmfloat rfactor = rra->unitFactorOfElement(i);
906 if (lfactor == rfactor) {
907 if (!_fEqualX(lvalue, rvalue))
908 return successResult(0); // false
909 else
910 continue;
911 }
912 if (lfactor < rfactor) {
913 if (!_fEqualX(lvalue, Unit::convRealToUnitFactor(rvalue, rfactor, lfactor)))
914 return successResult(0); // false
915 else
916 continue;
917 } else {
918 if (!_fEqualX(rvalue, Unit::convRealToUnitFactor(lvalue, lfactor, rfactor)))
919 return successResult(0); // false
920 else
921 continue;
922 }
923 }
924 }
925 return successResult(1); // true
926 }
927
928 ///////////////////////////////////////////////////////////////////////////
929 // built-in script function: search()
930
931 bool CoreVMFunction_search::acceptsArgType(vmint iArg, ExprType_t type) const {
932 if (iArg == 0)
933 return isArray(type);
934 else
935 return type == INT_EXPR || type == REAL_EXPR;
936 }
937
938 void CoreVMFunction_search::checkArgs(VMFnArgs* args,
939 std::function<void(String)> err,
940 std::function<void(String)> wrn)
941 {
942 // super class checks
943 Super::checkArgs(args, err, wrn);
944
945 // own checks ...
946 if (args->arg(0)->exprType() == INT_ARR_EXPR &&
947 args->arg(1)->exprType() != INT_EXPR)
948 {
949 String a = typeStr(INT_ARR_EXPR);
950 String bIs = typeStr(args->arg(1)->exprType());
951 String bShould = typeStr(INT_EXPR);
952 err("Argument 1 is " + a + ", hence argument 2 should be " + bShould + ", is " + bIs + " though.");
953 return;
954 }
955 if (args->arg(0)->exprType() == REAL_ARR_EXPR &&
956 args->arg(1)->exprType() != REAL_EXPR)
957 {
958 String a = typeStr(REAL_ARR_EXPR);
959 String bIs = typeStr(args->arg(1)->exprType());
960 String bShould = typeStr(REAL_EXPR);
961 err("Argument 1 is " + a + ", hence argument 2 should be " + bShould + ", is " + bIs + " though.");
962 return;
963 }
964 }
965
966 VMFnResult* CoreVMFunction_search::exec(VMFnArgs* args) {
967 VMArrayExpr* a = args->arg(0)->asArray();
968 const vmint n = a->arraySize();
969 if (a->exprType() == INT_ARR_EXPR) {
970 const vmint needle = args->arg(1)->asInt()->evalInt();
971 VMIntArrayExpr* intArray = a->asIntArray();
972 for (vmint i = 0; i < n; ++i)
973 if (intArray->evalIntElement(i) == needle)
974 return successResult(i);
975 } else { // real array ...
976 const vmfloat needle = args->arg(1)->asReal()->evalReal();
977 VMRealArrayExpr* realArray = a->asRealArray();
978 for (vmint i = 0; i < n; ++i) {
979 const vmfloat value = realArray->evalRealElement(i);
980 if (_fEqualX(value, needle))
981 return successResult(i);
982 }
983 }
984 return successResult(-1); // not found
985 }
986
987 ///////////////////////////////////////////////////////////////////////////
988 // built-in script function: sort()
989
990 bool CoreVMFunction_sort::acceptsArgType(vmint iArg, ExprType_t type) const {
991 if (iArg == 0)
992 return isArray(type);
993 else
994 return type == INT_EXPR;
995 }
996
997 // The following structs and template classes act as adapters for allowing to
998 // use std sort algorithms on our arrays. It might look a bit more complicated
999 // than it ought to be, but there is one reason for the large amount of
1000 // 'adapter' code below: the STL std algorithms rely on 'lvalues' to do their
1001 // (e.g. sorting) jobs, that is they expect containers to have 'localizeable'
1002 // data which essentially means their data should reside somewhere in memory and
1003 // directly be accessible (readable and writable) there, which is not the case
1004 // with our VM interfaces which actually always require virtual getter and
1005 // setter methods to be called instead. So we must emulate lvalues by custom
1006 // classes/structs which forward between our getters/setters and the lvalue
1007 // access operators used by the STL std algorithms.
1008
1009 struct IntArrayAccessor {
1010 static inline vmint getPrimaryValue(VMIntArrayExpr* arr, vmint index) {
1011 return arr->evalIntElement(index);
1012 }
1013 static inline void setPrimaryValue(VMIntArrayExpr* arr, vmint index, vmint value) {
1014 arr->assignIntElement(index, value);
1015 }
1016 };
1017
1018 struct RealArrayAccessor {
1019 static inline vmfloat getPrimaryValue(VMRealArrayExpr* arr, vmint index) {
1020 return arr->evalRealElement(index);
1021 }
1022 static inline void setPrimaryValue(VMRealArrayExpr* arr, vmint index, vmfloat value) {
1023 arr->assignRealElement(index, value);
1024 }
1025 };
1026
1027 template<class T_array> // i.e. T_array is either VMIntArrayExpr or VMRealArrayExpr
1028 struct ArrElemPOD {
1029 T_array* m_array;
1030 vmint m_index;
1031 };
1032
1033 // This class is used for temporary values by std::sort().
1034 template<class T_value> // i.e. T_value is either vmint or vmfloat
1035 struct ScalarNmbrVal {
1036 T_value primValue;
1037 vmfloat unitFactor;
1038
1039 inline bool operator<(const ScalarNmbrVal& other) const {
1040 return getProdValue() < other.getProdValue();
1041 }
1042 inline bool operator>(const ScalarNmbrVal& other) const {
1043 return getProdValue() > other.getProdValue();
1044 }
1045 inline vmfloat getProdValue() const {
1046 // simple solution for both vmint and vmfloat, should be fine for just sorting
1047 return primValue * unitFactor;
1048 }
1049 };
1050
1051 // This class emulates lvalue access (access by reference) which is used by ArrExprIter::operator*() below.
1052 template<class T_array, // T_array is either VMIntArrayExpr or VMRealArrayExpr
1053 class T_value, // T_value is either vmint or vmfloat
1054 class T_accessor> // T_accessor is either IntArrayAccessor or RealArrayAccessor
1055 class ArrElemRef : protected ArrElemPOD<T_array> {
1056 public:
1057 typedef ::LinuxSampler::ScalarNmbrVal<T_value> ScalarNmbrVal; // GCC 8.x requires this very detailed form of typedef (that is ::LinuxSampler:: as prefix), IMO a GCC bug
1058
1059 inline ArrElemRef(T_array* a, vmint index) {
1060 this->m_array = a;
1061 this->m_index = index;
1062 }
1063 inline ArrElemRef(const ArrElemRef& ref) {
1064 this->m_array = ref.m_array;
1065 this->m_index = ref.m_index;
1066 }
1067 inline ArrElemRef& operator=(const ArrElemRef& e) {
1068 setPrimValue(e.getPrimValue());
1069 setUnitFactor(e.getUnitFactor());
1070 return *this;
1071 }
1072 inline ArrElemRef& operator=(ScalarNmbrVal value) {
1073 setPrimValue(value.primValue);
1074 setUnitFactor(value.unitFactor);
1075 return *this;
1076 }
1077 inline bool operator==(const ArrElemRef& e) const {
1078 return getProdValue() == e.getProdValue();
1079 }
1080 inline bool operator!=(const ArrElemRef& e) const {
1081 return !(operator==(e));
1082 }
1083 inline bool operator<(const ArrElemRef& e) const {
1084 return getProdValue() < e.getProdValue();
1085 }
1086 inline bool operator>(const ArrElemRef& e) const {
1087 return getProdValue() > e.getProdValue();
1088 }
1089 inline bool operator<=(const ArrElemRef& e) const {
1090 return getProdValue() <= e.getProdValue();
1091 }
1092 inline bool operator>=(const ArrElemRef& e) const {
1093 return getProdValue() >= e.getProdValue();
1094 }
1095 inline bool operator==(const ScalarNmbrVal& s) const {
1096 return getProdValue() == s.getProdValue();
1097 }
1098 inline bool operator!=(const ScalarNmbrVal& s) const {
1099 return !(operator==(s));
1100 }
1101 inline bool operator<(const ScalarNmbrVal& s) const {
1102 return getProdValue() < s.getProdValue();
1103 }
1104 inline bool operator>(const ScalarNmbrVal& s) const {
1105 return getProdValue() > s.getProdValue();
1106 }
1107 inline bool operator<=(const ScalarNmbrVal& s) const {
1108 return getProdValue() <= s.getProdValue();
1109 }
1110 inline bool operator>=(const ScalarNmbrVal& s) const {
1111 return getProdValue() >= s.getProdValue();
1112 }
1113 inline operator ScalarNmbrVal() {
1114 return {
1115 .primValue = getPrimValue() ,
1116 .unitFactor = getUnitFactor()
1117 };
1118 }
1119 protected:
1120 inline T_value getPrimValue() const {
1121 return T_accessor::getPrimaryValue( this->m_array, this->m_index );
1122 }
1123 inline void setPrimValue(T_value value) {
1124 T_accessor::setPrimaryValue( this->m_array, this->m_index, value );
1125 }
1126 inline vmfloat getUnitFactor() const {
1127 return this->m_array->unitFactorOfElement(this->m_index);
1128 }
1129 inline void setUnitFactor(vmfloat factor) {
1130 this->m_array->assignElementUnitFactor(this->m_index, factor);
1131 }
1132 inline vmfloat getProdValue() const {
1133 // simple solution for both vmint and vmfloat, should be fine for just sorting
1134 vmfloat primary = (vmfloat) getPrimValue();
1135 vmfloat factor = getUnitFactor();
1136 return primary * factor;
1137 }
1138
1139 // allow swap() functions below to access protected methods here
1140 friend void swap(class ArrElemRef<T_array,T_value,T_accessor> a,
1141 class ArrElemRef<T_array,T_value,T_accessor> b);
1142 };
1143
1144 // custom iterator class to be used by std:sort() on our VM arrays
1145 template<class T_array, class T_value, class T_accessor>
1146 class ArrExprIter : public ArrElemPOD<T_array> {
1147 public:
1148 typedef std::random_access_iterator_tag iterator_category;
1149 typedef ssize_t difference_type;
1150 typedef ::LinuxSampler::ArrElemRef<T_array, T_value, T_accessor> ArrElemRef; // GCC 8.x requires this very detailed form of typedef (that is ::LinuxSampler:: as prefix), IMO a GCC bug
1151 typedef ArrElemRef reference; // type used by STL for access by reference
1152 typedef void pointer; // type used by STL for -> operator result, we don't use that operator at all so just void it
1153 typedef ScalarNmbrVal<T_value> value_type; // type used by STL for temporary values
1154
1155 ArrExprIter(T_array* a, vmint index) {
1156 this->m_array = a;
1157 this->m_index = index;
1158 }
1159 ArrExprIter(const ArrElemRef& ref) {
1160 this->m_array = ref.m_array;
1161 this->m_index = ref.m_index;
1162 }
1163 inline ArrElemRef operator*() {
1164 return ArrElemRef(this->m_array, this->m_index);
1165 }
1166 inline ArrExprIter& operator++() { // prefix increment
1167 ++(this->m_index);
1168 return *this;
1169 }
1170 inline ArrExprIter& operator--() { // prefix decrement
1171 --(this->m_index);
1172 return *this;
1173 }
1174 inline ArrExprIter operator++(int) { // postfix increment
1175 ArrExprIter it = *this;
1176 ++(this->m_index);
1177 return it;
1178 }
1179 inline ArrExprIter operator--(int) { // postfix decrement
1180 ArrExprIter it = *this;
1181 --(this->m_index);
1182 return it;
1183 }
1184 inline ArrExprIter& operator+=(difference_type d) {
1185 this->m_index += d;
1186 return *this;
1187 }
1188 inline ArrExprIter& operator-=(difference_type d) {
1189 this->m_index -= d;
1190 return *this;
1191 }
1192 inline bool operator==(const ArrExprIter& other) const {
1193 return this->m_index == other.m_index;
1194 }
1195 inline bool operator!=(const ArrExprIter& other) const {
1196 return this->m_index != other.m_index;
1197 }
1198 inline bool operator<(const ArrExprIter& other) const {
1199 return this->m_index < other.m_index;
1200 }
1201 inline bool operator>(const ArrExprIter& other) const {
1202 return this->m_index > other.m_index;
1203 }
1204 inline bool operator<=(const ArrExprIter& other) const {
1205 return this->m_index <= other.m_index;
1206 }
1207 inline bool operator>=(const ArrExprIter& other) const {
1208 return this->m_index >= other.m_index;
1209 }
1210 inline difference_type operator+(const ArrExprIter& other) const {
1211 return this->m_index + other.m_index;
1212 }
1213 inline difference_type operator-(const ArrExprIter& other) const {
1214 return this->m_index - other.m_index;
1215 }
1216 inline ArrExprIter operator-(difference_type d) const {
1217 return ArrExprIter(this->m_array, this->m_index - d);
1218 }
1219 inline ArrExprIter operator+(difference_type d) const {
1220 return ArrExprIter(this->m_array, this->m_index + d);
1221 }
1222 inline ArrExprIter operator*(difference_type factor) const {
1223 return ArrExprIter(this->m_array, this->m_index * factor);
1224 }
1225 };
1226
1227 typedef ArrExprIter<VMIntArrayExpr,vmint,IntArrayAccessor> IntArrExprIter;
1228 typedef ArrExprIter<VMRealArrayExpr,vmfloat,RealArrayAccessor> RealArrExprIter;
1229
1230 // intentionally not a template function to avoid potential clashes with other (i.e. system's) swap() functions
1231 inline void swap(IntArrExprIter::ArrElemRef a,
1232 IntArrExprIter::ArrElemRef b)
1233 {
1234 vmint valueA = a.getPrimValue();
1235 vmint valueB = b.getPrimValue();
1236 vmfloat factorA = a.getUnitFactor();
1237 vmfloat factorB = b.getUnitFactor();
1238 a.setPrimValue(valueB);
1239 a.setUnitFactor(factorB);
1240 b.setPrimValue(valueA);
1241 b.setUnitFactor(factorA);
1242 }
1243
1244 // intentionally not a template function to avoid potential clashes with other (i.e. system's) swap() functions
1245 inline void swap(RealArrExprIter::ArrElemRef a,
1246 RealArrExprIter::ArrElemRef b)
1247 {
1248 vmfloat valueA = a.getPrimValue();
1249 vmfloat valueB = b.getPrimValue();
1250 vmfloat factorA = a.getUnitFactor();
1251 vmfloat factorB = b.getUnitFactor();
1252 a.setPrimValue(valueB);
1253 a.setUnitFactor(factorB);
1254 b.setPrimValue(valueA);
1255 b.setUnitFactor(factorA);
1256 }
1257
1258 // used to sort in descending order (unlike the default behaviour of std::sort() which is ascending order)
1259 template<class T> // T is either IntArrExprIter or RealArrExprIter
1260 struct DescArrExprSorter {
1261 inline bool operator()(const typename T::value_type a, const typename T::value_type b) const {
1262 return a > b;
1263 }
1264 };
1265
1266 VMFnResult* CoreVMFunction_sort::exec(VMFnArgs* args) {
1267 const bool bAscending =
1268 (args->argsCount() < 2) ? true : !args->arg(1)->asInt()->evalInt();
1269
1270 if (args->arg(0)->exprType() == INT_ARR_EXPR) {
1271 VMIntArrayExpr* a = args->arg(0)->asIntArray();
1272 vmint n = a->arraySize();
1273 IntArrExprIter itBegin(a, 0);
1274 IntArrExprIter itEnd(a, n);
1275 if (bAscending) {
1276 std::sort(itBegin, itEnd);
1277 } else {
1278 DescArrExprSorter<IntArrExprIter> sorter;
1279 std::sort(itBegin, itEnd, sorter);
1280 }
1281 } else {
1282 VMRealArrayExpr* a = args->arg(0)->asRealArray();
1283 vmint n = a->arraySize();
1284 RealArrExprIter itBegin(a, 0);
1285 RealArrExprIter itEnd(a, n);
1286 if (bAscending) {
1287 std::sort(itBegin, itEnd);
1288 } else {
1289 DescArrExprSorter<RealArrExprIter> sorter;
1290 std::sort(itBegin, itEnd, sorter);
1291 }
1292 }
1293
1294 return successResult();
1295 }
1296
1297 ///////////////////////////////////////////////////////////////////////////
1298 // built-in script function: real_to_int() and int()
1299
1300 StdUnit_t CoreVMFunction_real_to_int::returnUnitType(VMFnArgs* args) {
1301 return args->arg(0)->asNumber()->unitType();
1302 }
1303
1304 bool CoreVMFunction_real_to_int::returnsFinal(VMFnArgs* args) {
1305 return args->arg(0)->asNumber()->isFinal();
1306 }
1307
1308 VMFnResult* CoreVMFunction_real_to_int::exec(VMFnArgs* args) {
1309 VMRealExpr* realExpr = args->arg(0)->asReal();
1310 vmfloat f = realExpr->evalReal();
1311 return successResult({
1312 .value = vmint(f),
1313 .unitFactor = realExpr->unitFactor()
1314 });
1315 }
1316
1317 ///////////////////////////////////////////////////////////////////////////
1318 // built-in script function: int_to_real() and real()
1319
1320 StdUnit_t CoreVMFunction_int_to_real::returnUnitType(VMFnArgs* args) {
1321 return args->arg(0)->asNumber()->unitType();
1322 }
1323
1324 bool CoreVMFunction_int_to_real::returnsFinal(VMFnArgs* args) {
1325 return args->arg(0)->asNumber()->isFinal();
1326 }
1327
1328 VMFnResult* CoreVMFunction_int_to_real::exec(VMFnArgs* args) {
1329 VMIntExpr* intExpr = args->arg(0)->asInt();
1330 vmint i = intExpr->evalInt();
1331 return successResult({
1332 .value = vmfloat(i),
1333 .unitFactor = intExpr->unitFactor()
1334 });
1335 }
1336
1337 ///////////////////////////////////////////////////////////////////////////
1338 // built-in script function: round()
1339
1340 StdUnit_t CoreVMFunction_round::returnUnitType(VMFnArgs* args) {
1341 return args->arg(0)->asNumber()->unitType();
1342 }
1343
1344 bool CoreVMFunction_round::returnsFinal(VMFnArgs* args) {
1345 return args->arg(0)->asNumber()->isFinal();
1346 }
1347
1348 VMFnResult* CoreVMFunction_round::exec(VMFnArgs* args) {
1349 VMRealExpr* realExpr = args->arg(0)->asReal();
1350 vmfloat f = realExpr->evalReal();
1351 if (sizeof(vmfloat) == sizeof(float))
1352 f = ::roundf(f);
1353 else
1354 f = ::round(f);
1355 return successResult({
1356 .value = f,
1357 .unitFactor = realExpr->unitFactor()
1358 });
1359 }
1360
1361 ///////////////////////////////////////////////////////////////////////////
1362 // built-in script function: ceil()
1363
1364 StdUnit_t CoreVMFunction_ceil::returnUnitType(VMFnArgs* args) {
1365 return args->arg(0)->asNumber()->unitType();
1366 }
1367
1368 bool CoreVMFunction_ceil::returnsFinal(VMFnArgs* args) {
1369 return args->arg(0)->asNumber()->isFinal();
1370 }
1371
1372 VMFnResult* CoreVMFunction_ceil::exec(VMFnArgs* args) {
1373 VMRealExpr* realExpr = args->arg(0)->asReal();
1374 vmfloat f = realExpr->evalReal();
1375 if (sizeof(vmfloat) == sizeof(float))
1376 f = ::ceilf(f);
1377 else
1378 f = ::ceil(f);
1379 return successResult({
1380 .value = f,
1381 .unitFactor = realExpr->unitFactor()
1382 });
1383 }
1384
1385 ///////////////////////////////////////////////////////////////////////////
1386 // built-in script function: floor()
1387
1388 StdUnit_t CoreVMFunction_floor::returnUnitType(VMFnArgs* args) {
1389 return args->arg(0)->asNumber()->unitType();
1390 }
1391
1392 bool CoreVMFunction_floor::returnsFinal(VMFnArgs* args) {
1393 return args->arg(0)->asNumber()->isFinal();
1394 }
1395
1396 VMFnResult* CoreVMFunction_floor::exec(VMFnArgs* args) {
1397 VMRealExpr* realExpr = args->arg(0)->asReal();
1398 vmfloat f = realExpr->evalReal();
1399 if (sizeof(vmfloat) == sizeof(float))
1400 f = ::floorf(f);
1401 else
1402 f = ::floor(f);
1403 return successResult({
1404 .value = f,
1405 .unitFactor = realExpr->unitFactor()
1406 });
1407 }
1408
1409 ///////////////////////////////////////////////////////////////////////////
1410 // built-in script function: sqrt()
1411
1412 StdUnit_t CoreVMFunction_sqrt::returnUnitType(VMFnArgs* args) {
1413 return args->arg(0)->asNumber()->unitType();
1414 }
1415
1416 bool CoreVMFunction_sqrt::returnsFinal(VMFnArgs* args) {
1417 return args->arg(0)->asNumber()->isFinal();
1418 }
1419
1420 VMFnResult* CoreVMFunction_sqrt::exec(VMFnArgs* args) {
1421 VMRealExpr* realExpr = args->arg(0)->asReal();
1422 vmfloat f = realExpr->evalReal();
1423 if (sizeof(vmfloat) == sizeof(float))
1424 f = ::sqrtf(f);
1425 else
1426 f = ::sqrt(f);
1427 return successResult({
1428 .value = f,
1429 .unitFactor = realExpr->unitFactor()
1430 });
1431 }
1432
1433 ///////////////////////////////////////////////////////////////////////////
1434 // built-in script function: log()
1435
1436 StdUnit_t CoreVMFunction_log::returnUnitType(VMFnArgs* args) {
1437 return args->arg(0)->asNumber()->unitType();
1438 }
1439
1440 bool CoreVMFunction_log::returnsFinal(VMFnArgs* args) {
1441 return args->arg(0)->asNumber()->isFinal();
1442 }
1443
1444 VMFnResult* CoreVMFunction_log::exec(VMFnArgs* args) {
1445 VMRealExpr* realExpr = args->arg(0)->asReal();
1446 vmfloat f = realExpr->evalReal();
1447 if (sizeof(vmfloat) == sizeof(float))
1448 f = ::logf(f);
1449 else
1450 f = ::log(f);
1451 return successResult({
1452 .value = f,
1453 .unitFactor = realExpr->unitFactor()
1454 });
1455 }
1456
1457 ///////////////////////////////////////////////////////////////////////////
1458 // built-in script function: log2()
1459
1460 StdUnit_t CoreVMFunction_log2::returnUnitType(VMFnArgs* args) {
1461 return args->arg(0)->asNumber()->unitType();
1462 }
1463
1464 bool CoreVMFunction_log2::returnsFinal(VMFnArgs* args) {
1465 return args->arg(0)->asNumber()->isFinal();
1466 }
1467
1468 VMFnResult* CoreVMFunction_log2::exec(VMFnArgs* args) {
1469 VMRealExpr* realExpr = args->arg(0)->asReal();
1470 vmfloat f = realExpr->evalReal();
1471 if (sizeof(vmfloat) == sizeof(float))
1472 f = ::log2f(f);
1473 else
1474 f = ::log2(f);
1475 return successResult({
1476 .value = f,
1477 .unitFactor = realExpr->unitFactor()
1478 });
1479 }
1480
1481 ///////////////////////////////////////////////////////////////////////////
1482 // built-in script function: log10()
1483
1484 StdUnit_t CoreVMFunction_log10::returnUnitType(VMFnArgs* args) {
1485 return args->arg(0)->asNumber()->unitType();
1486 }
1487
1488 bool CoreVMFunction_log10::returnsFinal(VMFnArgs* args) {
1489 return args->arg(0)->asNumber()->isFinal();
1490 }
1491
1492 VMFnResult* CoreVMFunction_log10::exec(VMFnArgs* args) {
1493 VMRealExpr* realExpr = args->arg(0)->asReal();
1494 vmfloat f = realExpr->evalReal();
1495 if (sizeof(vmfloat) == sizeof(float))
1496 f = ::log10f(f);
1497 else
1498 f = ::log10(f);
1499 return successResult({
1500 .value = f,
1501 .unitFactor = realExpr->unitFactor()
1502 });
1503 }
1504
1505 ///////////////////////////////////////////////////////////////////////////
1506 // built-in script function: exp()
1507
1508 StdUnit_t CoreVMFunction_exp::returnUnitType(VMFnArgs* args) {
1509 return args->arg(0)->asNumber()->unitType();
1510 }
1511
1512 bool CoreVMFunction_exp::returnsFinal(VMFnArgs* args) {
1513 return args->arg(0)->asNumber()->isFinal();
1514 }
1515
1516 VMFnResult* CoreVMFunction_exp::exec(VMFnArgs* args) {
1517 VMRealExpr* realExpr = args->arg(0)->asReal();
1518 vmfloat f = realExpr->evalReal();
1519 if (sizeof(vmfloat) == sizeof(float))
1520 f = ::expf(f);
1521 else
1522 f = ::exp(f);
1523 return successResult({
1524 .value = f,
1525 .unitFactor = realExpr->unitFactor()
1526 });
1527 }
1528
1529 ///////////////////////////////////////////////////////////////////////////
1530 // built-in script function: pow()
1531
1532 bool CoreVMFunction_pow::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {
1533 if (iArg == 0)
1534 return true;
1535 else
1536 return type == VM_NO_UNIT;
1537 }
1538
1539 bool CoreVMFunction_pow::acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const {
1540 return iArg == 0;
1541 }
1542
1543 StdUnit_t CoreVMFunction_pow::returnUnitType(VMFnArgs* args) {
1544 // pow() only allows unit for its 1st argument
1545 return args->arg(0)->asNumber()->unitType();
1546 }
1547
1548 bool CoreVMFunction_pow::returnsFinal(VMFnArgs* args) {
1549 // pow() only allows 'final'ness for its 1st argument
1550 return args->arg(0)->asNumber()->isFinal();
1551 }
1552
1553 VMFnResult* CoreVMFunction_pow::exec(VMFnArgs* args) {
1554 VMRealExpr* arg0 = args->arg(0)->asReal();
1555 VMRealExpr* arg1 = args->arg(1)->asReal();
1556 vmfloat a = arg0->evalReal();
1557 vmfloat b = arg1->evalReal();
1558 if (sizeof(vmfloat) == sizeof(float)) {
1559 return successResult({
1560 .value = ::powf(a,b),
1561 .unitFactor = arg0->unitFactor()
1562 });
1563 } else {
1564 return successResult({
1565 .value = static_cast<vmfloat>(::pow(a,b)),
1566 .unitFactor = arg0->unitFactor()
1567 });
1568 }
1569 }
1570
1571 ///////////////////////////////////////////////////////////////////////////
1572 // built-in script function: sin()
1573
1574 StdUnit_t CoreVMFunction_sin::returnUnitType(VMFnArgs* args) {
1575 return args->arg(0)->asNumber()->unitType();
1576 }
1577
1578 bool CoreVMFunction_sin::returnsFinal(VMFnArgs* args) {
1579 return args->arg(0)->asNumber()->isFinal();
1580 }
1581
1582 VMFnResult* CoreVMFunction_sin::exec(VMFnArgs* args) {
1583 VMRealExpr* realExpr = args->arg(0)->asReal();
1584 vmfloat f = realExpr->evalReal();
1585 if (sizeof(vmfloat) == sizeof(float))
1586 f = ::sinf(f);
1587 else
1588 f = ::sin(f);
1589 return successResult({
1590 .value = f,
1591 .unitFactor = realExpr->unitFactor()
1592 });
1593 }
1594
1595 ///////////////////////////////////////////////////////////////////////////
1596 // built-in script function: cos()
1597
1598 StdUnit_t CoreVMFunction_cos::returnUnitType(VMFnArgs* args) {
1599 return args->arg(0)->asNumber()->unitType();
1600 }
1601
1602 bool CoreVMFunction_cos::returnsFinal(VMFnArgs* args) {
1603 return args->arg(0)->asNumber()->isFinal();
1604 }
1605
1606 VMFnResult* CoreVMFunction_cos::exec(VMFnArgs* args) {
1607 VMRealExpr* realExpr = args->arg(0)->asReal();
1608 vmfloat f = realExpr->evalReal();
1609 if (sizeof(vmfloat) == sizeof(float))
1610 f = ::cosf(f);
1611 else
1612 f = ::cos(f);
1613 return successResult({
1614 .value = f,
1615 .unitFactor = realExpr->unitFactor()
1616 });
1617 }
1618
1619 ///////////////////////////////////////////////////////////////////////////
1620 // built-in script function: tan()
1621
1622 StdUnit_t CoreVMFunction_tan::returnUnitType(VMFnArgs* args) {
1623 return args->arg(0)->asNumber()->unitType();
1624 }
1625
1626 bool CoreVMFunction_tan::returnsFinal(VMFnArgs* args) {
1627 return args->arg(0)->asNumber()->isFinal();
1628 }
1629
1630 VMFnResult* CoreVMFunction_tan::exec(VMFnArgs* args) {
1631 VMRealExpr* realExpr = args->arg(0)->asReal();
1632 vmfloat f = realExpr->evalReal();
1633 if (sizeof(vmfloat) == sizeof(float))
1634 f = ::tanf(f);
1635 else
1636 f = ::tan(f);
1637 return successResult({
1638 .value = f,
1639 .unitFactor = realExpr->unitFactor()
1640 });
1641 }
1642
1643 ///////////////////////////////////////////////////////////////////////////
1644 // built-in script function: asin()
1645
1646 StdUnit_t CoreVMFunction_asin::returnUnitType(VMFnArgs* args) {
1647 return args->arg(0)->asNumber()->unitType();
1648 }
1649
1650 bool CoreVMFunction_asin::returnsFinal(VMFnArgs* args) {
1651 return args->arg(0)->asNumber()->isFinal();
1652 }
1653
1654 VMFnResult* CoreVMFunction_asin::exec(VMFnArgs* args) {
1655 VMRealExpr* realExpr = args->arg(0)->asReal();
1656 vmfloat f = realExpr->evalReal();
1657 if (sizeof(vmfloat) == sizeof(float))
1658 f = ::asinf(f);
1659 else
1660 f = ::asin(f);
1661 return successResult({
1662 .value = f,
1663 .unitFactor = realExpr->unitFactor()
1664 });
1665 }
1666
1667 ///////////////////////////////////////////////////////////////////////////
1668 // built-in script function: acos()
1669
1670 StdUnit_t CoreVMFunction_acos::returnUnitType(VMFnArgs* args) {
1671 return args->arg(0)->asNumber()->unitType();
1672 }
1673
1674 bool CoreVMFunction_acos::returnsFinal(VMFnArgs* args) {
1675 return args->arg(0)->asNumber()->isFinal();
1676 }
1677
1678 VMFnResult* CoreVMFunction_acos::exec(VMFnArgs* args) {
1679 VMRealExpr* realExpr = args->arg(0)->asReal();
1680 vmfloat f = realExpr->evalReal();
1681 if (sizeof(vmfloat) == sizeof(float))
1682 f = ::acosf(f);
1683 else
1684 f = ::acos(f);
1685 return successResult({
1686 .value = f,
1687 .unitFactor = realExpr->unitFactor()
1688 });
1689 }
1690
1691 ///////////////////////////////////////////////////////////////////////////
1692 // built-in script function: atan()
1693
1694 StdUnit_t CoreVMFunction_atan::returnUnitType(VMFnArgs* args) {
1695 return args->arg(0)->asNumber()->unitType();
1696 }
1697
1698 bool CoreVMFunction_atan::returnsFinal(VMFnArgs* args) {
1699 return args->arg(0)->asNumber()->isFinal();
1700 }
1701
1702 VMFnResult* CoreVMFunction_atan::exec(VMFnArgs* args) {
1703 VMRealExpr* realExpr = args->arg(0)->asReal();
1704 vmfloat f = realExpr->evalReal();
1705 if (sizeof(vmfloat) == sizeof(float))
1706 f = ::atanf(f);
1707 else
1708 f = ::atan(f);
1709 return successResult({
1710 .value = f,
1711 .unitFactor = realExpr->unitFactor()
1712 });
1713 }
1714
1715 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC