/[svn]/linuxsampler/trunk/src/scriptvm/common.h
ViewVC logotype

Diff of /linuxsampler/trunk/src/scriptvm/common.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2619 by schoenebeck, Wed Jun 11 13:24:32 2014 UTC revision 2942 by schoenebeck, Wed Jul 13 15:51:06 2016 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (c) 2014 Christian Schoenebeck   * Copyright (c) 2014-2016 Christian Schoenebeck
3   *   *
4   * http://www.linuxsampler.org   * http://www.linuxsampler.org
5   *   *
# Line 20  Line 20 
20  #include <stddef.h> // offsetof()  #include <stddef.h> // offsetof()
21    
22  namespace LinuxSampler {  namespace LinuxSampler {
23        
24        /**
25         * Identifies the type of a noteworthy issue identified by the script
26         * parser. That's either a parser error or parser warning.
27         */
28      enum ParserIssueType_t {      enum ParserIssueType_t {
29          PARSER_ERROR,          PARSER_ERROR, ///< Script parser encountered an error, the script cannot be executed.
30          PARSER_WARNING          PARSER_WARNING ///< Script parser encountered a warning, the script may be executed if desired, but the script may not necessarily behave as originally intended by the script author.
31      };      };
32    
33        /** @brief Expression's data type.
34         *
35         * Identifies to which data type an expression within a script evaluates to.
36         * This can for example reflect the data type of script function arguments,
37         * script function return values, but also the resulting data type of some
38         * mathematical formula within a script.
39         */
40      enum ExprType_t {      enum ExprType_t {
41          EMPTY_EXPR, ///< i.e. on invalid expressions or i.e. a function call that does not return a result value          EMPTY_EXPR, ///< i.e. on invalid expressions or i.e. a function call that does not return a result value (the built-in wait() or message() functions for instance)
42          INT_EXPR,          INT_EXPR, ///< integer (scalar) expression
43          INT_ARR_EXPR,          INT_ARR_EXPR, ///< integer array expression
44          STRING_EXPR,          STRING_EXPR, ///< string expression
45          STRING_ARR_EXPR,          STRING_ARR_EXPR, ///< string array expression
46      };      };
47    
48        /** @brief Result flags of a script statement or script function call.
49         *
50         * A set of bit flags which provide informations about the success or
51         * failure of a statement within a script. That's also especially used for
52         * providing informations about success / failure of a call to a built-in
53         * script function. The virtual machine evaluates these flags during runtime
54         * to decide whether it should i.e. stop or suspend execution of a script.
55         *
56         * Since these are bit flags, these constants are bitwise combined.
57         */
58      enum StmtFlags_t {      enum StmtFlags_t {
59         STMT_SUCCESS = 0, ///< Function / statement was executed successfully, no error occurred.         STMT_SUCCESS = 0, ///< Function / statement was executed successfully, no error occurred.
60         STMT_ABORT_SIGNALLED = 1, ///< VM should stop the current callback execution (usually because of an error, but might also be without an error reason).         STMT_ABORT_SIGNALLED = 1, ///< VM should stop the current callback execution (usually because of an error, but might also be without an error reason, i.e. when the built-in script function exit() was called).
61         STMT_SUSPEND_SIGNALLED = (1<<1),         STMT_SUSPEND_SIGNALLED = (1<<1), ///< VM supended execution, either because the script called the built-in wait() script function or because the script consumed too much execution time and was forced by the VM to be suspended for some time
62         STMT_ERROR_OCCURRED = (1<<2),         STMT_ERROR_OCCURRED = (1<<2), ///< VM stopped execution due to some script runtime error that occurred
63      };      };
64    
65        /** @brief Virtual machine execution status.
66         *
67         * A set of bit flags which reflect the current overall execution status of
68         * the virtual machine concerning a certain script execution instance.
69         *
70         * Since these are bit flags, these constants are bitwise combined.
71         */
72      enum VMExecStatus_t {      enum VMExecStatus_t {
73          VM_EXEC_NOT_RUNNING = 0,          VM_EXEC_NOT_RUNNING = 0, ///< Script is currently not executed by the VM.
74          VM_EXEC_RUNNING = 1,          VM_EXEC_RUNNING = 1, ///< The VM is currently executing the script.
75          VM_EXEC_SUSPENDED = (1<<1),          VM_EXEC_SUSPENDED = (1<<1), ///< Script is currently suspended by the VM, either because the script called the built-in wait() script function or because the script consumed too much execution time and was forced by the VM to be suspended for some time.
76          VM_EXEC_ERROR = (1<<2),          VM_EXEC_ERROR = (1<<2), ///< A runtime error occurred while executing the script (i.e. a call to some built-in script function failed).
77        };
78    
79        /** @brief Script event handler type.
80         *
81         * Identifies one of the possible event handler callback types defined by
82         * the NKSP script language.
83         */
84        enum VMEventHandlerType_t {
85            VM_EVENT_HANDLER_INIT, ///< Initilization event handler, that is script's "on init ... end on" code block.
86            VM_EVENT_HANDLER_NOTE, ///< Note event handler, that is script's "on note ... end on" code block.
87            VM_EVENT_HANDLER_RELEASE, ///< Release event handler, that is script's "on release ... end on" code block.
88            VM_EVENT_HANDLER_CONTROLLER, ///< Controller event handler, that is script's "on controller ... end on" code block.
89      };      };
90    
91        // just symbol prototyping
92      class VMIntExpr;      class VMIntExpr;
93      class VMStringExpr;      class VMStringExpr;
94      class VMIntArrayExpr;      class VMIntArrayExpr;
95      class VMStringArrayExpr;      class VMStringArrayExpr;
96    
97        /** @brief Virtual machine expression
98         *
99         * This is the abstract base class for all expressions of scripts.
100         * Deriving classes must implement the abstract method exprType().
101         *
102         * An expression within a script is translated into one instance of this
103         * class. It allows a high level access for the virtual machine to evaluate
104         * and handle expressions appropriately during execution. Expressions are
105         * for example all kinds of formulas, function calls, statements or a
106         * combination of them. Most of them evaluate to some kind of value, which
107         * might be further processed as part of encompassing expressions to outer
108         * expression results and so forth.
109         */
110      class VMExpr {      class VMExpr {
111      public:      public:
112            /**
113             * Identifies the data type to which the result of this expression
114             * evaluates to. This abstract method must be implemented by deriving
115             * classes.
116             */
117          virtual ExprType_t exprType() const = 0;          virtual ExprType_t exprType() const = 0;
118    
119            /**
120             * In case this expression is an integer expression, then this method
121             * returns a casted pointer to that VMIntExpr object. It returns NULL
122             * if this expression is not an integer expression.
123             *
124             * @b Note: type casting performed by this method is strict! That means
125             * if this expression is i.e. actually a string expression like "12",
126             * calling asInt() will @b not cast that numerical string expression to
127             * an integer expression 12 for you, instead this method will simply
128             * return NULL!
129             *
130             * @see exprType()
131             */
132          VMIntExpr* asInt() const;          VMIntExpr* asInt() const;
133    
134            /**
135             * In case this expression is a string expression, then this method
136             * returns a casted pointer to that VMStringExpr object. It returns NULL
137             * if this expression is not a string expression.
138             *
139             * @b Note: type casting performed by this method is strict! That means
140             * if this expression is i.e. actually an integer expression like 120,
141             * calling asString() will @b not cast that integer expression to a
142             * string expression "120" for you, instead this method will simply
143             * return NULL!
144             *
145             * @see exprType()
146             */
147          VMStringExpr* asString() const;          VMStringExpr* asString() const;
148    
149            /**
150             * In case this expression is an integer array expression, then this
151             * method returns a casted pointer to that VMIntArrayExpr object. It
152             * returns NULL if this expression is not an integer array expression.
153             *
154             * @b Note: type casting performed by this method is strict! That means
155             * if this expression is i.e. an integer expression or a string
156             * expression, calling asIntArray() will @b not cast those scalar
157             * expressions to an array expression for you, instead this method will
158             * simply return NULL!
159             *
160             * @see exprType()
161             */
162          VMIntArrayExpr* asIntArray() const;          VMIntArrayExpr* asIntArray() const;
163      };      };
164    
165        /** @brief Virtual machine integer expression
166         *
167         * This is the abstract base class for all expressions inside scripts which
168         * evaluate to an integer (scalar) value. Deriving classes implement the
169         * abstract method evalInt() to return the actual integer result value of
170         * the expression.
171         */
172      class VMIntExpr : virtual public VMExpr {      class VMIntExpr : virtual public VMExpr {
173      public:      public:
174            /**
175             * Returns the result of this expression as integer (scalar) value.
176             * This abstract method must be implemented by deriving classes.
177             */
178          virtual int evalInt() = 0;          virtual int evalInt() = 0;
179          ExprType_t exprType() const { return INT_EXPR; }  
180            /**
181             * Returns always INT_EXPR for instances of this class.
182             */
183            ExprType_t exprType() const OVERRIDE { return INT_EXPR; }
184      };      };
185    
186        /** @brief Virtual machine string expression
187         *
188         * This is the abstract base class for all expressions inside scripts which
189         * evaluate to a string value. Deriving classes implement the abstract
190         * method evalStr() to return the actual string result value of the
191         * expression.
192         */
193      class VMStringExpr : virtual public VMExpr {      class VMStringExpr : virtual public VMExpr {
194      public:      public:
195            /**
196             * Returns the result of this expression as string value. This abstract
197             * method must be implemented by deriving classes.
198             */
199          virtual String evalStr() = 0;          virtual String evalStr() = 0;
200          ExprType_t exprType() const { return STRING_EXPR; }  
201            /**
202             * Returns always STRING_EXPR for instances of this class.
203             */
204            ExprType_t exprType() const OVERRIDE { return STRING_EXPR; }
205      };      };
206    
207        /** @brief Virtual Machine Array Value Expression
208         *
209         * This is the abstract base class for all expressions inside scripts which
210         * evaluate to some kind of array value. Deriving classes implement the
211         * abstract method arraySize() to return the amount of elements within the
212         * array.
213         */
214      class VMArrayExpr : virtual public VMExpr {      class VMArrayExpr : virtual public VMExpr {
215      public:      public:
216            /**
217             * Returns amount of elements in this array. This abstract method must
218             * be implemented by deriving classes.
219             */
220          virtual int arraySize() const = 0;          virtual int arraySize() const = 0;
221      };      };
222    
223        /** @brief Virtual Machine Integer Array Expression
224         *
225         * This is the abstract base class for all expressions inside scripts which
226         * evaluate to an array of integer values. Deriving classes implement the
227         * abstract methods arraySize(), evalIntElement() and assignIntElement() to
228         * access the individual integer array values.
229         */
230      class VMIntArrayExpr : virtual public VMArrayExpr {      class VMIntArrayExpr : virtual public VMArrayExpr {
231      public:      public:
232            /**
233             * Returns the (scalar) integer value of the array element given by
234             * element index @a i.
235             *
236             * @param i - array element index (must be between 0 .. arraySize() - 1)
237             */
238          virtual int evalIntElement(uint i) = 0;          virtual int evalIntElement(uint i) = 0;
239    
240            /**
241             * Changes the current value of an element (given by array element
242             * index @a i) of this integer array.
243             *
244             * @param i - array element index (must be between 0 .. arraySize() - 1)
245             * @param value - new integer scalar value to be assigned to that array element
246             */
247          virtual void assignIntElement(uint i, int value) = 0;          virtual void assignIntElement(uint i, int value) = 0;
248    
249            /**
250             * Returns always INT_ARR_EXPR for instances of this class.
251             */
252            ExprType_t exprType() const OVERRIDE { return INT_ARR_EXPR; }
253      };      };
254    
255        /** @brief Arguments (parameters) for being passed to a built-in script function.
256         *
257         * An argument or a set of arguments passed to a script function are
258         * translated by the parser to an instance of this class. This abstract
259         * interface class is used by implementations of built-in functions to
260         * obtain the individual function argument values being passed to them at
261         * runtime.
262         */
263      class VMFnArgs {      class VMFnArgs {
264      public:      public:
265            /**
266             * Returns the amount of arguments going to be passed to the script
267             * function.
268             */
269          virtual int argsCount() const = 0;          virtual int argsCount() const = 0;
270    
271            /**
272             * Returns the respective argument (requested by argument index @a i) of
273             * this set of arguments. This method is called by implementations of
274             * built-in script functions to obtain the value of each function
275             * argument passed to the function at runtime.
276             *
277             * @param i - function argument index (indexed from left to right)
278             */
279          virtual VMExpr* arg(int i) = 0;          virtual VMExpr* arg(int i) = 0;
280      };      };
281    
282        /** @brief Result value returned from a call to a built-in script function.
283         *
284         * Implementations of built-in script functions return an instance of this
285         * object to let the virtual machine obtain the result value of the function
286         * call, which might then be further processed by the virtual machine
287         * according to the script. It also provides informations about the success
288         * or failure of the function call.
289         */
290      class VMFnResult {      class VMFnResult {
291      public:      public:
292            /**
293             * Returns the result value of the function call, represented by a high
294             * level expression object.
295             */
296          virtual VMExpr* resultValue() = 0;          virtual VMExpr* resultValue() = 0;
297    
298            /**
299             * Provides detailed informations of the success / failure of the
300             * function call. The virtual machine is evaluating the flags returned
301             * here to decide whether it must abort or suspend execution of the
302             * script at this point.
303             */
304          virtual StmtFlags_t resultFlags() { return STMT_SUCCESS; }          virtual StmtFlags_t resultFlags() { return STMT_SUCCESS; }
305      };      };
306    
307      /** @brief VM built-in function.      /** @brief Virtual machine built-in function.
308       *       *
309       * Abstract base class for built-in script functions, defining the interface       * Abstract base class for built-in script functions, defining the interface
310       * for all built-in script function implementations.       * for all built-in script function implementations. All built-in script
311         * functions are deriving from this abstract interface class in order to
312         * provide their functionality to the virtual machine with this unified
313         * interface.
314         *
315         * The methods of this interface class provide two purposes:
316         *
317         * 1. When a script is loaded, the script parser uses the methods of this
318         *    interface to check whether the script author was calling the
319         *    respective built-in script function in a correct way. For example
320         *    the parser checks whether the required amount of parameters were
321         *    passed to the function and whether the data types passed match the
322         *    data types expected by the function. If not, loading the script will
323         *    be aborted with a parser error, describing to the user (i.e. script
324         *    author) the precise misusage of the respective function.
325         * 2. After the script was loaded successfully and the script is executed,
326         *    the virtual machine calls the exec() method of the respective built-in
327         *    function to provide the actual functionality of the built-in function
328         *    call.
329       */       */
330      class VMFunction {      class VMFunction {
331      public:      public:
332          /**          /**
333           * Script data type of the function's return value. If the function does           * Script data type of the function's return value. If the function does
334           * not return any value, then it returns EMPTY_EXPR here.           * not return any value (void), then it returns EMPTY_EXPR here.
335           */           */
336          virtual ExprType_t returnType() = 0;          virtual ExprType_t returnType() = 0;
337    
# Line 127  namespace LinuxSampler { Line 353  namespace LinuxSampler {
353           * Script data type of the function's @c iArg 'th function argument.           * Script data type of the function's @c iArg 'th function argument.
354           * The information provided here is less strong than acceptsArgType().           * The information provided here is less strong than acceptsArgType().
355           * The parser will compare argument data types provided in scripts by           * The parser will compare argument data types provided in scripts by
356           * calling cceptsArgType(). The return value of argType() is used by the           * calling acceptsArgType(). The return value of argType() is used by the
357           * parser instead to show an appropriate parser error which data type           * parser instead to show an appropriate parser error which data type
358           * this function usually expects as "default" data type. Reason: a           * this function usually expects as "default" data type. Reason: a
359           * function may accept multiple data types for a certain function           * function may accept multiple data types for a certain function
# Line 135  namespace LinuxSampler { Line 361  namespace LinuxSampler {
361           * that case to the type it actually needs.           * that case to the type it actually needs.
362           *           *
363           * @param iArg - index of the function argument in question           * @param iArg - index of the function argument in question
364             *               (must be between 0 .. maxAllowedArgs() - 1)
365           */           */
366          virtual ExprType_t argType(int iArg) const = 0;          virtual ExprType_t argType(int iArg) const = 0;
367    
# Line 142  namespace LinuxSampler { Line 369  namespace LinuxSampler {
369           * This function is called by the parser to check whether arguments           * This function is called by the parser to check whether arguments
370           * passed in scripts to this function are accepted by this function. If           * passed in scripts to this function are accepted by this function. If
371           * a script calls this function with an argument's data type not           * a script calls this function with an argument's data type not
372           * accepted by this function, the parser will throw a parser error.           * accepted by this function, the parser will throw a parser error. On
373             * such errors the data type returned by argType() will be used to
374             * assemble an appropriate error message regarding the precise misusage
375             * of the built-in function.
376           *           *
377           * @param iArg - index of the function argument in question           * @param iArg - index of the function argument in question
378             *               (must be between 0 .. maxAllowedArgs() - 1)
379           * @param type - script data type used for this function argument by           * @param type - script data type used for this function argument by
380           *               currently parsed script           *               currently parsed script
381             * @return true if the given data type would be accepted for the
382             *         respective function argument by the function
383           */           */
384          virtual bool acceptsArgType(int iArg, ExprType_t type) const = 0;          virtual bool acceptsArgType(int iArg, ExprType_t type) const = 0;
385    
386          /**          /**
387           * Implements the actual function execution. This function is called by           * Implements the actual function execution. This exec() method is
388           * the VM when this function shall be executed at script runtime.           * called by the VM whenever this function implementation shall be
389             * executed at script runtime. This method blocks until the function
390             * call completed.
391           *           *
392           * @param args - function arguments for executing this built-in function           * @param args - function arguments for executing this built-in function
393             * @returns function's return value (if any) and general status
394             *          informations (i.e. whether the function call caused a
395             *          runtime error)
396           */           */
397          virtual VMFnResult* exec(VMFnArgs* args) = 0;          virtual VMFnResult* exec(VMFnArgs* args) = 0;
398    
399          /**          /**
400           * Concenience method for function implementations to show warning           * Convenience method for function implementations to show warning
401           * messages.           * messages during actual execution of the built-in function.
402           *           *
403           * @param txt - warning text           * @param txt - runtime warning text to be shown to user
404           */           */
405          void wrnMsg(const String& txt);          void wrnMsg(const String& txt);
406    
407          /**          /**
408           * Concenience method for function implementations to show error           * Convenience method for function implementations to show error
409           * messages.           * messages during actual execution of the built-in function.
410           *           *
411           * @param txt - error text           * @param txt - runtime error text to be shown to user
412           */           */
413          void errMsg(const String& txt);          void errMsg(const String& txt);
414      };      };
415    
416      /**      /** @brief Virtual machine relative pointer.
417         *
418       * POD base of VMIntRelPtr and VMInt8RelPtr structures. Not intended to be       * POD base of VMIntRelPtr and VMInt8RelPtr structures. Not intended to be
419       * used directly. Use VMIntRelPtr or VMInt8RelPtr instead.       * used directly. Use VMIntRelPtr or VMInt8RelPtr instead.
420         *
421         * @see VMIntRelPtr, VMInt8RelPtr
422       */       */
423      struct VMRelPtr {      struct VMRelPtr {
424          void** base; ///< Base pointer.          void** base; ///< Base pointer.
425          int offset;  ///< Offset (in bytes) to base pointer.          int offset;  ///< Offset (in bytes) relative to base pointer.
426      };      };
427    
428      /** @brief Pointer to built-in VM integer variable (of C/C++ type int).      /** @brief Pointer to built-in VM integer variable (of C/C++ type int).
429       *       *
430       * Used for defining built-in integer script variables.       * Used for defining built-in 32 bit integer script variables.
431       *       *
432       * @b CAUTION: You may only use this class for pointing to C/C++ variables       * @b CAUTION: You may only use this class for pointing to C/C++ variables
433       * of type "int" (which on most systems is 32 bit in size). If the C/C++ int       * of type "int" (which on most systems is 32 bit in size). If the C/C++ int
# Line 220  namespace LinuxSampler { Line 461  namespace LinuxSampler {
461    
462      /** @brief Pointer to built-in VM integer variable (of C/C++ type int8_t).      /** @brief Pointer to built-in VM integer variable (of C/C++ type int8_t).
463       *       *
464       * Used for defining built-in integer script variables.       * Used for defining built-in 8 bit integer script variables.
465       *       *
466       * @b CAUTION: You may only use this class for pointing to C/C++ variables       * @b CAUTION: You may only use this class for pointing to C/C++ variables
467       * of type "int8_t" (8 bit integer). If the C/C++ int variable you want to       * of type "int8_t" (8 bit integer). If the C/C++ int variable you want to
# Line 252  namespace LinuxSampler { Line 493  namespace LinuxSampler {
493    
494      /**      /**
495       * Convenience macro for initializing VMIntRelPtr and VMInt8RelPtr       * Convenience macro for initializing VMIntRelPtr and VMInt8RelPtr
496       * structures. Example:       * structures. Usage example:
497       * @code       * @code
498       * struct Foo {       * struct Foo {
499       *   uint8_t a;       *   uint8_t a; // native representation of a built-in integer script variable
500       *   int b;       *   int b; // native representation of another built-in integer script variable
501         *   int c; // native representation of another built-in integer script variable
502         *   uint8_t d; // native representation of another built-in integer script variable
503       * };       * };
504       *       *
505       * Foo foo1 = (Foo) { 1, 3000 };       * // initializing the built-in script variables to some values
506       * Foo foo2 = (Foo) { 2, 4000 };       * Foo foo1 = (Foo) { 1, 2000, 3000, 4 };
507         * Foo foo2 = (Foo) { 5, 6000, 7000, 8 };
508       *       *
509       * Foo* pFoo;       * Foo* pFoo;
510       *       *
511       * VMInt8RelPtr var1 = DECLARE_VMINT(pFoo, class Foo, a);       * VMInt8RelPtr varA = DECLARE_VMINT(pFoo, class Foo, a);
512       * VMIntRelPtr  var2 = DECLARE_VMINT(pFoo, class Foo, b);       * VMIntRelPtr  varB = DECLARE_VMINT(pFoo, class Foo, b);
513         * VMIntRelPtr  varC = DECLARE_VMINT(pFoo, class Foo, c);
514         * VMInt8RelPtr varD = DECLARE_VMINT(pFoo, class Foo, d);
515       *       *
516       * pFoo = &foo1;       * pFoo = &foo1;
517       * printf("%d\n", var1->evalInt()); // will print 1       * printf("%d\n", varA->evalInt()); // will print 1
518       * printf("%d\n", var2->evalInt()); // will print 3000       * printf("%d\n", varB->evalInt()); // will print 2000
519         * printf("%d\n", varC->evalInt()); // will print 3000
520         * printf("%d\n", varD->evalInt()); // will print 4
521         *
522         * // same printf() code, just with pFoo pointer being changed ...
523       *       *
524       * pFoo = &foo2;       * pFoo = &foo2;
525       * printf("%d\n", var1->evalInt()); // will print 2       * printf("%d\n", varA->evalInt()); // will print 5
526       * printf("%d\n", var2->evalInt()); // will print 4000       * printf("%d\n", varB->evalInt()); // will print 6000
527         * printf("%d\n", varC->evalInt()); // will print 7000
528         * printf("%d\n", varD->evalInt()); // will print 8
529       * @endcode       * @endcode
530         * As you can see above, by simply changing one single pointer, you can
531         * remap a huge bunch of built-in integer script variables to completely
532         * different native values/native variables. Which especially reduces code
533         * complexity inside the sampler engines which provide the actual script
534         * functionalities.
535       */       */
536      #define DECLARE_VMINT(basePtr, T_struct, T_member) ( \      #define DECLARE_VMINT(basePtr, T_struct, T_member) ( \
537          (VMRelPtr) {                                     \          (VMRelPtr) {                                     \
# Line 285  namespace LinuxSampler { Line 542  namespace LinuxSampler {
542    
543      /** @brief Built-in VM 8 bit integer array variable.      /** @brief Built-in VM 8 bit integer array variable.
544       *       *
545       * Used for defining built-in integer array script variables.       * Used for defining built-in integer array script variables (8 bit per
546         * array element). Currently there is no support for any other kind of array
547         * type. So all integer arrays of scripts use 8 bit data types.
548       */       */
549      struct VMInt8Array {      struct VMInt8Array {
550          int8_t* data;          int8_t* data;
# Line 294  namespace LinuxSampler { Line 553  namespace LinuxSampler {
553          VMInt8Array() : data(NULL), size(0) {}          VMInt8Array() : data(NULL), size(0) {}
554      };      };
555    
556        /** @brief Dynamically executed variable (abstract base class).
557         *
558         * Interface for the implementation of a dynamically generated content of
559         * a built-in script variable. Most built-in variables are simply pointers
560         * to some native location in memory. So when a script reads them, the
561         * memory location is simply read to get the value of the variable. A
562         * dynamic variable however is not simply a memory location. For each access
563         * to a dynamic variable some native code is executed to actually generate
564         * and provide the content (value) of this type of variable.
565         */
566        class VMDynVar : virtual public VMExpr {
567        public:
568            /**
569             * Whether a script may modify the content of this dynamic variable by
570             * assigning a new value to it.
571             *
572             * @see isConstExpr(), assign()
573             */
574            virtual bool isAssignable() const = 0;
575    
576            /**
577             * Returns true in case this dynamic variable can be considered to be a
578             * constant expression. A constant expression will retain the same value
579             * throughout the entire life time of a script and the expression's
580             * constant value may be evaluated already at script parse time, which
581             * may result in performance benefits during script runtime.
582             *
583             * However due to the "dynamic" behavior of dynamic variables, almost
584             * all dynamic variables are probably not constant expressions. That's
585             * why this method returns @c false by default. If you are really sure
586             * that your dynamic variable implementation can be considered a
587             * constant expression then you may override this method and return
588             * @c true instead. Note that when you return @c true here, your
589             * dynamic variable will really just be executed once; and exectly
590             * already when the script is loaded!
591             *
592             * As an example you may implement a "constant" built-in dynamic
593             * variable that checks for a certain operating system feature and
594             * returns the result of that OS feature check as content (value) of
595             * this dynamic variable. Since the respective OS feature might become
596             * available/unavailable after OS updates, software migration, etc. the
597             * OS feature check should at least be performed once each time the
598             * application is launched. And since the OS feature check might take a
599             * certain amount of execution time, it might make sense to only
600             * perform the check if the respective variable name is actually
601             * referenced at all in the script to be loaded. Note that the dynamic
602             * variable will still be evaluated again though if the script is
603             * loaded again. So it is up to you to probably cache the result in the
604             * implementation of your dynamic variable.
605             *
606             * On doubt, please rather consider to use a constant built-in script
607             * variable instead of implementing a "constant" dynamic variable, due
608             * to the runtime overhead a dynamic variable may cause.
609             *
610             * @see isAssignable()
611             */
612            virtual bool isConstExpr() const { return false; }
613    
614            /**
615             * In case this dynamic variable is assignable, the new value (content)
616             * to be assigned to this dynamic variable.
617             *
618             * By default this method does nothing. Override and implement this
619             * method in your subclass in case your dynamic variable allows to
620             * assign a new value by script.
621             *
622             * @param expr - new value to be assigned to this variable
623             */
624            virtual void assign(VMExpr* expr) {}
625        };
626    
627        /** @brief Dynamically executed variable (of integer data type).
628         *
629         * This is the base class for all built-in integer script variables whose
630         * variable content needs to be provided dynamically by executable native
631         * code on each script variable access.
632         */
633        class VMDynIntVar : virtual public VMDynVar, virtual public VMIntExpr {
634        public:
635        };
636    
637        /** @brief Dynamically executed variable (of string data type).
638         *
639         * This is the base class for all built-in string script variables whose
640         * variable content needs to be provided dynamically by executable native
641         * code on each script variable access.
642         */
643        class VMDynStringVar : virtual public VMDynVar, virtual public VMStringExpr {
644        public:
645        };
646    
647      /** @brief Provider for built-in script functions and variables.      /** @brief Provider for built-in script functions and variables.
648       *       *
649       * Abstract base class defining the interface for all classes which add and       * Abstract base class defining the high-level interface for all classes
650       * implement built-in script functions and built-in script variables.       * which add and implement built-in script functions and built-in script
651         * variables.
652       */       */
653      class VMFunctionProvider {      class VMFunctionProvider {
654      public:      public:
655          /**          /**
656           * Returns pointer to the built-in function with the given function           * Returns pointer to the built-in function with the given function
657           * name, or NULL if there is no built-in function with that name.           * @a name, or NULL if there is no built-in function with that function
658             * name.
659           *           *
660           * @param name - function name           * @param name - function name (i.e. "wait" or "message" or "exit", etc.)
661           */           */
662          virtual VMFunction* functionByName(const String& name) = 0;          virtual VMFunction* functionByName(const String& name) = 0;
663    
664          /**          /**
665           * Returns a variable name indexed map of all built-in script variables           * Returns a variable name indexed map of all built-in script variables
666           * which point to native "int" (usually 32 bit) variables.           * which point to native "int" scalar (usually 32 bit) variables.
667           */           */
668          virtual std::map<String,VMIntRelPtr*> builtInIntVariables() = 0;          virtual std::map<String,VMIntRelPtr*> builtInIntVariables() = 0;
669    
670          /**          /**
671           * Returns a variable name indexed map of all built-in script variables           * Returns a variable name indexed map of all built-in script integer
672           * which point to native "int8_t" (8 bit) variables.           * array variables with array element type "int8_t" (8 bit).
673           */           */
674          virtual std::map<String,VMInt8Array*> builtInIntArrayVariables() = 0;          virtual std::map<String,VMInt8Array*> builtInIntArrayVariables() = 0;
675    
# Line 326  namespace LinuxSampler { Line 678  namespace LinuxSampler {
678           * variables, which never change their value at runtime.           * variables, which never change their value at runtime.
679           */           */
680          virtual std::map<String,int> builtInConstIntVariables() = 0;          virtual std::map<String,int> builtInConstIntVariables() = 0;
681    
682            /**
683             * Returns a variable name indexed map of all built-in dynamic variables,
684             * which are not simply data stores, rather each one of them executes
685             * natively to provide or alter the respective script variable data.
686             */
687            virtual std::map<String,VMDynVar*> builtInDynamicVariables() = 0;
688      };      };
689    
690      /** @brief Execution state of a virtual machine.      /** @brief Execution state of a virtual machine.
# Line 333  namespace LinuxSampler { Line 692  namespace LinuxSampler {
692       * An instance of this abstract base class represents exactly one execution       * An instance of this abstract base class represents exactly one execution
693       * state of a virtual machine. This encompasses most notably the VM       * state of a virtual machine. This encompasses most notably the VM
694       * execution stack, and VM polyphonic variables. It does not contain global       * execution stack, and VM polyphonic variables. It does not contain global
695       * variable. Global variables are contained in the VMParserContext object.       * variables. Global variables are contained in the VMParserContext object.
696       * You might see a VMExecContext object as one virtual thread of the virtual       * You might see a VMExecContext object as one virtual thread of the virtual
697       * machine.       * machine.
698       *       *
# Line 346  namespace LinuxSampler { Line 705  namespace LinuxSampler {
705      class VMExecContext {      class VMExecContext {
706      public:      public:
707          virtual ~VMExecContext() {}          virtual ~VMExecContext() {}
708    
709            /**
710             * In case the script was suspended for some reason, this method returns
711             * the amount of microseconds before the script shall continue its
712             * execution. Note that the virtual machine itself does never put its
713             * own execution thread(s) to sleep. So the respective class (i.e. sampler
714             * engine) which is using the virtual machine classes here, must take
715             * care by itself about taking time stamps, determining the script
716             * handlers that shall be put aside for the requested amount of
717             * microseconds, indicated by this method by comparing the time stamps in
718             * real-time, and to continue passing the respective handler to
719             * ScriptVM::exec() as soon as its suspension exceeded, etc. Or in other
720             * words: all classes in this directory never have an idea what time it
721             * is.
722             *
723             * You should check the return value of ScriptVM::exec() to determine
724             * whether the script was actually suspended before calling this method
725             * here.
726             *
727             * @see ScriptVM::exec()
728             */
729          virtual int suspensionTimeMicroseconds() const = 0;          virtual int suspensionTimeMicroseconds() const = 0;
730      };      };
731    
732        /** @brief Script callback for a certain event.
733         *
734         * Represents a script callback for a certain event, i.e.
735         * "on note ... end on" code block.
736         */
737      class VMEventHandler {      class VMEventHandler {
738      public:      public:
739            /**
740             * Type of this event handler, which identifies its purpose. For example
741             * for a "on note ... end on" script callback block,
742             * @c VM_EVENT_HANDLER_NOTE would be returned here.
743             */
744            virtual VMEventHandlerType_t eventHandlerType() const = 0;
745    
746            /**
747             * Name of the event handler which identifies its purpose. For example
748             * for a "on note ... end on" script callback block, the name "note"
749             * would be returned here.
750             */
751          virtual String eventHandlerName() const = 0;          virtual String eventHandlerName() const = 0;
752    
753            /**
754             * Whether or not the event handler makes any use of so called
755             * "polyphonic" variables.
756             */
757            virtual bool isPolyphonic() const = 0;
758      };      };
759    
760        /**
761         * Encapsulates a noteworty parser issue. This encompasses the type of the
762         * issue (either a parser error or parser warning), a human readable
763         * explanation text of the error or warning and the location of the
764         * encountered parser issue within the script.
765         */
766      struct ParserIssue {      struct ParserIssue {
767          String txt;          String txt; ///< Human readable explanation text of the parser issue.
768          int line;          int firstLine; ///< The first line number within the script where this issue was encountered (indexed with 1 being the very first line).
769          ParserIssueType_t type;          int lastLine; ///< The last line number within the script where this issue was encountered.
770            int firstColumn; ///< The first column within the script where this issue was encountered (indexed with 1 being the very first column).
771            int lastColumn; ///< The last column within the script where this issue was encountered.
772            ParserIssueType_t type; ///< Whether this issue is either a parser error or just a parser warning.
773    
774            /**
775             * Print this issue out to the console (stdio).
776             */
777          inline void dump() {          inline void dump() {
778              switch (type) {              switch (type) {
779                  case PARSER_ERROR:                  case PARSER_ERROR:
780                      printf("[ERROR] line %d: %s\n", line, txt.c_str());                      printf("[ERROR] line %d, column %d: %s\n", firstLine, firstColumn, txt.c_str());
781                      break;                      break;
782                  case PARSER_WARNING:                  case PARSER_WARNING:
783                      printf("[Warning] line %d: %s\n", line, txt.c_str());                      printf("[Warning] line %d, column %d: %s\n", firstLine, firstColumn, txt.c_str());
784                      break;                      break;
785              }              }
786          }          }
787            
788            /**
789             * Returns true if this issue is a parser error. In this case the parsed
790             * script may not be executed!
791             */
792          inline bool isErr() const { return type == PARSER_ERROR;   }          inline bool isErr() const { return type == PARSER_ERROR;   }
793    
794            /**
795             * Returns true if this issue is just a parser warning. A parsed script
796             * that only raises warnings may be executed if desired, however the
797             * script may not behave exactly as intended by the script author.
798             */
799          inline bool isWrn() const { return type == PARSER_WARNING; }          inline bool isWrn() const { return type == PARSER_WARNING; }
800      };      };
801    
802        /**
803         * Convenience function used for converting an ExprType_t constant to a
804         * string, i.e. for generating error message by the parser.
805         */
806      inline String typeStr(const ExprType_t& type) {      inline String typeStr(const ExprType_t& type) {
807          switch (type) {          switch (type) {
808              case EMPTY_EXPR: return "empty";              case EMPTY_EXPR: return "empty";
# Line 388  namespace LinuxSampler { Line 817  namespace LinuxSampler {
817      /** @brief Virtual machine representation of a script.      /** @brief Virtual machine representation of a script.
818       *       *
819       * An instance of this abstract base class represents a parsed script,       * An instance of this abstract base class represents a parsed script,
820       * translated into a virtual machine. You should first check if there were       * translated into a virtual machine tree. You should first check if there
821       * any parser errors. If there were any parser errors, you should refrain       * were any parser errors. If there were any parser errors, you should
822       * from executing the virtual machine. Otherwise if there were no parser       * refrain from executing the virtual machine. Otherwise if there were no
823       * errors (i.e. only warnings), then you might access one of the script's       * parser errors (i.e. only warnings), then you might access one of the
824       * event handlers by i.e. calling eventHandlerByName() and pass the       * script's event handlers by i.e. calling eventHandlerByName() and pass the
825       * respective event handler to the ScriptVM class (or to one of its       * respective event handler to the ScriptVM class (or to one of the ScriptVM
826       * descendants) for execution.       * descendants) for execution.
827       *       *
828       * @see VMExecContext       * @see VMExecContext, ScriptVM
829       */       */
830      class VMParserContext {      class VMParserContext {
831      public:      public:
832          virtual ~VMParserContext() {}          virtual ~VMParserContext() {}
833    
834            /**
835             * Returns all noteworthy issues encountered when the script was parsed.
836             * These are parser errors and parser warnings.
837             */
838          virtual std::vector<ParserIssue> issues() const = 0;          virtual std::vector<ParserIssue> issues() const = 0;
839    
840            /**
841             * Same as issues(), but this method only returns parser errors.
842             */
843          virtual std::vector<ParserIssue> errors() const = 0;          virtual std::vector<ParserIssue> errors() const = 0;
844    
845            /**
846             * Same as issues(), but this method only returns parser warnings.
847             */
848          virtual std::vector<ParserIssue> warnings() const = 0;          virtual std::vector<ParserIssue> warnings() const = 0;
849    
850            /**
851             * Returns the translated virtual machine representation of an event
852             * handler block (i.e. "on note ... end on" code block) within the
853             * parsed script. This translated representation of the event handler
854             * can be executed by the virtual machine.
855             *
856             * @param index - index of the event handler within the script
857             */
858          virtual VMEventHandler* eventHandler(uint index) = 0;          virtual VMEventHandler* eventHandler(uint index) = 0;
859    
860            /**
861             * Same as eventHandler(), but this method returns the event handler by
862             * its name. So for a "on note ... end on" code block of the parsed
863             * script you would pass "note" for argument @a name here.
864             *
865             * @param name - name of the event handler (i.e. "init", "note",
866             *               "controller", "release")
867             */
868          virtual VMEventHandler* eventHandlerByName(const String& name) = 0;          virtual VMEventHandler* eventHandlerByName(const String& name) = 0;
869      };      };
870    
871        class SourceToken;
872    
873        /** @brief Recognized token of a script's source code.
874         *
875         * Represents one recognized token of a script's source code, for example
876         * a keyword, variable name, etc. and it provides further informations about
877         * that particular token, i.e. the precise location (line and column) of the
878         * token within the original script's source code.
879         *
880         * This class is not actually used by the sampler itself. It is rather
881         * provided for external script editor applications. Primary purpose of
882         * this class is syntax highlighting for external script editors.
883         */
884        class VMSourceToken {
885        public:
886            VMSourceToken();
887            VMSourceToken(SourceToken* ct);
888            VMSourceToken(const VMSourceToken& other);
889            virtual ~VMSourceToken();
890    
891            // original text of this token as it is in the script's source code
892            String text() const;
893    
894            // position of token in script
895            int firstLine() const; ///< First line this source token is located at in script source code (indexed with 0 being the very first line).
896            int firstColumn() const; ///< Last line this source token is located at in script source code.
897    
898            // base types
899            bool isEOF() const;
900            bool isNewLine() const;
901            bool isKeyword() const;
902            bool isVariableName() const;
903            bool isIdentifier() const;
904            bool isNumberLiteral() const;
905            bool isStringLiteral() const;
906            bool isComment() const;
907            bool isPreprocessor() const;
908            bool isOther() const;
909    
910            // extended types
911            bool isIntegerVariable() const;
912            bool isStringVariable() const;
913            bool isArrayVariable() const;
914            bool isEventHandlerName() const;
915    
916            VMSourceToken& operator=(const VMSourceToken& other);
917    
918        private:
919            SourceToken* m_token;
920        };
921    
922  } // namespace LinuxSampler  } // namespace LinuxSampler
923    
924  #endif // LS_INSTR_SCRIPT_PARSER_COMMON_H  #endif // LS_INSTR_SCRIPT_PARSER_COMMON_H

Legend:
Removed from v.2619  
changed lines
  Added in v.2942

  ViewVC Help
Powered by ViewVC