/[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 2596 by schoenebeck, Thu Jun 5 19:39:12 2014 UTC revision 2888 by schoenebeck, Sun Apr 24 18:16:10 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;
95        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;
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 {
215        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;
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 {
231        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;
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;
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 Virtual machine built-in function.
308         *
309         * Abstract base class for built-in script functions, defining the interface
310         * 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
334             * not return any value (void), then it returns EMPTY_EXPR here.
335             */
336          virtual ExprType_t returnType() = 0;          virtual ExprType_t returnType() = 0;
337    
338            /**
339             * Minimum amount of function arguments this function accepts. If a
340             * script is calling this function with less arguments, the script
341             * parser will throw a parser error.
342             */
343          virtual int minRequiredArgs() const = 0;          virtual int minRequiredArgs() const = 0;
344    
345            /**
346             * Maximum amount of function arguments this functions accepts. If a
347             * script is calling this function with more arguments, the script
348             * parser will throw a parser error.
349             */
350          virtual int maxAllowedArgs() const = 0;          virtual int maxAllowedArgs() const = 0;
351    
352            /**
353             * Script data type of the function's @c iArg 'th function argument.
354             * The information provided here is less strong than acceptsArgType().
355             * The parser will compare argument data types provided in scripts by
356             * calling acceptsArgType(). The return value of argType() is used by the
357             * parser instead to show an appropriate parser error which data type
358             * this function usually expects as "default" data type. Reason: a
359             * function may accept multiple data types for a certain function
360             * argument and would automatically cast the passed argument value in
361             * that case to the type it actually needs.
362             *
363             * @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    
368            /**
369             * This function is called by the parser to check whether arguments
370             * 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
372             * 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
378             *               (must be between 0 .. maxAllowedArgs() - 1)
379             * @param type - script data type used for this function argument by
380             *               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 exec() method is
388             * 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
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             * Convenience method for function implementations to show warning
401             * messages during actual execution of the built-in function.
402             *
403             * @param txt - runtime warning text to be shown to user
404             */
405            void wrnMsg(const String& txt);
406    
407            /**
408             * Convenience method for function implementations to show error
409             * messages during actual execution of the built-in function.
410             *
411             * @param txt - runtime error text to be shown to user
412             */
413            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 137  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 169  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 202  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 211  namespace LinuxSampler { Line 553  namespace LinuxSampler {
553          VMInt8Array() : data(NULL), size(0) {}          VMInt8Array() : data(NULL), size(0) {}
554      };      };
555    
556        /** @brief Provider for built-in script functions and variables.
557         *
558         * Abstract base class defining the high-level interface for all classes
559         * which add and implement built-in script functions and built-in script
560         * variables.
561         */
562      class VMFunctionProvider {      class VMFunctionProvider {
563      public:      public:
564            /**
565             * Returns pointer to the built-in function with the given function
566             * @a name, or NULL if there is no built-in function with that function
567             * name.
568             *
569             * @param name - function name (i.e. "wait" or "message" or "exit", etc.)
570             */
571          virtual VMFunction* functionByName(const String& name) = 0;          virtual VMFunction* functionByName(const String& name) = 0;
572    
573            /**
574             * Returns a variable name indexed map of all built-in script variables
575             * which point to native "int" scalar (usually 32 bit) variables.
576             */
577          virtual std::map<String,VMIntRelPtr*> builtInIntVariables() = 0;          virtual std::map<String,VMIntRelPtr*> builtInIntVariables() = 0;
578    
579            /**
580             * Returns a variable name indexed map of all built-in script integer
581             * array variables with array element type "int8_t" (8 bit).
582             */
583          virtual std::map<String,VMInt8Array*> builtInIntArrayVariables() = 0;          virtual std::map<String,VMInt8Array*> builtInIntArrayVariables() = 0;
584    
585            /**
586             * Returns a variable name indexed map of all built-in constant script
587             * variables, which never change their value at runtime.
588             */
589          virtual std::map<String,int> builtInConstIntVariables() = 0;          virtual std::map<String,int> builtInConstIntVariables() = 0;
590      };      };
591    
# Line 223  namespace LinuxSampler { Line 593  namespace LinuxSampler {
593       *       *
594       * An instance of this abstract base class represents exactly one execution       * An instance of this abstract base class represents exactly one execution
595       * state of a virtual machine. This encompasses most notably the VM       * state of a virtual machine. This encompasses most notably the VM
596       * execution stack, and VM polyphonic variables. You might see it as one       * execution stack, and VM polyphonic variables. It does not contain global
597       * virtual thread of the virtual machine.       * variables. Global variables are contained in the VMParserContext object.
598         * You might see a VMExecContext object as one virtual thread of the virtual
599         * machine.
600         *
601         * In contrast to a VMParserContext, a VMExecContext is not tied to a
602         * ScriptVM instance. Thus you can use a VMExecContext with different
603         * ScriptVM instances, however not concurrently at the same time.
604       *       *
605       * @see VMParserContext       * @see VMParserContext
606       */       */
607      class VMExecContext {      class VMExecContext {
608      public:      public:
609          virtual ~VMExecContext() {}          virtual ~VMExecContext() {}
610    
611            /**
612             * In case the script was suspended for some reason, this method returns
613             * the amount of microseconds before the script shall continue its
614             * execution. Note that the virtual machine itself does never put its
615             * own execution thread(s) to sleep. So the respective class (i.e. sampler
616             * engine) which is using the virtual machine classes here, must take
617             * care by itself about taking time stamps, determining the script
618             * handlers that shall be put aside for the requested amount of
619             * microseconds, indicated by this method by comparing the time stamps in
620             * real-time, and to continue passing the respective handler to
621             * ScriptVM::exec() as soon as its suspension exceeded, etc. Or in other
622             * words: all classes in this directory never have an idea what time it
623             * is.
624             *
625             * You should check the return value of ScriptVM::exec() to determine
626             * whether the script was actually suspended before calling this method
627             * here.
628             *
629             * @see ScriptVM::exec()
630             */
631          virtual int suspensionTimeMicroseconds() const = 0;          virtual int suspensionTimeMicroseconds() const = 0;
632      };      };
633    
634        /** @brief Script callback for a certain event.
635         *
636         * Represents a script callback for a certain event, i.e.
637         * "on note ... end on" code block.
638         */
639      class VMEventHandler {      class VMEventHandler {
640      public:      public:
641            /**
642             * Type of this event handler, which identifies its purpose. For example
643             * for a "on note ... end on" script callback block,
644             * @c VM_EVENT_HANDLER_NOTE would be returned here.
645             */
646            virtual VMEventHandlerType_t eventHandlerType() const = 0;
647    
648            /**
649             * Name of the event handler which identifies its purpose. For example
650             * for a "on note ... end on" script callback block, the name "note"
651             * would be returned here.
652             */
653          virtual String eventHandlerName() const = 0;          virtual String eventHandlerName() const = 0;
654    
655            /**
656             * Whether or not the event handler makes any use of so called
657             * "polyphonic" variables.
658             */
659            virtual bool isPolyphonic() const = 0;
660      };      };
661    
662        /**
663         * Encapsulates a noteworty parser issue. This encompasses the type of the
664         * issue (either a parser error or parser warning), a human readable
665         * explanation text of the error or warning and the location of the
666         * encountered parser issue within the script.
667         */
668      struct ParserIssue {      struct ParserIssue {
669          String txt;          String txt; ///< Human readable explanation text of the parser issue.
670          int line;          int line; ///< Line number within the script where this issue was encountered.
671          ParserIssueType_t type;          int column; ///< Column within the script where this issue was encountered.
672            ParserIssueType_t type; ///< Whether this issue is either a parser error or just a parser warning.
673    
674            /**
675             * Print this issue out to the console (stdio).
676             */
677          inline void dump() {          inline void dump() {
678              switch (type) {              switch (type) {
679                  case PARSER_ERROR:                  case PARSER_ERROR:
680                      printf("[ERROR] line %d: %s\n", line, txt.c_str());                      printf("[ERROR] line %d, column %d: %s\n", line, column, txt.c_str());
681                      break;                      break;
682                  case PARSER_WARNING:                  case PARSER_WARNING:
683                      printf("[Warning] line %d: %s\n", line, txt.c_str());                      printf("[Warning] line %d, column %d: %s\n", line, column, txt.c_str());
684                      break;                      break;
685              }              }
686          }          }
687            
688            /**
689             * Returns true if this issue is a parser error. In this case the parsed
690             * script may not be executed!
691             */
692          inline bool isErr() const { return type == PARSER_ERROR;   }          inline bool isErr() const { return type == PARSER_ERROR;   }
693    
694            /**
695             * Returns true if this issue is just a parser warning. A parsed script
696             * that only raises warnings may be executed if desired, however the
697             * script may not behave exactly as intended by the script author.
698             */
699          inline bool isWrn() const { return type == PARSER_WARNING; }          inline bool isWrn() const { return type == PARSER_WARNING; }
700      };      };
701    
702        /**
703         * Convenience function used for converting an ExprType_t constant to a
704         * string, i.e. for generating error message by the parser.
705         */
706      inline String typeStr(const ExprType_t& type) {      inline String typeStr(const ExprType_t& type) {
707          switch (type) {          switch (type) {
708              case EMPTY_EXPR: return "empty";              case EMPTY_EXPR: return "empty";
# Line 273  namespace LinuxSampler { Line 717  namespace LinuxSampler {
717      /** @brief Virtual machine representation of a script.      /** @brief Virtual machine representation of a script.
718       *       *
719       * An instance of this abstract base class represents a parsed script,       * An instance of this abstract base class represents a parsed script,
720       * translated into a virtual machine. You should first check if there were       * translated into a virtual machine tree. You should first check if there
721       * any parser errors. If there were any parser errors, you should refrain       * were any parser errors. If there were any parser errors, you should
722       * from executing the virtual machine. Otherwise if there were no parser       * refrain from executing the virtual machine. Otherwise if there were no
723       * 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
724       * event handlers by i.e. calling eventHandlerByName() and pass the       * script's event handlers by i.e. calling eventHandlerByName() and pass the
725       * 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
726       * descendants) for execution.       * descendants) for execution.
727       *       *
728       * @see VMExecContext       * @see VMExecContext, ScriptVM
729       */       */
730      class VMParserContext {      class VMParserContext {
731      public:      public:
732          virtual ~VMParserContext() {}          virtual ~VMParserContext() {}
733    
734            /**
735             * Returns all noteworthy issues encountered when the script was parsed.
736             * These are parser errors and parser warnings.
737             */
738          virtual std::vector<ParserIssue> issues() const = 0;          virtual std::vector<ParserIssue> issues() const = 0;
739    
740            /**
741             * Same as issues(), but this method only returns parser errors.
742             */
743          virtual std::vector<ParserIssue> errors() const = 0;          virtual std::vector<ParserIssue> errors() const = 0;
744    
745            /**
746             * Same as issues(), but this method only returns parser warnings.
747             */
748          virtual std::vector<ParserIssue> warnings() const = 0;          virtual std::vector<ParserIssue> warnings() const = 0;
749    
750            /**
751             * Returns the translated virtual machine representation of an event
752             * handler block (i.e. "on note ... end on" code block) within the
753             * parsed script. This translated representation of the event handler
754             * can be executed by the virtual machine.
755             *
756             * @param index - index of the event handler within the script
757             */
758          virtual VMEventHandler* eventHandler(uint index) = 0;          virtual VMEventHandler* eventHandler(uint index) = 0;
759    
760            /**
761             * Same as eventHandler(), but this method returns the event handler by
762             * its name. So for a "on note ... end on" code block of the parsed
763             * script you would pass "note" for argument @a name here.
764             *
765             * @param name - name of the event handler (i.e. "init", "note",
766             *               "controller", "release")
767             */
768          virtual VMEventHandler* eventHandlerByName(const String& name) = 0;          virtual VMEventHandler* eventHandlerByName(const String& name) = 0;
769      };      };
770    
771        class SourceToken;
772    
773        /** @brief Recognized token of a script's source code.
774         *
775         * Represents one recognized token of a script's source code, for example
776         * a keyword, variable name, etc. and it provides further informations about
777         * that particular token, i.e. the precise location (line and column) of the
778         * token within the original script's source code.
779         *
780         * This class is not actually used by the sampler itself. It is rather
781         * provided for external script editor applications. Primary purpose of
782         * this class is syntax highlighting for external script editors.
783         */
784        class VMSourceToken {
785        public:
786            VMSourceToken();
787            VMSourceToken(SourceToken* ct);
788            VMSourceToken(const VMSourceToken& other);
789            virtual ~VMSourceToken();
790    
791            // original text of this token as it is in the script's source code
792            String text() const;
793    
794            // position of token in script
795            int firstLine() const;
796            int firstColumn() const;
797    
798            // base types
799            bool isEOF() const;
800            bool isNewLine() const;
801            bool isKeyword() const;
802            bool isVariableName() const;
803            bool isIdentifier() const;
804            bool isNumberLiteral() const;
805            bool isStringLiteral() const;
806            bool isComment() const;
807            bool isPreprocessor() const;
808            bool isOther() const;
809    
810            // extended types
811            bool isIntegerVariable() const;
812            bool isStringVariable() const;
813            bool isArrayVariable() const;
814            bool isEventHandlerName() const;
815    
816            VMSourceToken& operator=(const VMSourceToken& other);
817    
818        private:
819            SourceToken* m_token;
820        };
821    
822  } // namespace LinuxSampler  } // namespace LinuxSampler
823    
824  #endif // LS_INSTR_SCRIPT_PARSER_COMMON_H  #endif // LS_INSTR_SCRIPT_PARSER_COMMON_H

Legend:
Removed from v.2596  
changed lines
  Added in v.2888

  ViewVC Help
Powered by ViewVC