--- linuxsampler/trunk/src/scriptvm/CoreVMFunctions.h 2019/08/29 13:44:35 3580 +++ linuxsampler/trunk/src/scriptvm/CoreVMFunctions.h 2019/08/30 11:40:25 3581 @@ -24,7 +24,7 @@ * An instance of this class is returned by built-in function implementations * which do not return a function return value. */ -class VMEmptyResult : public VMFnResult, public VMExpr { +class VMEmptyResult FINAL : public VMFnResult, public VMExpr { public: StmtFlags_t flags; ///< general completion status (i.e. success or failure) of the function call @@ -39,45 +39,47 @@ * An instance of this class is returned by built-in function implementations * which return an integer value as function return value. */ -class VMIntResult : public VMFnResult, public VMIntExpr { +class VMIntResult FINAL : public VMFnResult, public VMIntExpr { public: StmtFlags_t flags; ///< general completion status (i.e. success or failure) of the function call vmint value; ///< result value of the function call + vmfloat unitPrefixFactor; ///< unit factor of result value of the function call - VMIntResult() : flags(STMT_SUCCESS), value(0) {} + VMIntResult() : flags(STMT_SUCCESS), value(0), unitPrefixFactor(VM_NO_FACTOR) {} vmint evalInt() OVERRIDE { return value; } VMExpr* resultValue() OVERRIDE { return this; } StmtFlags_t resultFlags() OVERRIDE { return flags; } bool isConstExpr() const OVERRIDE { return false; } - MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE { return VM_NO_PREFIX; } - StdUnit_t unitType() const OVERRIDE { return VM_NO_UNIT; } - bool isFinal() const OVERRIDE { return false; } + vmfloat unitFactor() const OVERRIDE { return unitPrefixFactor; } + StdUnit_t unitType() const OVERRIDE { return VM_NO_UNIT; } // actually never called, VMFunction::returnUnitType() is always used instead + bool isFinal() const OVERRIDE { return false; } // actually never called, VMFunction::returnsFinal() is always used instead }; /** * An instance of this class is returned by built-in function implementations * which return a real number (floating point) value as function return value. */ -class VMRealResult : public VMFnResult, public VMRealExpr { +class VMRealResult FINAL : public VMFnResult, public VMRealExpr { public: StmtFlags_t flags; ///< general completion status (i.e. success or failure) of the function call vmfloat value; ///< result value of the function call + vmfloat unitPrefixFactor; ///< unit factor of result value of the function call - VMRealResult() : flags(STMT_SUCCESS), value(0) {} + VMRealResult() : flags(STMT_SUCCESS), value(0), unitPrefixFactor(VM_NO_FACTOR) {} vmfloat evalReal() OVERRIDE { return value; } VMExpr* resultValue() OVERRIDE { return this; } StmtFlags_t resultFlags() OVERRIDE { return flags; } bool isConstExpr() const OVERRIDE { return false; } - MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE { return VM_NO_PREFIX; } - StdUnit_t unitType() const OVERRIDE { return VM_NO_UNIT; } - bool isFinal() const OVERRIDE { return false; } + vmfloat unitFactor() const OVERRIDE { return unitPrefixFactor; } + StdUnit_t unitType() const OVERRIDE { return VM_NO_UNIT; } // actually never called, VMFunction::returnUnitType() is always used instead + bool isFinal() const OVERRIDE { return false; } // actually never called, VMFunction::returnsFinal() is always used instead }; /** * An instance of this class is returned by built-in function implementations * which return a string value as function return value. */ -class VMStringResult : public VMFnResult, public VMStringExpr { +class VMStringResult FINAL : public VMFnResult, public VMStringExpr { public: StmtFlags_t flags; ///< general completion status (i.e. success or failure) of the function call String value; ///< result value of the function call @@ -97,6 +99,8 @@ protected: virtual ~VMEmptyResultFunction() {} ExprType_t returnType(VMFnArgs* args) OVERRIDE { return EMPTY_EXPR; } + StdUnit_t returnUnitType(VMFnArgs* args) OVERRIDE { return VM_NO_UNIT; } + bool returnsFinal(VMFnArgs* args) OVERRIDE { return false; } VMFnResult* errorResult(); VMFnResult* successResult(); bool modifiesArg(vmint iArg) const OVERRIDE { return false; } @@ -104,6 +108,16 @@ VMEmptyResult result; }; +struct VMIntFnResDef { + vmint value = 0; //NOTE: sequence matters! Since this is usually initialized with VMIntExpr::evalInt() it should be before member unitFactor, since the latter is usually initialized with VMIntExpr::unitFactor() which does not evaluate the expression. + vmfloat unitFactor = VM_NO_FACTOR; +}; + +struct VMRealFnResDef { + vmfloat value = vmfloat(0); //NOTE: sequence matters! Since this is usually initialized with VMRealExpr::evalReal() it should be before member unitFactor, since the latter is usually initialized with VMRealExpr::unitFactor() which does not evaluate the expression. + vmfloat unitFactor = VM_NO_FACTOR; +}; + /** * Abstract base class for built-in script functions which return an integer * (scalar) as their function return value. @@ -113,7 +127,9 @@ virtual ~VMIntResultFunction() {} ExprType_t returnType(VMFnArgs* args) OVERRIDE { return INT_EXPR; } VMFnResult* errorResult(vmint i = 0); + VMFnResult* errorResult(VMIntFnResDef res); VMFnResult* successResult(vmint i = 0); + VMFnResult* successResult(VMIntFnResDef res); bool modifiesArg(vmint iArg) const OVERRIDE { return false; } protected: VMIntResult result; @@ -128,7 +144,9 @@ virtual ~VMRealResultFunction() {} ExprType_t returnType(VMFnArgs* args) OVERRIDE { return REAL_EXPR; } VMFnResult* errorResult(vmfloat f = 0); + VMFnResult* errorResult(VMRealFnResDef res); VMFnResult* successResult(vmfloat f = 0); + VMFnResult* successResult(VMRealFnResDef res); bool modifiesArg(vmint iArg) const OVERRIDE { return false; } protected: VMRealResult result; @@ -162,6 +180,10 @@ VMFnResult* errorResult(vmfloat f); VMFnResult* successResult(vmint i); VMFnResult* successResult(vmfloat f); + VMFnResult* errorIntResult(VMIntFnResDef res); + VMFnResult* errorRealResult(VMRealFnResDef res); + VMFnResult* successIntResult(VMIntFnResDef res); + VMFnResult* successRealResult(VMRealFnResDef res); bool modifiesArg(vmint iArg) const OVERRIDE { return false; } protected: VMIntResult intResult; @@ -175,7 +197,7 @@ /** * Implements the built-in message() script function. */ -class CoreVMFunction_message : public VMEmptyResultFunction { +class CoreVMFunction_message FINAL : public VMEmptyResultFunction { public: vmint minRequiredArgs() const OVERRIDE { return 1; } vmint maxAllowedArgs() const OVERRIDE { return 1; } @@ -187,13 +209,16 @@ /** * Implements the built-in exit() script function. */ -class CoreVMFunction_exit : public VMEmptyResultFunction { +class CoreVMFunction_exit FINAL : public VMEmptyResultFunction { public: CoreVMFunction_exit(ScriptVM* vm) : vm(vm) {} vmint minRequiredArgs() const OVERRIDE { return 0; } vmint maxAllowedArgs() const OVERRIDE; bool acceptsArgType(vmint iArg, ExprType_t type) const OVERRIDE; ExprType_t argType(vmint iArg) const OVERRIDE { return INT_EXPR; } + bool acceptsArgUnitType(vmint iArg, StdUnit_t type) const OVERRIDE; + bool acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const OVERRIDE; + bool acceptsArgFinal(vmint iArg) const OVERRIDE; VMFnResult* exec(VMFnArgs* args) OVERRIDE; protected: ScriptVM* vm; @@ -219,12 +244,17 @@ /** * Implements the built-in abs() script function. */ -class CoreVMFunction_abs : public VMScalarNumberResultFunction { +class CoreVMFunction_abs FINAL : public VMScalarNumberResultFunction { public: ExprType_t returnType(VMFnArgs* args) OVERRIDE; + StdUnit_t returnUnitType(VMFnArgs* args) OVERRIDE; + bool returnsFinal(VMFnArgs* args) OVERRIDE; vmint minRequiredArgs() const OVERRIDE { return 1; } vmint maxAllowedArgs() const OVERRIDE { return 1; } bool acceptsArgType(vmint iArg, ExprType_t type) const OVERRIDE; + bool acceptsArgUnitType(vmint iArg, StdUnit_t type) const OVERRIDE { return true; } + bool acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const OVERRIDE { return true; } + bool acceptsArgFinal(vmint iArg) const OVERRIDE { return true; } ExprType_t argType(vmint iArg) const OVERRIDE { return INT_EXPR; } VMFnResult* exec(VMFnArgs* args) OVERRIDE; }; @@ -232,20 +262,31 @@ /** * Implements the built-in random() script function. */ -class CoreVMFunction_random : public VMIntResultFunction { +class CoreVMFunction_random FINAL : public VMScalarNumberResultFunction { + using Super = VMScalarNumberResultFunction; // just an alias for the super class public: + ExprType_t returnType(VMFnArgs* args) OVERRIDE; + StdUnit_t returnUnitType(VMFnArgs* args) OVERRIDE; + bool returnsFinal(VMFnArgs* args) OVERRIDE; vmint minRequiredArgs() const OVERRIDE { return 2; } vmint maxAllowedArgs() const OVERRIDE { return 2; } bool acceptsArgType(vmint iArg, ExprType_t type) const OVERRIDE; + bool acceptsArgUnitType(vmint iArg, StdUnit_t type) const OVERRIDE { return true; } + bool acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const OVERRIDE { return true; } + bool acceptsArgFinal(vmint iArg) const OVERRIDE { return true; } ExprType_t argType(vmint iArg) const OVERRIDE { return INT_EXPR; } + void checkArgs(VMFnArgs* args, std::function err, + std::function wrn) OVERRIDE; VMFnResult* exec(VMFnArgs* args) OVERRIDE; }; /** * Implements the built-in num_elements() script function. */ -class CoreVMFunction_num_elements : public VMIntResultFunction { +class CoreVMFunction_num_elements FINAL : public VMIntResultFunction { public: + StdUnit_t returnUnitType(VMFnArgs* args) OVERRIDE { return VM_NO_UNIT; } + bool returnsFinal(VMFnArgs* args) OVERRIDE { return false; } vmint minRequiredArgs() const OVERRIDE { return 1; } vmint maxAllowedArgs() const OVERRIDE { return 1; } bool acceptsArgType(vmint iArg, ExprType_t type) const OVERRIDE; @@ -256,119 +297,175 @@ /** * Implements the built-in inc() script function. */ -class CoreVMFunction_inc : public VMIntResultFunction { +class CoreVMFunction_inc FINAL : public VMIntResultFunction { + using Super = VMIntResultFunction; // just an alias for the super class public: + StdUnit_t returnUnitType(VMFnArgs* args) OVERRIDE; + bool returnsFinal(VMFnArgs* args) OVERRIDE; vmint minRequiredArgs() const OVERRIDE { return 1; } vmint maxAllowedArgs() const OVERRIDE { return 1; } bool acceptsArgType(vmint iArg, ExprType_t type) const OVERRIDE { return type == INT_EXPR; } + bool acceptsArgUnitType(vmint iArg, StdUnit_t type) const OVERRIDE { return true; } + bool acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const OVERRIDE { return true; } + bool acceptsArgFinal(vmint iArg) const OVERRIDE { return true; } ExprType_t argType(vmint iArg) const OVERRIDE { return INT_EXPR; } bool modifiesArg(vmint iArg) const OVERRIDE { return true; } + void checkArgs(VMFnArgs* args, std::function err, + std::function wrn) OVERRIDE; VMFnResult* exec(VMFnArgs* args) OVERRIDE; }; /** * Implements the built-in dec() script function. */ -class CoreVMFunction_dec : public VMIntResultFunction { +class CoreVMFunction_dec FINAL : public VMIntResultFunction { + using Super = VMIntResultFunction; // just an alias for the super class public: + StdUnit_t returnUnitType(VMFnArgs* args) OVERRIDE; + bool returnsFinal(VMFnArgs* args) OVERRIDE; vmint minRequiredArgs() const OVERRIDE { return 1; } vmint maxAllowedArgs() const OVERRIDE { return 1; } bool acceptsArgType(vmint iArg, ExprType_t type) const OVERRIDE { return type == INT_EXPR; } + bool acceptsArgUnitType(vmint iArg, StdUnit_t type) const OVERRIDE { return true; } + bool acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const OVERRIDE { return true; } + bool acceptsArgFinal(vmint iArg) const OVERRIDE { return true; } ExprType_t argType(vmint iArg) const OVERRIDE { return INT_EXPR; } bool modifiesArg(vmint iArg) const OVERRIDE { return true; } + void checkArgs(VMFnArgs* args, std::function err, + std::function wrn) OVERRIDE; VMFnResult* exec(VMFnArgs* args) OVERRIDE; }; /** * Implements the built-in in_range() script function. */ -class CoreVMFunction_in_range : public VMIntResultFunction { +class CoreVMFunction_in_range FINAL : public VMIntResultFunction { + using Super = VMIntResultFunction; // just an alias for the super class public: + StdUnit_t returnUnitType(VMFnArgs* args) OVERRIDE { return VM_NO_UNIT; } + bool returnsFinal(VMFnArgs* args) OVERRIDE { return false; } vmint minRequiredArgs() const OVERRIDE { return 3; } vmint maxAllowedArgs() const OVERRIDE { return 3; } - bool acceptsArgType(vmint iArg, ExprType_t type) const OVERRIDE { return type == INT_EXPR; } + bool acceptsArgType(vmint iArg, ExprType_t type) const OVERRIDE; ExprType_t argType(vmint iArg) const OVERRIDE { return INT_EXPR; } + bool acceptsArgUnitType(vmint iArg, StdUnit_t type) const OVERRIDE { return true; } + bool acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const OVERRIDE { return true; } + bool acceptsArgFinal(vmint iArg) const OVERRIDE { return true; } + void checkArgs(VMFnArgs* args, std::function err, + std::function wrn) OVERRIDE; VMFnResult* exec(VMFnArgs* args) OVERRIDE; }; /** * Implements the built-in sh_left() script function. */ -class CoreVMFunction_sh_left : public VMIntResultFunction { +class CoreVMFunction_sh_left FINAL : public VMIntResultFunction { public: + StdUnit_t returnUnitType(VMFnArgs* args) OVERRIDE { return VM_NO_UNIT; } + bool returnsFinal(VMFnArgs* args) OVERRIDE; vmint minRequiredArgs() const OVERRIDE { return 2; } vmint maxAllowedArgs() const OVERRIDE { return 2; } bool acceptsArgType(vmint iArg, ExprType_t type) const OVERRIDE { return type == INT_EXPR; } ExprType_t argType(vmint iArg) const OVERRIDE { return INT_EXPR; } + bool acceptsArgFinal(vmint iArg) const OVERRIDE { return true; } VMFnResult* exec(VMFnArgs* args) OVERRIDE; }; /** * Implements the built-in sh_right() script function. */ -class CoreVMFunction_sh_right : public VMIntResultFunction { +class CoreVMFunction_sh_right FINAL : public VMIntResultFunction { public: + StdUnit_t returnUnitType(VMFnArgs* args) OVERRIDE { return VM_NO_UNIT; } + bool returnsFinal(VMFnArgs* args) OVERRIDE; vmint minRequiredArgs() const OVERRIDE { return 2; } vmint maxAllowedArgs() const OVERRIDE { return 2; } bool acceptsArgType(vmint iArg, ExprType_t type) const OVERRIDE { return type == INT_EXPR; } ExprType_t argType(vmint iArg) const OVERRIDE { return INT_EXPR; } + bool acceptsArgFinal(vmint iArg) const OVERRIDE { return true; } VMFnResult* exec(VMFnArgs* args) OVERRIDE; }; /** * Implements the built-in min() script function. */ -class CoreVMFunction_min : public VMScalarNumberResultFunction { +class CoreVMFunction_min FINAL : public VMScalarNumberResultFunction { + using Super = VMScalarNumberResultFunction; // just an alias for the super class public: ExprType_t returnType(VMFnArgs* args) OVERRIDE; + StdUnit_t returnUnitType(VMFnArgs* args) OVERRIDE; + bool returnsFinal(VMFnArgs* args) OVERRIDE; vmint minRequiredArgs() const OVERRIDE { return 2; } vmint maxAllowedArgs() const OVERRIDE { return 2; } bool acceptsArgType(vmint iArg, ExprType_t type) const OVERRIDE; ExprType_t argType(vmint iArg) const OVERRIDE { return INT_EXPR; } + bool acceptsArgUnitType(vmint iArg, StdUnit_t type) const OVERRIDE { return true; } + bool acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const OVERRIDE { return true; } + bool acceptsArgFinal(vmint iArg) const OVERRIDE { return true; } + void checkArgs(VMFnArgs* args, std::function err, + std::function wrn) OVERRIDE; VMFnResult* exec(VMFnArgs* args) OVERRIDE; }; /** * Implements the built-in max() script function. */ -class CoreVMFunction_max : public VMScalarNumberResultFunction { +class CoreVMFunction_max FINAL : public VMScalarNumberResultFunction { + using Super = VMScalarNumberResultFunction; // just an alias for the super class public: ExprType_t returnType(VMFnArgs* args) OVERRIDE; + StdUnit_t returnUnitType(VMFnArgs* args) OVERRIDE; + bool returnsFinal(VMFnArgs* args) OVERRIDE; vmint minRequiredArgs() const OVERRIDE { return 2; } vmint maxAllowedArgs() const OVERRIDE { return 2; } bool acceptsArgType(vmint iArg, ExprType_t type) const OVERRIDE; ExprType_t argType(vmint iArg) const OVERRIDE { return INT_EXPR; } + bool acceptsArgUnitType(vmint iArg, StdUnit_t type) const OVERRIDE { return true; } + bool acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const OVERRIDE { return true; } + bool acceptsArgFinal(vmint iArg) const OVERRIDE { return true; } + void checkArgs(VMFnArgs* args, std::function err, + std::function wrn) OVERRIDE; VMFnResult* exec(VMFnArgs* args) OVERRIDE; }; /** * Implements the built-in array_equal() script function. */ -class CoreVMFunction_array_equal : public VMIntResultFunction { +class CoreVMFunction_array_equal FINAL : public VMIntResultFunction { + using Super = VMIntResultFunction; // just an alias for the super class public: + StdUnit_t returnUnitType(VMFnArgs* args) OVERRIDE { return VM_NO_UNIT; } + bool returnsFinal(VMFnArgs* args) OVERRIDE { return false; } vmint minRequiredArgs() const OVERRIDE { return 2; } vmint maxAllowedArgs() const OVERRIDE { return 2; } - bool acceptsArgType(vmint iArg, ExprType_t type) const OVERRIDE { return type == INT_ARR_EXPR; } + bool acceptsArgType(vmint iArg, ExprType_t type) const OVERRIDE; ExprType_t argType(vmint iArg) const OVERRIDE { return INT_ARR_EXPR; } + void checkArgs(VMFnArgs* args, std::function err, + std::function wrn) OVERRIDE; VMFnResult* exec(VMFnArgs* args) OVERRIDE; }; /** * Implements the built-in search() script function. */ -class CoreVMFunction_search : public VMIntResultFunction { +class CoreVMFunction_search FINAL : public VMIntResultFunction { + using Super = VMIntResultFunction; // just an alias for the super class public: + StdUnit_t returnUnitType(VMFnArgs* args) OVERRIDE { return VM_NO_UNIT; } + bool returnsFinal(VMFnArgs* args) OVERRIDE { return false; } vmint minRequiredArgs() const OVERRIDE { return 2; } vmint maxAllowedArgs() const OVERRIDE { return 2; } bool acceptsArgType(vmint iArg, ExprType_t type) const OVERRIDE; ExprType_t argType(vmint iArg) const OVERRIDE; + void checkArgs(VMFnArgs* args, std::function err, + std::function wrn) OVERRIDE; VMFnResult* exec(VMFnArgs* args) OVERRIDE; }; /** * Implements the built-in sort() script function. */ -class CoreVMFunction_sort : public VMEmptyResultFunction { +class CoreVMFunction_sort FINAL : public VMEmptyResultFunction { public: vmint minRequiredArgs() const OVERRIDE { return 1; } vmint maxAllowedArgs() const OVERRIDE { return 2; } @@ -383,12 +480,17 @@ * variant int(). The behaviour of the two built-in script functions are * identical ATM. */ -class CoreVMFunction_real_to_int : public VMIntResultFunction { +class CoreVMFunction_real_to_int FINAL : public VMIntResultFunction { public: + StdUnit_t returnUnitType(VMFnArgs* args) OVERRIDE; + bool returnsFinal(VMFnArgs* args) OVERRIDE; vmint minRequiredArgs() const OVERRIDE { return 1; } vmint maxAllowedArgs() const OVERRIDE { return 1; } bool acceptsArgType(vmint iArg, ExprType_t type) const OVERRIDE { return type == REAL_EXPR; } ExprType_t argType(vmint iArg) const OVERRIDE { return REAL_EXPR; } + bool acceptsArgUnitType(vmint iArg, StdUnit_t type) const OVERRIDE { return true; } + bool acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const OVERRIDE { return true; } + bool acceptsArgFinal(vmint iArg) const OVERRIDE { return true; } VMFnResult* exec(VMFnArgs* args) OVERRIDE; }; @@ -397,12 +499,17 @@ * variant real(). The behaviour of the two built-in script functions are * identical ATM. */ -class CoreVMFunction_int_to_real : public VMRealResultFunction { +class CoreVMFunction_int_to_real FINAL : public VMRealResultFunction { public: + StdUnit_t returnUnitType(VMFnArgs* args) OVERRIDE; + bool returnsFinal(VMFnArgs* args) OVERRIDE; vmint minRequiredArgs() const OVERRIDE { return 1; } vmint maxAllowedArgs() const OVERRIDE { return 1; } bool acceptsArgType(vmint iArg, ExprType_t type) const OVERRIDE { return type == INT_EXPR; } ExprType_t argType(vmint iArg) const OVERRIDE { return INT_EXPR; } + bool acceptsArgUnitType(vmint iArg, StdUnit_t type) const OVERRIDE { return true; } + bool acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const OVERRIDE { return true; } + bool acceptsArgFinal(vmint iArg) const OVERRIDE { return true; } VMFnResult* exec(VMFnArgs* args) OVERRIDE; };