--- linuxsampler/trunk/src/scriptvm/common.h 2019/08/23 11:44:00 3561 +++ linuxsampler/trunk/src/scriptvm/common.h 2019/08/30 12:23:40 3582 @@ -19,6 +19,7 @@ #include #include #include // offsetof() +#include // std::function<> namespace LinuxSampler { @@ -37,8 +38,9 @@ typedef uint64_t vmuint; /** - * Native data type used internally by the script engine for floating point - * data types. This type is currently not exposed to scripts. + * Native data type used by the script engine both internally for floating + * point data, as well as for all @c real data types used by scripts (i.e. + * for all ~foo variables in NKSP scripts). */ typedef float vmfloat; @@ -64,6 +66,8 @@ INT_ARR_EXPR, ///< integer array expression STRING_EXPR, ///< string expression STRING_ARR_EXPR, ///< string array expression + REAL_EXPR, ///< floating point (scalar) expression + REAL_ARR_EXPR, ///< floating point array expression }; /** @brief Result flags of a script statement or script function call. @@ -134,6 +138,14 @@ }; /** + * This constant is used for comparison with Unit::unitFactor() to check + * whether a number does have any metric unit prefix at all. + * + * @see Unit::unitFactor() + */ + static const vmfloat VM_NO_FACTOR = vmfloat(1); + + /** * All measurement unit types supported by this script engine. * * @e Note: there is no standard unit "cents" here (for pitch/tuning), use @@ -150,63 +162,99 @@ VM_BEL, ///< Measuring relation between two energy levels (in logarithmic scale). Since we are using it for accoustics, we are always referring to A-weighted Bels (i.e. dBA). }; + //TODO: see Unit::hasUnitFactorEver() + enum EverTriState_t { + VM_NEVER = 0, + VM_MAYBE, + VM_ALWAYS, + }; + // just symbol prototyping class VMIntExpr; + class VMRealExpr; class VMStringExpr; + class VMNumberExpr; + class VMArrayExpr; class VMIntArrayExpr; + class VMRealArrayExpr; class VMStringArrayExpr; class VMParserContext; - /** @brief Virtual machine measuring unit. + /** @brief Virtual machine standard measuring unit. * * Abstract base class representing standard measurement units throughout - * the script engine. These might be i.e. "dB" (deci Bel) for loudness, - * "Hz" (Hertz) for frequencies or "s" for "seconds". + * the script engine. These might be e.g. "dB" (deci Bel) for loudness, + * "Hz" (Hertz) for frequencies or "s" for "seconds". These unit types can + * combined with metric prefixes, for instance "kHz" (kilo Hertz), + * "us" (micro second), etc. * * Originally the script engine only supported abstract integer values for * controlling any synthesis parameter or built-in function argument or * variable. Under certain situations it makes sense though for an * instrument script author to provide values in real, standard measurement - * units, for example setting the frequency of some LFO directly to "20Hz". - * Hence support for standard units in scripts was added as an extension to - * the NKSP script engine. + * units to provide a more natural and intuitive approach for writing + * instrument scripts, for example by setting the frequency of some LFO + * directly to "20Hz" or reducing loudness by "-4.2dB". Hence support for + * standard units in scripts was added as an extension to the NKSP script + * engine. + * + * So a unit consists of 1) a sequence of metric prefixes as scale factor + * (e.g. "k" for kilo) and 2) the actual unit type (e.g. "Hz" for Hertz). + * The unit type is a constant feature of number literals and variables, so + * once a variable was declared with a unit type (or no unit type at all) + * then that unit type of that variable cannot be changed for the entire + * life time of the script. This is different from the unit's metric + * prefix(es) of variables which may freely be changed at runtime. */ class VMUnit { public: /** - * Returns the metric prefix of this unit. A metric prefix essentially - * is just a mathematical scale factor that should be applied to the - * number associated with the measurement unit. Usually a unit either - * has exactly none or one prefix, but note that there might also be - * units with more than one prefix, for example mdB (mili deci bel) - * is used sometimes which has two prefixes. This is an exception though - * and more than two prefixes is currently not supported by the script - * engine. + * Returns the metric prefix(es) of this unit as unit factor. A metric + * prefix essentially is just a mathematical scale factor that should be + * applied to the number associated with the measurement unit. Consider + * a string literal in an NKSP script like '3kHz' where 'k' (kilo) is + * the metric prefix, which essentically is a scale factor of 1000. * - * Start iterating over the prefixes of this unit by passing @c 0 as - * argument to this method. The prefixes are terminated with return - * value VM_NO_PREFIX being always the last element. + * Usually a unit either has exactly none or one metric prefix, but note + * that there might also be units with more than one prefix, for example + * @c mdB (milli deci Bel) is used sometimes which has two prefixes. The + * latter is an exception though and more than two prefixes is currently + * not supported by the script engine. * - * @param i - index of prefix - * @returns prefix of requested index or VM_NO_PREFIX otherwise - * @see unitFactor() + * The factor returned by this method is the final mathematical factor + * that should be multiplied against the number associated with this + * unit. This factor results from the sequence of metric prefixes of + * this unit. + * + * @see MetricPrefix_t, hasUnitFactorNow(), hasUnitFactorEver(), + * VM_NO_FACTOR + * @returns current metric unit factor */ - virtual MetricPrefix_t unitPrefix(vmuint i) const = 0; + virtual vmfloat unitFactor() const = 0; + + //TODO: this still needs to be implemented in tree.h/.pp, built-in functions and as 2nd pass of parser appropriately + /*virtual*/ EverTriState_t hasUnitFactorEver() const { return VM_NEVER; } /** - * Conveniently returns the final mathematical factor that should be - * multiplied against the number associated with this unit. This factor - * results from the sequence of metric prefixes of this unit. + * Whether this unit currently does have any metric unit prefix. + * + * This is actually just a convenience method which returns @c true if + * unitFactor() is not @c 1.0. * - * @see unitPrefix() + * @see MetricPrefix_t, unitFactor(), hasUnitFactorEver(), VM_NO_FACTOR + * @returns @c true if this unit currently has any metric prefix */ - vmfloat unitFactor() const; + bool hasUnitFactorNow() const; /** * This is the actual fundamental measuring unit base type of this unit, * which might be either Hertz, second or Bel. * - * @returns standard unit type identifier or VM_NO_UNIT if no unit used + * Note that a number without a unit type may still have metric + * prefixes. + * + * @returns standard unit type identifier or VM_NO_UNIT if no unit type + * is used for this object */ virtual StdUnit_t unitType() const = 0; @@ -219,8 +267,21 @@ /** * Returns the actual mathematical factor represented by the passed * two @a prefix1 and @a prefix2 arguments. + * + * @returns scale factor of given metric unit prefixes */ static vmfloat unitFactor(MetricPrefix_t prefix1, MetricPrefix_t prefix2); + + /** + * Returns the actual mathematical factor represented by the passed + * @a prefixes array. The passed array should always be terminated by a + * VM_NO_PREFIX value as last element. + * + * @param prefixes - sequence of metric prefixes + * @param size - max. amount of elements of array @a prefixes + * @returns scale factor of given metric unit prefixes + */ + static vmfloat unitFactor(const MetricPrefix_t* prefixes, vmuint size = 2); }; /** @brief Virtual machine expression @@ -254,13 +315,50 @@ * if this expression is i.e. actually a string expression like "12", * calling asInt() will @b not cast that numerical string expression to * an integer expression 12 for you, instead this method will simply - * return NULL! + * return NULL! Same applies if this expression is actually a real + * number expression: asInt() would return NULL in that case as well. * - * @see exprType() + * @see exprType(), asReal(), asNumber() */ VMIntExpr* asInt() const; /** + * In case this expression is a real number (floating point) expression, + * then this method returns a casted pointer to that VMRealExpr object. + * It returns NULL if this expression is not a real number expression. + * + * @b Note: type casting performed by this method is strict! That means + * if this expression is i.e. actually a string expression like "12", + * calling asReal() will @b not cast that numerical string expression to + * a real number expression 12.0 for you, instead this method will + * simply return NULL! Same applies if this expression is actually an + * integer expression: asReal() would return NULL in that case as well. + * + * @see exprType(), asInt(), asNumber() + */ + VMRealExpr* asReal() const; + + /** + * In case this expression is a scalar number expression, that is either + * an integer (scalar) expression or a real number (floating point + * scalar) expression, then this method returns a casted pointer to that + * VMNumberExpr base class object. It returns NULL if this + * expression is neither an integer (scalar), nor a real number (scalar) + * expression. + * + * Since the methods asInt() and asReal() are very strict, this method + * is provided as convenience access in case only very general + * information (e.g. which standard measurement unit is being used or + * whether final operator being effective to this expression) is + * intended to be retrieved of this scalar number expression independent + * from whether this expression is actually an integer or a real number + * expression. + * + * @see exprType(), asInt(), asReal() + */ + VMNumberExpr* asNumber() const; + + /** * In case this expression is a string expression, then this method * returns a casted pointer to that VMStringExpr object. It returns NULL * if this expression is not a string expression. @@ -281,10 +379,10 @@ * returns NULL if this expression is not an integer array expression. * * @b Note: type casting performed by this method is strict! That means - * if this expression is i.e. an integer expression or a string - * expression, calling asIntArray() will @b not cast those scalar - * expressions to an array expression for you, instead this method will - * simply return NULL! + * if this expression is i.e. an integer scalar expression, a real + * number expression or a string expression, calling asIntArray() will + * @b not cast those expressions to an integer array expression for you, + * instead this method will simply return NULL! * * @b Note: this method is currently, and in contrast to its other * counter parts, declared as virtual method. Some deriving classes are @@ -299,6 +397,47 @@ virtual VMIntArrayExpr* asIntArray() const; /** + * In case this expression is a real number (floating point) array + * expression, then this method returns a casted pointer to that + * VMRealArrayExpr object. It returns NULL if this expression is not a + * real number array expression. + * + * @b Note: type casting performed by this method is strict! That means + * if this expression is i.e. a real number scalar expression, an + * integer expression or a string expression, calling asRealArray() will + * @b not cast those scalar expressions to a real number array + * expression for you, instead this method will simply return NULL! + * + * @b Note: this method is currently, and in contrast to its other + * counter parts, declared as virtual method. Some deriving classes are + * currently using this to override this default implementation in order + * to implement an "evaluate now as real number array" behavior. This + * has efficiency reasons, however this also currently makes this part + * of the API less clean and should thus be addressed in future with + * appropriate changes to the API. + * + * @see exprType() + */ + virtual VMRealArrayExpr* asRealArray() const; + + /** + * This is an alternative to calling either asIntArray() or + * asRealArray(). This method here might be used if the fundamental + * scalar data type (real or integer) of the array is not relevant, + * i.e. for just getting the size of the array. Since all as*() methods + * here are very strict regarding type casting, this asArray() method + * sometimes can reduce code complexity. + * + * Likewise calling this method only returns a valid pointer if the + * expression is some array type (currently either integer array or real + * number array). For any other expression type this method will return + * NULL instead. + * + * @see exprType() + */ + VMArrayExpr* asArray() const; + + /** * Returns true in case this expression can be considered to be a * constant expression. A constant expression will retain the same * value throughout the entire life time of a script and the @@ -329,6 +468,60 @@ bool isModifyable() const; }; + /** @brief Virtual machine scalar number expression + * + * This is the abstract base class for integer (scalar) expressions and + * real number (floating point scalar) expressions of scripts. + */ + class VMNumberExpr : virtual public VMExpr, virtual public VMUnit { + public: + /** + * Returns @c true if the value of this expression should be applied + * as final value to the respective destination synthesis chain + * parameter. + * + * This property is somewhat special and dedicated for the purpose of + * this expression's (integer or real number) value to be applied as + * parameter to the synthesis chain of the sampler (i.e. for altering a + * filter cutoff frequency). Now historically and by default all values + * of scripts are applied relatively to the sampler's synthesis chain, + * that is the synthesis parameter value of a script is multiplied + * against other sources for the same synthesis parameter (i.e. an LFO + * or a dedicated MIDI controller either hard wired in the engine or + * defined by the instrument patch). So by default the resulting actual + * final synthesis parameter is a combination of all these sources. This + * has the advantage that it creates a very living and dynamic overall + * sound. + * + * However sometimes there are requirements by script authors where this + * is not what you want. Therefore the NKSP script engine added a + * language extension by prefixing a value in scripts with a @c ! + * character the value will be defined as being the "final" value of the + * destination synthesis parameter, so that causes this value to be + * applied exclusively, and the values of all other sources are thus + * entirely ignored by the sampler's synthesis core as long as this + * value is assigned by the script engine as "final" value for the + * requested synthesis parameter. + */ + virtual bool isFinal() const = 0; + + /** + * Calling this method evaluates the expression and returns the value + * of the expression as integer. If this scalar number expression is a + * real number expression then this method automatically casts the value + * from real number to integer. + */ + vmint evalCastInt(); + + /** + * Calling this method evaluates the expression and returns the value + * of the expression as real number. If this scalar number expression is + * an integer expression then this method automatically casts the value + * from integer to real number. + */ + vmfloat evalCastReal(); + }; + /** @brief Virtual machine integer expression * * This is the abstract base class for all expressions inside scripts which @@ -336,7 +529,7 @@ * abstract method evalInt() to return the actual integer result value of * the expression. */ - class VMIntExpr : virtual public VMExpr, virtual public VMUnit { + class VMIntExpr : virtual public VMNumberExpr { public: /** * Returns the result of this expression as integer (scalar) value. @@ -365,35 +558,46 @@ * Returns always INT_EXPR for instances of this class. */ ExprType_t exprType() const OVERRIDE { return INT_EXPR; } + }; + /** @brief Virtual machine real number (floating point scalar) expression + * + * This is the abstract base class for all expressions inside scripts which + * evaluate to a real number (floating point scalar) value. Deriving classes + * implement the abstract method evalReal() to return the actual floating + * point result value of the expression. + */ + class VMRealExpr : virtual public VMNumberExpr { + public: /** - * Returns @c true if the value of this expression should be applied - * as final value to the respective destination synthesis chain - * parameter. - * - * This property is somewhat special and dedicated for the purpose of - * this expression's integer value to be applied as parameter to the - * synthesis chain of the sampler (i.e. for altering a filter cutoff - * frequency). Now historically and by default all values of scripts are - * applied relatively to the sampler's synthesis chain, that is the - * synthesis parameter value of a script is multiplied against other - * sources for the same synthesis parameter (i.e. an LFO or a dedicated - * MIDI controller either hard wired in the engine or defined by the - * instrument patch). So by default the resulting actual final synthesis - * parameter is a combination of all these sources. This has the - * advantage that it creates a very living and dynamic overall sound. + * Returns the result of this expression as real number (floating point + * scalar) value. This abstract method must be implemented by deriving + * classes. + */ + virtual vmfloat evalReal() = 0; + + /** + * Returns the result of this expression as real number (floating point + * scalar) value and thus behaves similar to the previous method, + * however this overridden method automatically takes unit prefixes into + * account and returns a value corresponding to the expected given unit + * @a prefix. * - * However sometimes there are requirements by script authors where this - * is not what you want. Therefore the NKSP script engine added a - * language extension by prefixing a value in scripts with a @c ! - * character the value will be defined as being the "final" value of the - * destination synthesis parameter, so that causes this value to be - * applied exclusively, and the values of all other sources are thus - * entirely ignored by the sampler's synthesis core as long as this - * value is assigned by the script engine as "final" value for the - * requested synthesis parameter. + * @param prefix - default measurement unit prefix expected by caller */ - virtual bool isFinal() const = 0; + vmfloat evalReal(MetricPrefix_t prefix); + + /** + * This method behaves like the previous method, just that it takes + * a default measurement prefix with two elements (i.e. "milli cents" + * for tuning). + */ + vmfloat evalReal(MetricPrefix_t prefix1, MetricPrefix_t prefix2); + + /** + * Returns always REAL_EXPR for instances of this class. + */ + ExprType_t exprType() const OVERRIDE { return REAL_EXPR; } }; /** @brief Virtual machine string expression @@ -433,6 +637,32 @@ virtual vmint arraySize() const = 0; }; + /** @brief Virtual Machine Number Array Expression + * + * This is the abstract base class for all expressions which either evaluate + * to an integer array or real number array. + */ + class VMNumberArrayExpr : virtual public VMArrayExpr { + public: + /** + * Returns the metric unit factor of the requested array element. + * + * @param i - array element index (must be between 0 .. arraySize() - 1) + * @see VMUnit::unitFactor() for details about metric unit factors + */ + virtual vmfloat unitFactorOfElement(vmuint i) const = 0; + + /** + * Changes the current unit factor of the array element given by element + * index @a i. + * + * @param i - array element index (must be between 0 .. arraySize() - 1) + * @param factor - new unit factor to be assigned + * @see VMUnit::unitFactor() for details about metric unit factors + */ + virtual void assignElementUnitFactor(vmuint i, vmfloat factor) = 0; + }; + /** @brief Virtual Machine Integer Array Expression * * This is the abstract base class for all expressions inside scripts which @@ -440,7 +670,7 @@ * abstract methods arraySize(), evalIntElement() and assignIntElement() to * access the individual integer array values. */ - class VMIntArrayExpr : virtual public VMArrayExpr { + class VMIntArrayExpr : virtual public VMNumberArrayExpr { public: /** * Returns the (scalar) integer value of the array element given by @@ -465,6 +695,38 @@ ExprType_t exprType() const OVERRIDE { return INT_ARR_EXPR; } }; + /** @brief Virtual Machine Real Number Array Expression + * + * This is the abstract base class for all expressions inside scripts which + * evaluate to an array of real numbers (floating point values). Deriving + * classes implement the abstract methods arraySize(), evalRealElement() and + * assignRealElement() to access the array's individual real numbers. + */ + class VMRealArrayExpr : virtual public VMNumberArrayExpr { + public: + /** + * Returns the (scalar) real mumber (floating point value) of the array + * element given by element index @a i. + * + * @param i - array element index (must be between 0 .. arraySize() - 1) + */ + virtual vmfloat evalRealElement(vmuint i) = 0; + + /** + * Changes the current value of an element (given by array element + * index @a i) of this real number array. + * + * @param i - array element index (must be between 0 .. arraySize() - 1) + * @param value - new real number value to be assigned to that array element + */ + virtual void assignRealElement(vmuint i, vmfloat value) = 0; + + /** + * Returns always REAL_ARR_EXPR for instances of this class. + */ + ExprType_t exprType() const OVERRIDE { return REAL_ARR_EXPR; } + }; + /** @brief Arguments (parameters) for being passed to a built-in script function. * * An argument or a set of arguments passed to a script function are @@ -545,8 +807,54 @@ /** * Script data type of the function's return value. If the function does * not return any value (void), then it returns EMPTY_EXPR here. + * + * Some functions may have a different return type depending on the + * arguments to be passed to this function. That's what the @a args + * parameter is for, so that the method implementation can look ahead + * of what kind of parameters are going to be passed to the built-in + * function later on in order to decide which return value type would + * be used and returned by the function accordingly in that case. + * + * @param args - function arguments going to be passed for executing + * this built-in function later on + */ + virtual ExprType_t returnType(VMFnArgs* args) = 0; + + /** + * Standard measuring unit type of the function's result value + * (e.g. second, Hertz). + * + * Some functions may have a different standard measuring unit type for + * their return value depending on the arguments to be passed to this + * function. That's what the @a args parameter is for, so that the + * method implementation can look ahead of what kind of parameters are + * going to be passed to the built-in function later on in order to + * decide which return value type would be used and returned by the + * function accordingly in that case. + * + * @param args - function arguments going to be passed for executing + * this built-in function later on + * @see Unit for details about standard measuring units + */ + virtual StdUnit_t returnUnitType(VMFnArgs* args) = 0; + + /** + * Whether the result value returned by this built-in function is + * considered to be a 'final' value. + * + * Some functions may have a different 'final' feature for their return + * value depending on the arguments to be passed to this function. + * That's what the @a args parameter is for, so that the method + * implementation can look ahead of what kind of parameters are going to + * be passed to the built-in function later on in order to decide which + * return value type would be used and returned by the function + * accordingly in that case. + * + * @param args - function arguments going to be passed for executing + * this built-in function later on + * @see VMNumberExpr::isFinal() for details about 'final' values */ - virtual ExprType_t returnType() = 0; + virtual bool returnsFinal(VMFnArgs* args) = 0; /** * Minimum amount of function arguments this function accepts. If a @@ -630,13 +938,15 @@ * * @param iArg - index of the function argument in question * (must be between 0 .. maxAllowedArgs() - 1) + * @param type - standard measurement unit data type used for that + * function argument by currently parsed script * * @return true if a metric prefix would be accepted for the respective * function argument by this function * * @see MetricPrefix_t */ - virtual bool acceptsArgUnitPrefix(vmint iArg) const; + virtual bool acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const; /** * This method is called by the parser to check whether arguments @@ -654,7 +964,7 @@ * @return true if a "final" value would be accepted for the respective * function argument by the function * - * @see VMIntExpr::isFinal() + * @see VMNumberExpr::isFinal(), returnsFinal() */ virtual bool acceptsArgFinal(vmint iArg) const; @@ -674,6 +984,40 @@ virtual bool modifiesArg(vmint iArg) const = 0; /** + * This method is called by the parser to let the built-in function + * perform its own, individual parse time checks on the arguments to be + * passed to the built-in function. So this method is the place for + * implementing custom checks which are very specific to the individual + * built-in function's purpose and its individual requirements. + * + * For instance the built-in 'in_range()' function uses this method to + * check whether the last 2 of their 3 arguments are of same data type + * and if not it triggers a parser error. 'in_range()' also checks + * whether all of its 3 arguments do have the same standard measuring + * unit type and likewise raises a parser error if not. + * + * For less critical issues built-in functions may also raise parser + * warnings instead. + * + * It is recommended that classes implementing (that is overriding) this + * method should always call their super class's implementation of this + * method to ensure their potential parse time checks are always + * performed as well. + * + * @param args - function arguments going to be passed for executing + * this built-in function later on + * @param err - the parser's error handler to be called by this method + * implementation to trigger a parser error with the + * respective error message text + * @param wrn - the parser's warning handler to be called by this method + * implementation to trigger a parser warning with the + * respective warning message text + */ + virtual void checkArgs(VMFnArgs* args, + std::function err, + std::function wrn); + + /** * Implements the actual function execution. This exec() method is * called by the VM whenever this function implementation shall be * executed at script runtime. This method blocks until the function @@ -959,8 +1303,9 @@ /** @brief Built-in VM 8 bit integer array variable. * * Used for defining built-in integer array script variables (8 bit per - * array element). Currently there is no support for any other kind of array - * type. So all integer arrays of scripts use 8 bit data types. + * array element). Currently there is no support for any other kind of + * built-in array type. So all built-in integer arrays accessed by scripts + * use 8 bit data types. */ struct VMInt8Array { int8_t* data; @@ -972,7 +1317,8 @@ /** @brief Virtual machine script variable. * - * Common interface for all variables accessed in scripts. + * Common interface for all variables accessed in scripts, independent of + * their precise data type. */ class VMVariable : virtual public VMExpr { public: @@ -993,7 +1339,7 @@ */ virtual void assignExpr(VMExpr* expr) = 0; }; - + /** @brief Dynamically executed variable (abstract base class). * * Interface for the implementation of a dynamically generated content of @@ -1067,7 +1413,7 @@ */ class VMDynIntVar : virtual public VMDynVar, virtual public VMIntExpr { public: - MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE { return VM_NO_PREFIX; } + vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; } StdUnit_t unitType() const OVERRIDE { return VM_NO_UNIT; } bool isFinal() const OVERRIDE { return false; } }; @@ -1349,6 +1695,8 @@ case EMPTY_EXPR: return "empty"; case INT_EXPR: return "integer"; case INT_ARR_EXPR: return "integer array"; + case REAL_EXPR: return "real number"; + case REAL_ARR_EXPR: return "real number array"; case STRING_EXPR: return "string"; case STRING_ARR_EXPR: return "string array"; } @@ -1356,6 +1704,43 @@ } /** + * Convenience function used for retrieving the data type of a script + * variable name being passed to this function. + * + * @param name - some script variable name (e.g. "$foo") + * @return variable's data type (e.g. INT_EXPR for example above) + */ + inline ExprType_t exprTypeOfVarName(const String& name) { + if (name.empty()) return (ExprType_t) -1; + const char prefix = name[0]; + switch (prefix) { + case '$': return INT_EXPR; + case '%': return INT_ARR_EXPR; + case '~': return REAL_EXPR; + case '?': return REAL_ARR_EXPR; + case '@': return STRING_EXPR; + case '!': return STRING_ARR_EXPR; + } + return (ExprType_t) -1; + } + + /** + * Returns @c true in case the passed data type is some array data type. + */ + inline bool isArray(const ExprType_t& type) { + return type == INT_ARR_EXPR || type == REAL_ARR_EXPR || + type == STRING_ARR_EXPR; + } + + /** + * Returns @c true in case the passed data type is some scalar number type + * (i.e. not an array and not a string). + */ + inline bool isNumber(const ExprType_t& type) { + return type == INT_EXPR || type == REAL_EXPR; + } + + /** * Convenience function used for converting an StdUnit_t constant to a * string, i.e. for generating error message by the parser. */ @@ -1468,12 +1853,17 @@ bool isStringLiteral() const; ///< Returns true in case this source token represents a string literal (i.e. "Some text"). bool isComment() const; ///< Returns true in case this source token represents a source code comment. bool isPreprocessor() const; ///< Returns true in case this source token represents a preprocessor statement. + bool isMetricPrefix() const; + bool isStdUnit() const; bool isOther() const; ///< Returns true in case this source token represents anything else not covered by the token types mentioned above. // extended types bool isIntegerVariable() const; ///< Returns true in case this source token represents an integer variable name (i.e. "$someIntVariable"). + bool isRealVariable() const; ///< Returns true in case this source token represents a floating point variable name (i.e. "~someRealVariable"). bool isStringVariable() const; ///< Returns true in case this source token represents an string variable name (i.e. "\@someStringVariable"). - bool isArrayVariable() const; ///< Returns true in case this source token represents an array variable name (i.e. "%someArryVariable"). + bool isIntArrayVariable() const; ///< Returns true in case this source token represents an integer array variable name (i.e. "%someArrayVariable"). + bool isRealArrayVariable() const; ///< Returns true in case this source token represents a real number array variable name (i.e. "?someArrayVariable"). + bool isArrayVariable() const DEPRECATED_API; ///< Returns true in case this source token represents an @b integer array variable name (i.e. "%someArrayVariable"). @deprecated This method will be removed, use isIntArrayVariable() instead. bool isEventHandlerName() const; ///< Returns true in case this source token represents an event handler name (i.e. "note", "release", "controller"). VMSourceToken& operator=(const VMSourceToken& other);