--- linuxsampler/trunk/src/scriptvm/CoreVMFunctions.cpp 2019/08/30 11:40:25 3581 +++ linuxsampler/trunk/src/scriptvm/CoreVMFunctions.cpp 2019/09/04 15:10:06 3596 @@ -117,58 +117,58 @@ } /////////////////////////////////////////////////////////////////////////// -// class VMScalarNumberResultFunction +// class VMNumberResultFunction -VMFnResult* VMScalarNumberResultFunction::errorResult(vmint i) { +VMFnResult* VMNumberResultFunction::errorResult(vmint i) { intResult.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED); intResult.value = i; intResult.unitPrefixFactor = VM_NO_FACTOR; return &intResult; } -VMFnResult* VMScalarNumberResultFunction::errorResult(vmfloat f) { +VMFnResult* VMNumberResultFunction::errorResult(vmfloat f) { realResult.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED); realResult.value = f; realResult.unitPrefixFactor = VM_NO_FACTOR; return &realResult; } -VMFnResult* VMScalarNumberResultFunction::successResult(vmint i) { +VMFnResult* VMNumberResultFunction::successResult(vmint i) { intResult.flags = STMT_SUCCESS; intResult.value = i; intResult.unitPrefixFactor = VM_NO_FACTOR; return &intResult; } -VMFnResult* VMScalarNumberResultFunction::successResult(vmfloat f) { +VMFnResult* VMNumberResultFunction::successResult(vmfloat f) { realResult.flags = STMT_SUCCESS; realResult.value = f; realResult.unitPrefixFactor = VM_NO_FACTOR; return &realResult; } -VMFnResult* VMScalarNumberResultFunction::errorIntResult(VMIntFnResDef res) { +VMFnResult* VMNumberResultFunction::errorIntResult(VMIntFnResDef res) { intResult.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED); intResult.value = res.value; intResult.unitPrefixFactor = res.unitFactor; return &intResult; } -VMFnResult* VMScalarNumberResultFunction::errorRealResult(VMRealFnResDef res) { +VMFnResult* VMNumberResultFunction::errorRealResult(VMRealFnResDef res) { realResult.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED); realResult.value = res.value; realResult.unitPrefixFactor = res.unitFactor; return &realResult; } -VMFnResult* VMScalarNumberResultFunction::successIntResult(VMIntFnResDef res) { +VMFnResult* VMNumberResultFunction::successIntResult(VMIntFnResDef res) { intResult.flags = STMT_SUCCESS; intResult.value = res.value; intResult.unitPrefixFactor = res.unitFactor; return &intResult; } -VMFnResult* VMScalarNumberResultFunction::successRealResult(VMRealFnResDef res) { +VMFnResult* VMNumberResultFunction::successRealResult(VMRealFnResDef res) { realResult.flags = STMT_SUCCESS; realResult.value = res.value; realResult.unitPrefixFactor = res.unitFactor; @@ -277,22 +277,23 @@ /////////////////////////////////////////////////////////////////////////// // built-in script function: wait() +bool CoreVMFunction_wait::acceptsArgType(vmint iArg, ExprType_t type) const { + return type == INT_EXPR || type == REAL_EXPR; +} + bool CoreVMFunction_wait::acceptsArgUnitType(vmint iArg, StdUnit_t type) const { - if (iArg == 0) - return type == VM_NO_UNIT || type == VM_SECOND; - else - return type == VM_NO_UNIT; + return type == VM_NO_UNIT || type == VM_SECOND; } bool CoreVMFunction_wait::acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const { - return iArg == 0 && type == VM_SECOND; + return type == VM_SECOND; // only allow metric prefix(es) if 'seconds' is used as unit type } VMFnResult* CoreVMFunction_wait::exec(VMFnArgs* args) { ExecContext* ctx = dynamic_cast(vm->currentVMExecContext()); - VMIntExpr* expr = dynamic_cast(args->arg(0)); + VMNumberExpr* expr = args->arg(0)->asNumber(); StdUnit_t unit = expr->unitType(); - vmint us = (unit) ? expr->evalInt(VM_MICRO) : expr->evalInt(); + vmint us = (unit) ? expr->evalCastInt(VM_MICRO) : expr->evalCastInt(); if (us < 0) { wrnMsg("wait(): argument may not be negative! Aborting script!"); this->result.flags = STMT_ABORT_SIGNALLED; @@ -314,11 +315,11 @@ } StdUnit_t CoreVMFunction_abs::returnUnitType(VMFnArgs* args) { - return args->arg(0)->asScalarNumberExpr()->unitType(); + return args->arg(0)->asNumber()->unitType(); } bool CoreVMFunction_abs::returnsFinal(VMFnArgs* args) { - return args->arg(0)->asScalarNumberExpr()->isFinal(); + return args->arg(0)->asNumber()->isFinal(); } bool CoreVMFunction_abs::acceptsArgType(vmint iArg, ExprType_t type) const { @@ -330,13 +331,13 @@ if (arg->exprType() == REAL_EXPR) { VMRealExpr* expr = arg->asReal(); return successRealResult({ - .value = ::fabs(expr->evalReal()), + .value = static_cast(::fabs(expr->evalReal())), .unitFactor = expr->unitFactor() }); } else { VMIntExpr* expr = arg->asInt(); return successIntResult({ - .value = ::abs(expr->evalInt()), + .value = std::abs(expr->evalInt()), .unitFactor = expr->unitFactor() }); } @@ -353,12 +354,12 @@ StdUnit_t CoreVMFunction_random::returnUnitType(VMFnArgs* args) { // we ensure in checkArgs() below (which is called before this method here) // that both arguments must be of same unit type, so either one is fine here - return args->arg(0)->asScalarNumberExpr()->unitType(); + return args->arg(0)->asNumber()->unitType(); } bool CoreVMFunction_random::returnsFinal(VMFnArgs* args) { - return args->arg(0)->asScalarNumberExpr()->isFinal() || - args->arg(1)->asScalarNumberExpr()->isFinal(); + return args->arg(0)->asNumber()->isFinal() || + args->arg(1)->asNumber()->isFinal(); } bool CoreVMFunction_random::acceptsArgType(vmint iArg, ExprType_t type) const { @@ -373,19 +374,19 @@ Super::checkArgs(args, err, wrn); // own checks ... - if (args->arg(0)->asScalarNumberExpr()->unitType() != - args->arg(1)->asScalarNumberExpr()->unitType()) + if (args->arg(0)->asNumber()->unitType() != + args->arg(1)->asNumber()->unitType()) { - String a = unitTypeStr(args->arg(0)->asScalarNumberExpr()->unitType()); - String b = unitTypeStr(args->arg(1)->asScalarNumberExpr()->unitType()); + String a = unitTypeStr(args->arg(0)->asNumber()->unitType()); + String b = unitTypeStr(args->arg(1)->asNumber()->unitType()); err("Argument 1 has unit type " + a + ", whereas argument 2 has unit type " + b + "."); return; } - if (args->arg(0)->asScalarNumberExpr()->isFinal() != - args->arg(1)->asScalarNumberExpr()->isFinal()) + if (args->arg(0)->asNumber()->isFinal() != + args->arg(1)->asNumber()->isFinal()) { - String a = args->arg(0)->asScalarNumberExpr()->isFinal() ? "'final'" : "not 'final'"; - String b = args->arg(1)->asScalarNumberExpr()->isFinal() ? "'final'" : "not 'final'"; + String a = args->arg(0)->asNumber()->isFinal() ? "'final'" : "not 'final'"; + String b = args->arg(1)->asNumber()->isFinal() ? "'final'" : "not 'final'"; wrn("Argument 1 is " + a + ", whereas argument 2 is " + b + ", function result will be final."); } } @@ -393,8 +394,8 @@ VMFnResult* CoreVMFunction_random::exec(VMFnArgs* args) { float f = float(::rand()) / float(RAND_MAX); - VMScalarNumberExpr* arg0 = args->arg(0)->asScalarNumberExpr(); - VMScalarNumberExpr* arg1 = args->arg(1)->asScalarNumberExpr(); + VMNumberExpr* arg0 = args->arg(0)->asNumber(); + VMNumberExpr* arg1 = args->arg(1)->asNumber(); if (arg0->exprType() == INT_EXPR && arg1->exprType() == INT_EXPR) { vmint iMin = args->arg(0)->asInt()->evalInt(); @@ -456,11 +457,11 @@ // built-in script function: inc() StdUnit_t CoreVMFunction_inc::returnUnitType(VMFnArgs* args) { - return args->arg(0)->asScalarNumberExpr()->unitType(); + return args->arg(0)->asNumber()->unitType(); } bool CoreVMFunction_inc::returnsFinal(VMFnArgs* args) { - return args->arg(0)->asScalarNumberExpr()->isFinal(); + return args->arg(0)->asNumber()->isFinal(); } void CoreVMFunction_inc::checkArgs(VMFnArgs* args, @@ -471,8 +472,8 @@ Super::checkArgs(args, err, wrn); // own checks ... - if (args->arg(0)->asScalarNumberExpr()->unitType()) { - String unitType = unitTypeStr(args->arg(0)->asScalarNumberExpr()->unitType()); + if (args->arg(0)->asNumber()->unitType()) { + String unitType = unitTypeStr(args->arg(0)->asNumber()->unitType()); wrn("Argument has a unit type (" + unitType + "), only the number before the unit will be incremented by one."); } } @@ -497,11 +498,11 @@ // built-in script function: dec() StdUnit_t CoreVMFunction_dec::returnUnitType(VMFnArgs* args) { - return args->arg(0)->asScalarNumberExpr()->unitType(); + return args->arg(0)->asNumber()->unitType(); } bool CoreVMFunction_dec::returnsFinal(VMFnArgs* args) { - return args->arg(0)->asScalarNumberExpr()->isFinal(); + return args->arg(0)->asNumber()->isFinal(); } void CoreVMFunction_dec::checkArgs(VMFnArgs* args, @@ -512,8 +513,8 @@ Super::checkArgs(args, err, wrn); // own checks ... - if (args->arg(0)->asScalarNumberExpr()->unitType()) { - String unitType = unitTypeStr(args->arg(0)->asScalarNumberExpr()->unitType()); + if (args->arg(0)->asNumber()->unitType()) { + String unitType = unitTypeStr(args->arg(0)->asNumber()->unitType()); wrn("Argument has a unit type (" + unitType + "), only the number before the unit will be decremented by one."); } } @@ -549,14 +550,14 @@ Super::checkArgs(args, err, wrn); // own checks ... - if (args->arg(0)->asScalarNumberExpr()->unitType() != - args->arg(1)->asScalarNumberExpr()->unitType() || - args->arg(1)->asScalarNumberExpr()->unitType() != - args->arg(2)->asScalarNumberExpr()->unitType()) + if (args->arg(0)->asNumber()->unitType() != + args->arg(1)->asNumber()->unitType() || + args->arg(1)->asNumber()->unitType() != + args->arg(2)->asNumber()->unitType()) { - String a = unitTypeStr(args->arg(0)->asScalarNumberExpr()->unitType()); - String b = unitTypeStr(args->arg(1)->asScalarNumberExpr()->unitType()); - String c = unitTypeStr(args->arg(2)->asScalarNumberExpr()->unitType()); + String a = unitTypeStr(args->arg(0)->asNumber()->unitType()); + String b = unitTypeStr(args->arg(1)->asNumber()->unitType()); + String c = unitTypeStr(args->arg(2)->asNumber()->unitType()); err("Arguments must all have same unit, however argument 1 is " + a + ", argument 2 is " + b + ", argument 3 is " + c + "."); return; @@ -581,9 +582,9 @@ } VMFnResult* CoreVMFunction_in_range::exec(VMFnArgs* args) { - VMScalarNumberExpr* argNeedle = args->arg(0)->asScalarNumberExpr(); - VMScalarNumberExpr* argLo = args->arg(1)->asScalarNumberExpr(); - VMScalarNumberExpr* argHi = args->arg(2)->asScalarNumberExpr(); + VMNumberExpr* argNeedle = args->arg(0)->asNumber(); + VMNumberExpr* argLo = args->arg(1)->asNumber(); + VMNumberExpr* argHi = args->arg(2)->asNumber(); vmfloat needle = argNeedle->evalCastReal(); vmfloat lo = argLo->evalCastReal(); @@ -602,7 +603,7 @@ // built-in script function: sh_left() bool CoreVMFunction_sh_left::returnsFinal(VMFnArgs* args) { - return args->arg(0)->asScalarNumberExpr()->isFinal(); + return args->arg(0)->asNumber()->isFinal(); } VMFnResult* CoreVMFunction_sh_left::exec(VMFnArgs* args) { @@ -615,7 +616,7 @@ // built-in script function: sh_right() bool CoreVMFunction_sh_right::returnsFinal(VMFnArgs* args) { - return args->arg(0)->asScalarNumberExpr()->isFinal(); + return args->arg(0)->asNumber()->isFinal(); } VMFnResult* CoreVMFunction_sh_right::exec(VMFnArgs* args) { @@ -633,12 +634,12 @@ } StdUnit_t CoreVMFunction_min::returnUnitType(VMFnArgs* args) { - return args->arg(0)->asScalarNumberExpr()->unitType(); + return args->arg(0)->asNumber()->unitType(); } bool CoreVMFunction_min::returnsFinal(VMFnArgs* args) { - return args->arg(0)->asScalarNumberExpr()->isFinal() || - args->arg(1)->asScalarNumberExpr()->isFinal(); + return args->arg(0)->asNumber()->isFinal() || + args->arg(1)->asNumber()->isFinal(); } bool CoreVMFunction_min::acceptsArgType(vmint iArg, ExprType_t type) const { @@ -653,11 +654,11 @@ Super::checkArgs(args, err, wrn); // own checks ... - if (args->arg(0)->asScalarNumberExpr()->unitType() != - args->arg(1)->asScalarNumberExpr()->unitType()) + if (args->arg(0)->asNumber()->unitType() != + args->arg(1)->asNumber()->unitType()) { - String a = unitTypeStr(args->arg(0)->asScalarNumberExpr()->unitType()); - String b = unitTypeStr(args->arg(1)->asScalarNumberExpr()->unitType()); + String a = unitTypeStr(args->arg(0)->asNumber()->unitType()); + String b = unitTypeStr(args->arg(1)->asNumber()->unitType()); err("Argument 1 has unit type " + a + ", whereas argument 2 has unit type " + b + "."); return; } @@ -668,18 +669,18 @@ wrn("Argument 1 is " + a + ", whereas argument 2 is " + b + ", function result will be " + c + "."); return; } - if (args->arg(0)->asScalarNumberExpr()->isFinal() != - args->arg(1)->asScalarNumberExpr()->isFinal()) + if (args->arg(0)->asNumber()->isFinal() != + args->arg(1)->asNumber()->isFinal()) { - String a = args->arg(0)->asScalarNumberExpr()->isFinal() ? "'final'" : "not 'final'"; - String b = args->arg(1)->asScalarNumberExpr()->isFinal() ? "'final'" : "not 'final'"; + String a = args->arg(0)->asNumber()->isFinal() ? "'final'" : "not 'final'"; + String b = args->arg(1)->asNumber()->isFinal() ? "'final'" : "not 'final'"; wrn("Argument 1 is " + a + ", whereas argument 2 is " + b + ", function result will be final."); } } VMFnResult* CoreVMFunction_min::exec(VMFnArgs* args) { - VMScalarNumberExpr* lhs = args->arg(0)->asScalarNumberExpr(); - VMScalarNumberExpr* rhs = args->arg(1)->asScalarNumberExpr(); + VMNumberExpr* lhs = args->arg(0)->asNumber(); + VMNumberExpr* rhs = args->arg(1)->asNumber(); if (lhs->exprType() == REAL_EXPR && rhs->exprType() == REAL_EXPR) { vmfloat lm = lhs->asReal()->evalReal(); vmfloat rm = rhs->asReal()->evalReal(); @@ -728,12 +729,12 @@ } StdUnit_t CoreVMFunction_max::returnUnitType(VMFnArgs* args) { - return args->arg(0)->asScalarNumberExpr()->unitType(); + return args->arg(0)->asNumber()->unitType(); } bool CoreVMFunction_max::returnsFinal(VMFnArgs* args) { - return args->arg(0)->asScalarNumberExpr()->isFinal() || - args->arg(1)->asScalarNumberExpr()->isFinal(); + return args->arg(0)->asNumber()->isFinal() || + args->arg(1)->asNumber()->isFinal(); } bool CoreVMFunction_max::acceptsArgType(vmint iArg, ExprType_t type) const { @@ -748,11 +749,11 @@ Super::checkArgs(args, err, wrn); // own checks ... - if (args->arg(0)->asScalarNumberExpr()->unitType() != - args->arg(1)->asScalarNumberExpr()->unitType()) + if (args->arg(0)->asNumber()->unitType() != + args->arg(1)->asNumber()->unitType()) { - String a = unitTypeStr(args->arg(0)->asScalarNumberExpr()->unitType()); - String b = unitTypeStr(args->arg(1)->asScalarNumberExpr()->unitType()); + String a = unitTypeStr(args->arg(0)->asNumber()->unitType()); + String b = unitTypeStr(args->arg(1)->asNumber()->unitType()); err("Argument 1 has unit type " + a + ", whereas argument 2 has unit type " + b + "."); return; } @@ -763,18 +764,18 @@ wrn("Argument 1 is " + a + ", whereas argument 2 is " + b + ", function result will be " + c + "."); return; } - if (args->arg(0)->asScalarNumberExpr()->isFinal() != - args->arg(1)->asScalarNumberExpr()->isFinal()) + if (args->arg(0)->asNumber()->isFinal() != + args->arg(1)->asNumber()->isFinal()) { - String a = args->arg(0)->asScalarNumberExpr()->isFinal() ? "'final'" : "not 'final'"; - String b = args->arg(1)->asScalarNumberExpr()->isFinal() ? "'final'" : "not 'final'"; + String a = args->arg(0)->asNumber()->isFinal() ? "'final'" : "not 'final'"; + String b = args->arg(1)->asNumber()->isFinal() ? "'final'" : "not 'final'"; wrn("Argument 1 is " + a + ", whereas argument 2 is " + b + ", function result will be final."); } } VMFnResult* CoreVMFunction_max::exec(VMFnArgs* args) { - VMScalarNumberExpr* lhs = args->arg(0)->asScalarNumberExpr(); - VMScalarNumberExpr* rhs = args->arg(1)->asScalarNumberExpr(); + VMNumberExpr* lhs = args->arg(0)->asNumber(); + VMNumberExpr* rhs = args->arg(1)->asNumber(); if (lhs->exprType() == REAL_EXPR && rhs->exprType() == REAL_EXPR) { vmfloat lm = lhs->asReal()->evalReal(); vmfloat rm = rhs->asReal()->evalReal(); @@ -911,10 +912,6 @@ /////////////////////////////////////////////////////////////////////////// // built-in script function: search() -ExprType_t CoreVMFunction_search::argType(vmint iArg) const { - return (iArg == 0) ? INT_ARR_EXPR : INT_EXPR; -} - bool CoreVMFunction_search::acceptsArgType(vmint iArg, ExprType_t type) const { if (iArg == 0) return isArray(type); @@ -974,10 +971,6 @@ /////////////////////////////////////////////////////////////////////////// // built-in script function: sort() -ExprType_t CoreVMFunction_sort::argType(vmint iArg) const { - return (iArg == 0) ? INT_ARR_EXPR : INT_EXPR; -} - bool CoreVMFunction_sort::acceptsArgType(vmint iArg, ExprType_t type) const { if (iArg == 0) return isArray(type); @@ -989,7 +982,7 @@ // use std sort algorithms on our arrays. It might look a bit more complicated // than it ought to be, but there is one reason for the large amount of // 'adapter' code below: the STL std algorithms rely on 'lvalues' to do their -// e.g. sorting) jobs, that is they expect containers to have 'localizeable' +// (e.g. sorting) jobs, that is they expect containers to have 'localizeable' // data which essentially means their data should reside somewhere in memory and // directly be accessible (readable and writable) there, which is not the case // with our VM interfaces which actually always require virtual getter and @@ -1045,7 +1038,7 @@ class T_accessor> // T_accessor is either IntArrayAccessor or RealArrayAccessor class ArrElemRef : protected ArrElemPOD { public: - typedef ScalarNmbrVal ScalarNmbrVal; + typedef ::LinuxSampler::ScalarNmbrVal ScalarNmbrVal; // GCC 8.x requires this very detailed form of typedef (that is ::LinuxSampler:: as prefix), IMO a GCC bug inline ArrElemRef(T_array* a, vmint index) { this->m_array = a; @@ -1138,7 +1131,7 @@ public: typedef std::random_access_iterator_tag iterator_category; typedef ssize_t difference_type; - typedef ArrElemRef ArrElemRef; + typedef ::LinuxSampler::ArrElemRef ArrElemRef; // GCC 8.x requires this very detailed form of typedef (that is ::LinuxSampler:: as prefix), IMO a GCC bug typedef ArrElemRef reference; // type used by STL for access by reference typedef void pointer; // type used by STL for -> operator result, we don't use that operator at all so just void it typedef ScalarNmbrVal value_type; // type used by STL for temporary values @@ -1219,8 +1212,8 @@ typedef ArrExprIter RealArrExprIter; // intentionally not a template function to avoid potential clashes with other (i.e. system's) swap() functions -static inline void swap(IntArrExprIter::ArrElemRef a, - IntArrExprIter::ArrElemRef b) +inline void swap(IntArrExprIter::ArrElemRef a, + IntArrExprIter::ArrElemRef b) { vmint valueA = a.getPrimValue(); vmint valueB = b.getPrimValue(); @@ -1233,8 +1226,8 @@ } // intentionally not a template function to avoid potential clashes with other (i.e. system's) swap() functions -static inline void swap(RealArrExprIter::ArrElemRef a, - RealArrExprIter::ArrElemRef b) +inline void swap(RealArrExprIter::ArrElemRef a, + RealArrExprIter::ArrElemRef b) { vmfloat valueA = a.getPrimValue(); vmfloat valueB = b.getPrimValue(); @@ -1289,11 +1282,11 @@ // built-in script function: real_to_int() and int() StdUnit_t CoreVMFunction_real_to_int::returnUnitType(VMFnArgs* args) { - return args->arg(0)->asScalarNumberExpr()->unitType(); + return args->arg(0)->asNumber()->unitType(); } bool CoreVMFunction_real_to_int::returnsFinal(VMFnArgs* args) { - return args->arg(0)->asScalarNumberExpr()->isFinal(); + return args->arg(0)->asNumber()->isFinal(); } VMFnResult* CoreVMFunction_real_to_int::exec(VMFnArgs* args) { @@ -1309,11 +1302,11 @@ // built-in script function: int_to_real() and real() StdUnit_t CoreVMFunction_int_to_real::returnUnitType(VMFnArgs* args) { - return args->arg(0)->asScalarNumberExpr()->unitType(); + return args->arg(0)->asNumber()->unitType(); } bool CoreVMFunction_int_to_real::returnsFinal(VMFnArgs* args) { - return args->arg(0)->asScalarNumberExpr()->isFinal(); + return args->arg(0)->asNumber()->isFinal(); } VMFnResult* CoreVMFunction_int_to_real::exec(VMFnArgs* args) { @@ -1325,4 +1318,382 @@ }); } +/////////////////////////////////////////////////////////////////////////// +// built-in script function: round() + +StdUnit_t CoreVMFunction_round::returnUnitType(VMFnArgs* args) { + return args->arg(0)->asNumber()->unitType(); +} + +bool CoreVMFunction_round::returnsFinal(VMFnArgs* args) { + return args->arg(0)->asNumber()->isFinal(); +} + +VMFnResult* CoreVMFunction_round::exec(VMFnArgs* args) { + VMRealExpr* realExpr = args->arg(0)->asReal(); + vmfloat f = realExpr->evalReal(); + if (sizeof(vmfloat) == sizeof(float)) + f = ::roundf(f); + else + f = ::round(f); + return successResult({ + .value = f, + .unitFactor = realExpr->unitFactor() + }); +} + +/////////////////////////////////////////////////////////////////////////// +// built-in script function: ceil() + +StdUnit_t CoreVMFunction_ceil::returnUnitType(VMFnArgs* args) { + return args->arg(0)->asNumber()->unitType(); +} + +bool CoreVMFunction_ceil::returnsFinal(VMFnArgs* args) { + return args->arg(0)->asNumber()->isFinal(); +} + +VMFnResult* CoreVMFunction_ceil::exec(VMFnArgs* args) { + VMRealExpr* realExpr = args->arg(0)->asReal(); + vmfloat f = realExpr->evalReal(); + if (sizeof(vmfloat) == sizeof(float)) + f = ::ceilf(f); + else + f = ::ceil(f); + return successResult({ + .value = f, + .unitFactor = realExpr->unitFactor() + }); +} + +/////////////////////////////////////////////////////////////////////////// +// built-in script function: floor() + +StdUnit_t CoreVMFunction_floor::returnUnitType(VMFnArgs* args) { + return args->arg(0)->asNumber()->unitType(); +} + +bool CoreVMFunction_floor::returnsFinal(VMFnArgs* args) { + return args->arg(0)->asNumber()->isFinal(); +} + +VMFnResult* CoreVMFunction_floor::exec(VMFnArgs* args) { + VMRealExpr* realExpr = args->arg(0)->asReal(); + vmfloat f = realExpr->evalReal(); + if (sizeof(vmfloat) == sizeof(float)) + f = ::floorf(f); + else + f = ::floor(f); + return successResult({ + .value = f, + .unitFactor = realExpr->unitFactor() + }); +} + +/////////////////////////////////////////////////////////////////////////// +// built-in script function: sqrt() + +StdUnit_t CoreVMFunction_sqrt::returnUnitType(VMFnArgs* args) { + return args->arg(0)->asNumber()->unitType(); +} + +bool CoreVMFunction_sqrt::returnsFinal(VMFnArgs* args) { + return args->arg(0)->asNumber()->isFinal(); +} + +VMFnResult* CoreVMFunction_sqrt::exec(VMFnArgs* args) { + VMRealExpr* realExpr = args->arg(0)->asReal(); + vmfloat f = realExpr->evalReal(); + if (sizeof(vmfloat) == sizeof(float)) + f = ::sqrtf(f); + else + f = ::sqrt(f); + return successResult({ + .value = f, + .unitFactor = realExpr->unitFactor() + }); +} + +/////////////////////////////////////////////////////////////////////////// +// built-in script function: log() + +StdUnit_t CoreVMFunction_log::returnUnitType(VMFnArgs* args) { + return args->arg(0)->asNumber()->unitType(); +} + +bool CoreVMFunction_log::returnsFinal(VMFnArgs* args) { + return args->arg(0)->asNumber()->isFinal(); +} + +VMFnResult* CoreVMFunction_log::exec(VMFnArgs* args) { + VMRealExpr* realExpr = args->arg(0)->asReal(); + vmfloat f = realExpr->evalReal(); + if (sizeof(vmfloat) == sizeof(float)) + f = ::logf(f); + else + f = ::log(f); + return successResult({ + .value = f, + .unitFactor = realExpr->unitFactor() + }); +} + +/////////////////////////////////////////////////////////////////////////// +// built-in script function: log2() + +StdUnit_t CoreVMFunction_log2::returnUnitType(VMFnArgs* args) { + return args->arg(0)->asNumber()->unitType(); +} + +bool CoreVMFunction_log2::returnsFinal(VMFnArgs* args) { + return args->arg(0)->asNumber()->isFinal(); +} + +VMFnResult* CoreVMFunction_log2::exec(VMFnArgs* args) { + VMRealExpr* realExpr = args->arg(0)->asReal(); + vmfloat f = realExpr->evalReal(); + if (sizeof(vmfloat) == sizeof(float)) + f = ::log2f(f); + else + f = ::log2(f); + return successResult({ + .value = f, + .unitFactor = realExpr->unitFactor() + }); +} + +/////////////////////////////////////////////////////////////////////////// +// built-in script function: log10() + +StdUnit_t CoreVMFunction_log10::returnUnitType(VMFnArgs* args) { + return args->arg(0)->asNumber()->unitType(); +} + +bool CoreVMFunction_log10::returnsFinal(VMFnArgs* args) { + return args->arg(0)->asNumber()->isFinal(); +} + +VMFnResult* CoreVMFunction_log10::exec(VMFnArgs* args) { + VMRealExpr* realExpr = args->arg(0)->asReal(); + vmfloat f = realExpr->evalReal(); + if (sizeof(vmfloat) == sizeof(float)) + f = ::log10f(f); + else + f = ::log10(f); + return successResult({ + .value = f, + .unitFactor = realExpr->unitFactor() + }); +} + +/////////////////////////////////////////////////////////////////////////// +// built-in script function: exp() + +StdUnit_t CoreVMFunction_exp::returnUnitType(VMFnArgs* args) { + return args->arg(0)->asNumber()->unitType(); +} + +bool CoreVMFunction_exp::returnsFinal(VMFnArgs* args) { + return args->arg(0)->asNumber()->isFinal(); +} + +VMFnResult* CoreVMFunction_exp::exec(VMFnArgs* args) { + VMRealExpr* realExpr = args->arg(0)->asReal(); + vmfloat f = realExpr->evalReal(); + if (sizeof(vmfloat) == sizeof(float)) + f = ::expf(f); + else + f = ::exp(f); + return successResult({ + .value = f, + .unitFactor = realExpr->unitFactor() + }); +} + +/////////////////////////////////////////////////////////////////////////// +// built-in script function: pow() + +bool CoreVMFunction_pow::acceptsArgUnitType(vmint iArg, StdUnit_t type) const { + if (iArg == 0) + return true; + else + return type == VM_NO_UNIT; +} + +bool CoreVMFunction_pow::acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const { + return iArg == 0; +} + +StdUnit_t CoreVMFunction_pow::returnUnitType(VMFnArgs* args) { + // pow() only allows unit for its 1st argument + return args->arg(0)->asNumber()->unitType(); +} + +bool CoreVMFunction_pow::returnsFinal(VMFnArgs* args) { + // pow() only allows 'final'ness for its 1st argument + return args->arg(0)->asNumber()->isFinal(); +} + +VMFnResult* CoreVMFunction_pow::exec(VMFnArgs* args) { + VMRealExpr* arg0 = args->arg(0)->asReal(); + VMRealExpr* arg1 = args->arg(1)->asReal(); + vmfloat a = arg0->evalReal(); + vmfloat b = arg1->evalReal(); + if (sizeof(vmfloat) == sizeof(float)) { + return successResult({ + .value = ::powf(a,b), + .unitFactor = arg0->unitFactor() + }); + } else { + return successResult({ + .value = static_cast(::pow(a,b)), + .unitFactor = arg0->unitFactor() + }); + } +} + +/////////////////////////////////////////////////////////////////////////// +// built-in script function: sin() + +StdUnit_t CoreVMFunction_sin::returnUnitType(VMFnArgs* args) { + return args->arg(0)->asNumber()->unitType(); +} + +bool CoreVMFunction_sin::returnsFinal(VMFnArgs* args) { + return args->arg(0)->asNumber()->isFinal(); +} + +VMFnResult* CoreVMFunction_sin::exec(VMFnArgs* args) { + VMRealExpr* realExpr = args->arg(0)->asReal(); + vmfloat f = realExpr->evalReal(); + if (sizeof(vmfloat) == sizeof(float)) + f = ::sinf(f); + else + f = ::sin(f); + return successResult({ + .value = f, + .unitFactor = realExpr->unitFactor() + }); +} + +/////////////////////////////////////////////////////////////////////////// +// built-in script function: cos() + +StdUnit_t CoreVMFunction_cos::returnUnitType(VMFnArgs* args) { + return args->arg(0)->asNumber()->unitType(); +} + +bool CoreVMFunction_cos::returnsFinal(VMFnArgs* args) { + return args->arg(0)->asNumber()->isFinal(); +} + +VMFnResult* CoreVMFunction_cos::exec(VMFnArgs* args) { + VMRealExpr* realExpr = args->arg(0)->asReal(); + vmfloat f = realExpr->evalReal(); + if (sizeof(vmfloat) == sizeof(float)) + f = ::cosf(f); + else + f = ::cos(f); + return successResult({ + .value = f, + .unitFactor = realExpr->unitFactor() + }); +} + +/////////////////////////////////////////////////////////////////////////// +// built-in script function: tan() + +StdUnit_t CoreVMFunction_tan::returnUnitType(VMFnArgs* args) { + return args->arg(0)->asNumber()->unitType(); +} + +bool CoreVMFunction_tan::returnsFinal(VMFnArgs* args) { + return args->arg(0)->asNumber()->isFinal(); +} + +VMFnResult* CoreVMFunction_tan::exec(VMFnArgs* args) { + VMRealExpr* realExpr = args->arg(0)->asReal(); + vmfloat f = realExpr->evalReal(); + if (sizeof(vmfloat) == sizeof(float)) + f = ::tanf(f); + else + f = ::tan(f); + return successResult({ + .value = f, + .unitFactor = realExpr->unitFactor() + }); +} + +/////////////////////////////////////////////////////////////////////////// +// built-in script function: asin() + +StdUnit_t CoreVMFunction_asin::returnUnitType(VMFnArgs* args) { + return args->arg(0)->asNumber()->unitType(); +} + +bool CoreVMFunction_asin::returnsFinal(VMFnArgs* args) { + return args->arg(0)->asNumber()->isFinal(); +} + +VMFnResult* CoreVMFunction_asin::exec(VMFnArgs* args) { + VMRealExpr* realExpr = args->arg(0)->asReal(); + vmfloat f = realExpr->evalReal(); + if (sizeof(vmfloat) == sizeof(float)) + f = ::asinf(f); + else + f = ::asin(f); + return successResult({ + .value = f, + .unitFactor = realExpr->unitFactor() + }); +} + +/////////////////////////////////////////////////////////////////////////// +// built-in script function: acos() + +StdUnit_t CoreVMFunction_acos::returnUnitType(VMFnArgs* args) { + return args->arg(0)->asNumber()->unitType(); +} + +bool CoreVMFunction_acos::returnsFinal(VMFnArgs* args) { + return args->arg(0)->asNumber()->isFinal(); +} + +VMFnResult* CoreVMFunction_acos::exec(VMFnArgs* args) { + VMRealExpr* realExpr = args->arg(0)->asReal(); + vmfloat f = realExpr->evalReal(); + if (sizeof(vmfloat) == sizeof(float)) + f = ::acosf(f); + else + f = ::acos(f); + return successResult({ + .value = f, + .unitFactor = realExpr->unitFactor() + }); +} + +/////////////////////////////////////////////////////////////////////////// +// built-in script function: atan() + +StdUnit_t CoreVMFunction_atan::returnUnitType(VMFnArgs* args) { + return args->arg(0)->asNumber()->unitType(); +} + +bool CoreVMFunction_atan::returnsFinal(VMFnArgs* args) { + return args->arg(0)->asNumber()->isFinal(); +} + +VMFnResult* CoreVMFunction_atan::exec(VMFnArgs* args) { + VMRealExpr* realExpr = args->arg(0)->asReal(); + vmfloat f = realExpr->evalReal(); + if (sizeof(vmfloat) == sizeof(float)) + f = ::atanf(f); + else + f = ::atan(f); + return successResult({ + .value = f, + .unitFactor = realExpr->unitFactor() + }); +} + } // namespace LinuxSampler