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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2960 - (hide annotations) (download) (as text)
Sun Jul 17 12:10:06 2016 UTC (7 years, 8 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 44251 byte(s)
- Just some minor API doc comment update.

1 schoenebeck 2581 /*
2 schoenebeck 2871 * Copyright (c) 2014-2016 Christian Schoenebeck
3 schoenebeck 2581 *
4     * http://www.linuxsampler.org
5     *
6     * This file is part of LinuxSampler and released under the same terms.
7     * See README file for details.
8     */
9    
10     // This header defines data types shared between the VM core implementation
11     // (inside the current source directory) and other parts of the sampler
12     // (located at other source directories).
13    
14     #ifndef LS_INSTR_SCRIPT_PARSER_COMMON_H
15     #define LS_INSTR_SCRIPT_PARSER_COMMON_H
16    
17     #include "../common/global.h"
18 schoenebeck 2588 #include <vector>
19 schoenebeck 2594 #include <map>
20     #include <stddef.h> // offsetof()
21 schoenebeck 2581
22     namespace LinuxSampler {
23 schoenebeck 2727
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 schoenebeck 2581 enum ParserIssueType_t {
29 schoenebeck 2727 PARSER_ERROR, ///< Script parser encountered an error, the script cannot be executed.
30     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 schoenebeck 2581 };
32    
33 schoenebeck 2727 /** @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 schoenebeck 2581 enum ExprType_t {
41 schoenebeck 2727 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, ///< integer (scalar) expression
43     INT_ARR_EXPR, ///< integer array expression
44     STRING_EXPR, ///< string expression
45     STRING_ARR_EXPR, ///< string array expression
46 schoenebeck 2581 };
47    
48 schoenebeck 2727 /** @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 schoenebeck 2581 enum StmtFlags_t {
59     STMT_SUCCESS = 0, ///< Function / statement was executed successfully, no error occurred.
60 schoenebeck 2727 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), ///< 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), ///< VM stopped execution due to some script runtime error that occurred
63 schoenebeck 2581 };
64    
65 schoenebeck 2727 /** @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 schoenebeck 2581 enum VMExecStatus_t {
73 schoenebeck 2727 VM_EXEC_NOT_RUNNING = 0, ///< Script is currently not executed by the VM.
74     VM_EXEC_RUNNING = 1, ///< The VM is currently executing the script.
75     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), ///< A runtime error occurred while executing the script (i.e. a call to some built-in script function failed).
77 schoenebeck 2581 };
78    
79 schoenebeck 2879 /** @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 schoenebeck 2727 // just symbol prototyping
92 schoenebeck 2596 class VMIntExpr;
93     class VMStringExpr;
94 schoenebeck 2619 class VMIntArrayExpr;
95     class VMStringArrayExpr;
96 schoenebeck 2596
97 schoenebeck 2727 /** @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 schoenebeck 2581 class VMExpr {
111     public:
112 schoenebeck 2727 /**
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 schoenebeck 2581 virtual ExprType_t exprType() const = 0;
118 schoenebeck 2727
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 schoenebeck 2596 VMIntExpr* asInt() const;
133 schoenebeck 2727
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 schoenebeck 2596 VMStringExpr* asString() const;
148 schoenebeck 2727
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 schoenebeck 2619 VMIntArrayExpr* asIntArray() const;
163 schoenebeck 2945
164     /**
165     * Returns true in case this expression can be considered to be a
166     * constant expression. A constant expression will retain the same
167     * value throughout the entire life time of a script and the
168     * expression's constant value may be evaluated already at script
169     * parse time, which may result in performance benefits during script
170     * runtime.
171 schoenebeck 2960 *
172     * @b NOTE: A constant expression is per se always also non modifyable.
173     * But a non modifyable expression may not necessarily be a constant
174     * expression!
175     *
176     * @see isModifyable()
177 schoenebeck 2945 */
178     virtual bool isConstExpr() const = 0;
179    
180 schoenebeck 2960 /**
181     * Returns true in case this expression is allowed to be modified.
182     * If this method returns @c false then this expression must be handled
183     * as read-only expression, which means that assigning a new value to it
184     * is either not possible or not allowed.
185     *
186     * @b NOTE: A constant expression is per se always also non modifyable.
187     * But a non modifyable expression may not necessarily be a constant
188     * expression!
189     *
190     * @see isConstExpr()
191     */
192 schoenebeck 2945 bool isModifyable() const;
193 schoenebeck 2581 };
194    
195 schoenebeck 2727 /** @brief Virtual machine integer expression
196     *
197     * This is the abstract base class for all expressions inside scripts which
198     * evaluate to an integer (scalar) value. Deriving classes implement the
199     * abstract method evalInt() to return the actual integer result value of
200     * the expression.
201     */
202 schoenebeck 2581 class VMIntExpr : virtual public VMExpr {
203     public:
204 schoenebeck 2727 /**
205     * Returns the result of this expression as integer (scalar) value.
206     * This abstract method must be implemented by deriving classes.
207     */
208 schoenebeck 2581 virtual int evalInt() = 0;
209 schoenebeck 2727
210     /**
211     * Returns always INT_EXPR for instances of this class.
212     */
213     ExprType_t exprType() const OVERRIDE { return INT_EXPR; }
214 schoenebeck 2581 };
215    
216 schoenebeck 2727 /** @brief Virtual machine string expression
217     *
218     * This is the abstract base class for all expressions inside scripts which
219     * evaluate to a string value. Deriving classes implement the abstract
220     * method evalStr() to return the actual string result value of the
221     * expression.
222     */
223 schoenebeck 2581 class VMStringExpr : virtual public VMExpr {
224     public:
225 schoenebeck 2727 /**
226     * Returns the result of this expression as string value. This abstract
227     * method must be implemented by deriving classes.
228     */
229 schoenebeck 2581 virtual String evalStr() = 0;
230 schoenebeck 2727
231     /**
232     * Returns always STRING_EXPR for instances of this class.
233     */
234     ExprType_t exprType() const OVERRIDE { return STRING_EXPR; }
235 schoenebeck 2581 };
236    
237 schoenebeck 2727 /** @brief Virtual Machine Array Value Expression
238     *
239     * This is the abstract base class for all expressions inside scripts which
240     * evaluate to some kind of array value. Deriving classes implement the
241     * abstract method arraySize() to return the amount of elements within the
242     * array.
243     */
244 schoenebeck 2619 class VMArrayExpr : virtual public VMExpr {
245     public:
246 schoenebeck 2727 /**
247     * Returns amount of elements in this array. This abstract method must
248     * be implemented by deriving classes.
249     */
250 schoenebeck 2619 virtual int arraySize() const = 0;
251     };
252    
253 schoenebeck 2727 /** @brief Virtual Machine Integer Array Expression
254     *
255     * This is the abstract base class for all expressions inside scripts which
256     * evaluate to an array of integer values. Deriving classes implement the
257     * abstract methods arraySize(), evalIntElement() and assignIntElement() to
258     * access the individual integer array values.
259     */
260 schoenebeck 2619 class VMIntArrayExpr : virtual public VMArrayExpr {
261     public:
262 schoenebeck 2727 /**
263     * Returns the (scalar) integer value of the array element given by
264     * element index @a i.
265     *
266     * @param i - array element index (must be between 0 .. arraySize() - 1)
267     */
268 schoenebeck 2619 virtual int evalIntElement(uint i) = 0;
269 schoenebeck 2727
270     /**
271     * Changes the current value of an element (given by array element
272     * index @a i) of this integer array.
273     *
274     * @param i - array element index (must be between 0 .. arraySize() - 1)
275     * @param value - new integer scalar value to be assigned to that array element
276     */
277 schoenebeck 2619 virtual void assignIntElement(uint i, int value) = 0;
278 schoenebeck 2727
279     /**
280     * Returns always INT_ARR_EXPR for instances of this class.
281     */
282     ExprType_t exprType() const OVERRIDE { return INT_ARR_EXPR; }
283 schoenebeck 2619 };
284    
285 schoenebeck 2727 /** @brief Arguments (parameters) for being passed to a built-in script function.
286     *
287     * An argument or a set of arguments passed to a script function are
288     * translated by the parser to an instance of this class. This abstract
289     * interface class is used by implementations of built-in functions to
290     * obtain the individual function argument values being passed to them at
291     * runtime.
292     */
293 schoenebeck 2581 class VMFnArgs {
294     public:
295 schoenebeck 2727 /**
296     * Returns the amount of arguments going to be passed to the script
297     * function.
298     */
299 schoenebeck 2581 virtual int argsCount() const = 0;
300 schoenebeck 2727
301     /**
302     * Returns the respective argument (requested by argument index @a i) of
303     * this set of arguments. This method is called by implementations of
304     * built-in script functions to obtain the value of each function
305     * argument passed to the function at runtime.
306     *
307     * @param i - function argument index (indexed from left to right)
308     */
309 schoenebeck 2581 virtual VMExpr* arg(int i) = 0;
310     };
311    
312 schoenebeck 2727 /** @brief Result value returned from a call to a built-in script function.
313     *
314     * Implementations of built-in script functions return an instance of this
315     * object to let the virtual machine obtain the result value of the function
316     * call, which might then be further processed by the virtual machine
317     * according to the script. It also provides informations about the success
318     * or failure of the function call.
319     */
320 schoenebeck 2581 class VMFnResult {
321     public:
322 schoenebeck 2727 /**
323     * Returns the result value of the function call, represented by a high
324     * level expression object.
325     */
326 schoenebeck 2581 virtual VMExpr* resultValue() = 0;
327 schoenebeck 2727
328     /**
329     * Provides detailed informations of the success / failure of the
330     * function call. The virtual machine is evaluating the flags returned
331     * here to decide whether it must abort or suspend execution of the
332     * script at this point.
333     */
334 schoenebeck 2581 virtual StmtFlags_t resultFlags() { return STMT_SUCCESS; }
335     };
336    
337 schoenebeck 2727 /** @brief Virtual machine built-in function.
338 schoenebeck 2612 *
339     * Abstract base class for built-in script functions, defining the interface
340 schoenebeck 2727 * for all built-in script function implementations. All built-in script
341     * functions are deriving from this abstract interface class in order to
342     * provide their functionality to the virtual machine with this unified
343     * interface.
344     *
345     * The methods of this interface class provide two purposes:
346     *
347     * 1. When a script is loaded, the script parser uses the methods of this
348     * interface to check whether the script author was calling the
349     * respective built-in script function in a correct way. For example
350     * the parser checks whether the required amount of parameters were
351     * passed to the function and whether the data types passed match the
352     * data types expected by the function. If not, loading the script will
353     * be aborted with a parser error, describing to the user (i.e. script
354     * author) the precise misusage of the respective function.
355     * 2. After the script was loaded successfully and the script is executed,
356     * the virtual machine calls the exec() method of the respective built-in
357     * function to provide the actual functionality of the built-in function
358     * call.
359 schoenebeck 2612 */
360 schoenebeck 2581 class VMFunction {
361     public:
362 schoenebeck 2612 /**
363     * Script data type of the function's return value. If the function does
364 schoenebeck 2727 * not return any value (void), then it returns EMPTY_EXPR here.
365 schoenebeck 2612 */
366 schoenebeck 2581 virtual ExprType_t returnType() = 0;
367 schoenebeck 2612
368     /**
369     * Minimum amount of function arguments this function accepts. If a
370     * script is calling this function with less arguments, the script
371     * parser will throw a parser error.
372     */
373 schoenebeck 2581 virtual int minRequiredArgs() const = 0;
374 schoenebeck 2612
375     /**
376     * Maximum amount of function arguments this functions accepts. If a
377     * script is calling this function with more arguments, the script
378     * parser will throw a parser error.
379     */
380 schoenebeck 2581 virtual int maxAllowedArgs() const = 0;
381 schoenebeck 2612
382     /**
383     * Script data type of the function's @c iArg 'th function argument.
384     * The information provided here is less strong than acceptsArgType().
385     * The parser will compare argument data types provided in scripts by
386 schoenebeck 2871 * calling acceptsArgType(). The return value of argType() is used by the
387 schoenebeck 2612 * parser instead to show an appropriate parser error which data type
388     * this function usually expects as "default" data type. Reason: a
389     * function may accept multiple data types for a certain function
390     * argument and would automatically cast the passed argument value in
391     * that case to the type it actually needs.
392     *
393     * @param iArg - index of the function argument in question
394 schoenebeck 2727 * (must be between 0 .. maxAllowedArgs() - 1)
395 schoenebeck 2612 */
396 schoenebeck 2581 virtual ExprType_t argType(int iArg) const = 0;
397 schoenebeck 2612
398     /**
399 schoenebeck 2945 * This method is called by the parser to check whether arguments
400 schoenebeck 2612 * passed in scripts to this function are accepted by this function. If
401     * a script calls this function with an argument's data type not
402 schoenebeck 2727 * accepted by this function, the parser will throw a parser error. On
403     * such errors the data type returned by argType() will be used to
404     * assemble an appropriate error message regarding the precise misusage
405     * of the built-in function.
406 schoenebeck 2612 *
407     * @param iArg - index of the function argument in question
408 schoenebeck 2727 * (must be between 0 .. maxAllowedArgs() - 1)
409 schoenebeck 2612 * @param type - script data type used for this function argument by
410     * currently parsed script
411 schoenebeck 2727 * @return true if the given data type would be accepted for the
412     * respective function argument by the function
413 schoenebeck 2612 */
414 schoenebeck 2581 virtual bool acceptsArgType(int iArg, ExprType_t type) const = 0;
415 schoenebeck 2612
416     /**
417 schoenebeck 2945 * This method is called by the parser to check whether some arguments
418     * (and if yes which ones) passed to this script function will be
419     * modified by this script function. Most script functions simply use
420     * their arguments as inputs, that is they only read the argument's
421     * values. However some script function may also use passed
422     * argument(s) as output variables. In this case the function
423     * implementation must return @c true for the respective argument
424     * index here.
425     *
426     * @param iArg - index of the function argument in question
427     * (must be between 0 .. maxAllowedArgs() - 1)
428     */
429     virtual bool modifiesArg(int iArg) const = 0;
430    
431     /**
432 schoenebeck 2727 * Implements the actual function execution. This exec() method is
433     * called by the VM whenever this function implementation shall be
434     * executed at script runtime. This method blocks until the function
435     * call completed.
436 schoenebeck 2612 *
437     * @param args - function arguments for executing this built-in function
438 schoenebeck 2727 * @returns function's return value (if any) and general status
439     * informations (i.e. whether the function call caused a
440     * runtime error)
441 schoenebeck 2612 */
442 schoenebeck 2581 virtual VMFnResult* exec(VMFnArgs* args) = 0;
443 schoenebeck 2612
444     /**
445 schoenebeck 2727 * Convenience method for function implementations to show warning
446     * messages during actual execution of the built-in function.
447 schoenebeck 2612 *
448 schoenebeck 2727 * @param txt - runtime warning text to be shown to user
449 schoenebeck 2612 */
450 schoenebeck 2598 void wrnMsg(const String& txt);
451 schoenebeck 2612
452     /**
453 schoenebeck 2727 * Convenience method for function implementations to show error
454     * messages during actual execution of the built-in function.
455 schoenebeck 2612 *
456 schoenebeck 2727 * @param txt - runtime error text to be shown to user
457 schoenebeck 2612 */
458 schoenebeck 2598 void errMsg(const String& txt);
459 schoenebeck 2581 };
460    
461 schoenebeck 2727 /** @brief Virtual machine relative pointer.
462     *
463 schoenebeck 2594 * POD base of VMIntRelPtr and VMInt8RelPtr structures. Not intended to be
464     * used directly. Use VMIntRelPtr or VMInt8RelPtr instead.
465 schoenebeck 2727 *
466     * @see VMIntRelPtr, VMInt8RelPtr
467 schoenebeck 2594 */
468     struct VMRelPtr {
469     void** base; ///< Base pointer.
470 schoenebeck 2727 int offset; ///< Offset (in bytes) relative to base pointer.
471 schoenebeck 2948 bool readonly; ///< Whether the pointed data may be modified or just be read.
472 schoenebeck 2594 };
473    
474     /** @brief Pointer to built-in VM integer variable (of C/C++ type int).
475     *
476 schoenebeck 2727 * Used for defining built-in 32 bit integer script variables.
477 schoenebeck 2594 *
478     * @b CAUTION: You may only use this class for pointing to C/C++ variables
479     * of type "int" (which on most systems is 32 bit in size). If the C/C++ int
480     * variable you want to reference is only 8 bit in size, then you @b must
481     * use VMInt8RelPtr instead!
482     *
483     * For efficiency reasons the actual native C/C++ int variable is referenced
484     * by two components here. The actual native int C/C++ variable in memory
485     * is dereferenced at VM run-time by taking the @c base pointer dereference
486     * and adding @c offset bytes. This has the advantage that for a large
487     * number of built-in int variables, only one (or few) base pointer need
488     * to be re-assigned before running a script, instead of updating each
489     * built-in variable each time before a script is executed.
490     *
491     * Refer to DECLARE_VMINT() for example code.
492     *
493     * @see VMInt8RelPtr, DECLARE_VMINT()
494     */
495     struct VMIntRelPtr : VMRelPtr {
496     VMIntRelPtr() {
497     base = NULL;
498     offset = 0;
499 schoenebeck 2948 readonly = false;
500 schoenebeck 2594 }
501     VMIntRelPtr(const VMRelPtr& data) {
502     base = data.base;
503     offset = data.offset;
504 schoenebeck 2948 readonly = false;
505 schoenebeck 2594 }
506     virtual int evalInt() { return *(int*)&(*(uint8_t**)base)[offset]; }
507     virtual void assign(int i) { *(int*)&(*(uint8_t**)base)[offset] = i; }
508     };
509    
510     /** @brief Pointer to built-in VM integer variable (of C/C++ type int8_t).
511     *
512 schoenebeck 2727 * Used for defining built-in 8 bit integer script variables.
513 schoenebeck 2594 *
514     * @b CAUTION: You may only use this class for pointing to C/C++ variables
515     * of type "int8_t" (8 bit integer). If the C/C++ int variable you want to
516     * reference is an "int" type (which is 32 bit on most systems), then you
517     * @b must use VMIntRelPtr instead!
518     *
519     * For efficiency reasons the actual native C/C++ int variable is referenced
520     * by two components here. The actual native int C/C++ variable in memory
521     * is dereferenced at VM run-time by taking the @c base pointer dereference
522     * and adding @c offset bytes. This has the advantage that for a large
523     * number of built-in int variables, only one (or few) base pointer need
524     * to be re-assigned before running a script, instead of updating each
525     * built-in variable each time before a script is executed.
526     *
527     * Refer to DECLARE_VMINT() for example code.
528     *
529     * @see VMIntRelPtr, DECLARE_VMINT()
530     */
531     struct VMInt8RelPtr : VMIntRelPtr {
532     VMInt8RelPtr() : VMIntRelPtr() {}
533     VMInt8RelPtr(const VMRelPtr& data) : VMIntRelPtr(data) {}
534     virtual int evalInt() OVERRIDE {
535     return *(uint8_t*)&(*(uint8_t**)base)[offset];
536     }
537     virtual void assign(int i) OVERRIDE {
538     *(uint8_t*)&(*(uint8_t**)base)[offset] = i;
539     }
540     };
541    
542     /**
543     * Convenience macro for initializing VMIntRelPtr and VMInt8RelPtr
544 schoenebeck 2727 * structures. Usage example:
545 schoenebeck 2594 * @code
546     * struct Foo {
547 schoenebeck 2727 * uint8_t a; // native representation of a built-in integer script variable
548     * int b; // native representation of another built-in integer script variable
549     * int c; // native representation of another built-in integer script variable
550     * uint8_t d; // native representation of another built-in integer script variable
551 schoenebeck 2594 * };
552     *
553 schoenebeck 2727 * // initializing the built-in script variables to some values
554     * Foo foo1 = (Foo) { 1, 2000, 3000, 4 };
555     * Foo foo2 = (Foo) { 5, 6000, 7000, 8 };
556 schoenebeck 2594 *
557     * Foo* pFoo;
558     *
559 schoenebeck 2727 * VMInt8RelPtr varA = DECLARE_VMINT(pFoo, class Foo, a);
560     * VMIntRelPtr varB = DECLARE_VMINT(pFoo, class Foo, b);
561     * VMIntRelPtr varC = DECLARE_VMINT(pFoo, class Foo, c);
562     * VMInt8RelPtr varD = DECLARE_VMINT(pFoo, class Foo, d);
563 schoenebeck 2594 *
564     * pFoo = &foo1;
565 schoenebeck 2727 * printf("%d\n", varA->evalInt()); // will print 1
566     * printf("%d\n", varB->evalInt()); // will print 2000
567     * printf("%d\n", varC->evalInt()); // will print 3000
568     * printf("%d\n", varD->evalInt()); // will print 4
569 schoenebeck 2594 *
570 schoenebeck 2727 * // same printf() code, just with pFoo pointer being changed ...
571     *
572 schoenebeck 2594 * pFoo = &foo2;
573 schoenebeck 2727 * printf("%d\n", varA->evalInt()); // will print 5
574     * printf("%d\n", varB->evalInt()); // will print 6000
575     * printf("%d\n", varC->evalInt()); // will print 7000
576     * printf("%d\n", varD->evalInt()); // will print 8
577 schoenebeck 2594 * @endcode
578 schoenebeck 2727 * As you can see above, by simply changing one single pointer, you can
579     * remap a huge bunch of built-in integer script variables to completely
580     * different native values/native variables. Which especially reduces code
581     * complexity inside the sampler engines which provide the actual script
582     * functionalities.
583 schoenebeck 2594 */
584     #define DECLARE_VMINT(basePtr, T_struct, T_member) ( \
585     (VMRelPtr) { \
586     (void**) &basePtr, \
587 schoenebeck 2948 offsetof(T_struct, T_member), \
588     false \
589 schoenebeck 2594 } \
590     ) \
591    
592 schoenebeck 2948 /**
593     * Same as DECLARE_VMINT(), but this one defines the VMIntRelPtr and
594     * VMInt8RelPtr structures to be of read-only type. That means the script
595     * parser will abort any script at parser time if the script is trying to
596     * modify such a read-only built-in variable.
597     *
598     * @b NOTE: this is only intended for built-in read-only variables that
599     * may change during runtime! If your built-in variable's data is rather
600     * already available at parser time and won't change during runtime, then
601     * you should rather register a built-in constant in your VM class instead!
602     *
603     * @see ScriptVM::builtInConstIntVariables()
604     */
605     #define DECLARE_VMINT_READONLY(basePtr, T_struct, T_member) ( \
606     (VMRelPtr) { \
607     (void**) &basePtr, \
608     offsetof(T_struct, T_member), \
609     true \
610     } \
611     ) \
612    
613 schoenebeck 2594 /** @brief Built-in VM 8 bit integer array variable.
614     *
615 schoenebeck 2727 * Used for defining built-in integer array script variables (8 bit per
616     * array element). Currently there is no support for any other kind of array
617     * type. So all integer arrays of scripts use 8 bit data types.
618 schoenebeck 2594 */
619     struct VMInt8Array {
620     int8_t* data;
621     int size;
622    
623     VMInt8Array() : data(NULL), size(0) {}
624     };
625    
626 schoenebeck 2945 /** @brief Virtual machine script variable.
627     *
628     * Common interface for all variables accessed in scripts.
629     */
630     class VMVariable : virtual public VMExpr {
631     public:
632     /**
633     * Whether a script may modify the content of this variable by
634     * assigning a new value to it.
635     *
636     * @see isConstExpr(), assign()
637     */
638     virtual bool isAssignable() const = 0;
639    
640     /**
641     * In case this variable is assignable, this method will be called to
642     * perform the value assignment to this variable with @a expr
643     * reflecting the new value to be assigned.
644     *
645     * @param expr - new value to be assigned to this variable
646     */
647     virtual void assignExpr(VMExpr* expr) = 0;
648     };
649    
650 schoenebeck 2942 /** @brief Dynamically executed variable (abstract base class).
651     *
652     * Interface for the implementation of a dynamically generated content of
653     * a built-in script variable. Most built-in variables are simply pointers
654     * to some native location in memory. So when a script reads them, the
655     * memory location is simply read to get the value of the variable. A
656     * dynamic variable however is not simply a memory location. For each access
657     * to a dynamic variable some native code is executed to actually generate
658     * and provide the content (value) of this type of variable.
659     */
660 schoenebeck 2945 class VMDynVar : public VMVariable {
661 schoenebeck 2942 public:
662     /**
663     * Returns true in case this dynamic variable can be considered to be a
664     * constant expression. A constant expression will retain the same value
665     * throughout the entire life time of a script and the expression's
666     * constant value may be evaluated already at script parse time, which
667     * may result in performance benefits during script runtime.
668     *
669     * However due to the "dynamic" behavior of dynamic variables, almost
670     * all dynamic variables are probably not constant expressions. That's
671     * why this method returns @c false by default. If you are really sure
672     * that your dynamic variable implementation can be considered a
673     * constant expression then you may override this method and return
674     * @c true instead. Note that when you return @c true here, your
675     * dynamic variable will really just be executed once; and exectly
676     * already when the script is loaded!
677     *
678     * As an example you may implement a "constant" built-in dynamic
679     * variable that checks for a certain operating system feature and
680     * returns the result of that OS feature check as content (value) of
681     * this dynamic variable. Since the respective OS feature might become
682     * available/unavailable after OS updates, software migration, etc. the
683     * OS feature check should at least be performed once each time the
684     * application is launched. And since the OS feature check might take a
685     * certain amount of execution time, it might make sense to only
686     * perform the check if the respective variable name is actually
687     * referenced at all in the script to be loaded. Note that the dynamic
688     * variable will still be evaluated again though if the script is
689     * loaded again. So it is up to you to probably cache the result in the
690     * implementation of your dynamic variable.
691     *
692     * On doubt, please rather consider to use a constant built-in script
693     * variable instead of implementing a "constant" dynamic variable, due
694     * to the runtime overhead a dynamic variable may cause.
695     *
696     * @see isAssignable()
697     */
698 schoenebeck 2945 bool isConstExpr() const OVERRIDE { return false; }
699 schoenebeck 2942
700     /**
701     * In case this dynamic variable is assignable, the new value (content)
702     * to be assigned to this dynamic variable.
703     *
704     * By default this method does nothing. Override and implement this
705     * method in your subclass in case your dynamic variable allows to
706     * assign a new value by script.
707     *
708     * @param expr - new value to be assigned to this variable
709     */
710 schoenebeck 2945 void assignExpr(VMExpr* expr) OVERRIDE {}
711 schoenebeck 2942 };
712    
713     /** @brief Dynamically executed variable (of integer data type).
714     *
715     * This is the base class for all built-in integer script variables whose
716     * variable content needs to be provided dynamically by executable native
717     * code on each script variable access.
718     */
719     class VMDynIntVar : virtual public VMDynVar, virtual public VMIntExpr {
720     public:
721     };
722    
723     /** @brief Dynamically executed variable (of string data type).
724     *
725     * This is the base class for all built-in string script variables whose
726     * variable content needs to be provided dynamically by executable native
727     * code on each script variable access.
728     */
729     class VMDynStringVar : virtual public VMDynVar, virtual public VMStringExpr {
730     public:
731     };
732    
733 schoenebeck 2612 /** @brief Provider for built-in script functions and variables.
734     *
735 schoenebeck 2727 * Abstract base class defining the high-level interface for all classes
736     * which add and implement built-in script functions and built-in script
737     * variables.
738 schoenebeck 2612 */
739 schoenebeck 2581 class VMFunctionProvider {
740     public:
741 schoenebeck 2612 /**
742     * Returns pointer to the built-in function with the given function
743 schoenebeck 2727 * @a name, or NULL if there is no built-in function with that function
744     * name.
745 schoenebeck 2612 *
746 schoenebeck 2727 * @param name - function name (i.e. "wait" or "message" or "exit", etc.)
747 schoenebeck 2612 */
748 schoenebeck 2581 virtual VMFunction* functionByName(const String& name) = 0;
749 schoenebeck 2612
750     /**
751     * Returns a variable name indexed map of all built-in script variables
752 schoenebeck 2727 * which point to native "int" scalar (usually 32 bit) variables.
753 schoenebeck 2612 */
754 schoenebeck 2594 virtual std::map<String,VMIntRelPtr*> builtInIntVariables() = 0;
755 schoenebeck 2612
756     /**
757 schoenebeck 2727 * Returns a variable name indexed map of all built-in script integer
758     * array variables with array element type "int8_t" (8 bit).
759 schoenebeck 2612 */
760 schoenebeck 2594 virtual std::map<String,VMInt8Array*> builtInIntArrayVariables() = 0;
761 schoenebeck 2612
762     /**
763     * Returns a variable name indexed map of all built-in constant script
764     * variables, which never change their value at runtime.
765     */
766 schoenebeck 2594 virtual std::map<String,int> builtInConstIntVariables() = 0;
767 schoenebeck 2942
768     /**
769     * Returns a variable name indexed map of all built-in dynamic variables,
770     * which are not simply data stores, rather each one of them executes
771     * natively to provide or alter the respective script variable data.
772     */
773     virtual std::map<String,VMDynVar*> builtInDynamicVariables() = 0;
774 schoenebeck 2581 };
775    
776 schoenebeck 2594 /** @brief Execution state of a virtual machine.
777     *
778     * An instance of this abstract base class represents exactly one execution
779     * state of a virtual machine. This encompasses most notably the VM
780 schoenebeck 2612 * execution stack, and VM polyphonic variables. It does not contain global
781 schoenebeck 2727 * variables. Global variables are contained in the VMParserContext object.
782 schoenebeck 2612 * You might see a VMExecContext object as one virtual thread of the virtual
783     * machine.
784 schoenebeck 2594 *
785 schoenebeck 2612 * In contrast to a VMParserContext, a VMExecContext is not tied to a
786     * ScriptVM instance. Thus you can use a VMExecContext with different
787     * ScriptVM instances, however not concurrently at the same time.
788     *
789 schoenebeck 2594 * @see VMParserContext
790     */
791 schoenebeck 2581 class VMExecContext {
792     public:
793     virtual ~VMExecContext() {}
794 schoenebeck 2727
795     /**
796     * In case the script was suspended for some reason, this method returns
797     * the amount of microseconds before the script shall continue its
798     * execution. Note that the virtual machine itself does never put its
799     * own execution thread(s) to sleep. So the respective class (i.e. sampler
800     * engine) which is using the virtual machine classes here, must take
801     * care by itself about taking time stamps, determining the script
802     * handlers that shall be put aside for the requested amount of
803 schoenebeck 2871 * microseconds, indicated by this method by comparing the time stamps in
804 schoenebeck 2727 * real-time, and to continue passing the respective handler to
805     * ScriptVM::exec() as soon as its suspension exceeded, etc. Or in other
806     * words: all classes in this directory never have an idea what time it
807     * is.
808     *
809     * You should check the return value of ScriptVM::exec() to determine
810     * whether the script was actually suspended before calling this method
811     * here.
812     *
813     * @see ScriptVM::exec()
814     */
815 schoenebeck 2581 virtual int suspensionTimeMicroseconds() const = 0;
816     };
817    
818 schoenebeck 2645 /** @brief Script callback for a certain event.
819     *
820     * Represents a script callback for a certain event, i.e.
821 schoenebeck 2727 * "on note ... end on" code block.
822 schoenebeck 2645 */
823 schoenebeck 2581 class VMEventHandler {
824     public:
825 schoenebeck 2645 /**
826 schoenebeck 2879 * Type of this event handler, which identifies its purpose. For example
827     * for a "on note ... end on" script callback block,
828     * @c VM_EVENT_HANDLER_NOTE would be returned here.
829     */
830     virtual VMEventHandlerType_t eventHandlerType() const = 0;
831    
832     /**
833 schoenebeck 2645 * Name of the event handler which identifies its purpose. For example
834     * for a "on note ... end on" script callback block, the name "note"
835     * would be returned here.
836     */
837 schoenebeck 2581 virtual String eventHandlerName() const = 0;
838 schoenebeck 2645
839     /**
840     * Whether or not the event handler makes any use of so called
841     * "polyphonic" variables.
842     */
843     virtual bool isPolyphonic() const = 0;
844 schoenebeck 2581 };
845    
846 schoenebeck 2727 /**
847     * Encapsulates a noteworty parser issue. This encompasses the type of the
848     * issue (either a parser error or parser warning), a human readable
849     * explanation text of the error or warning and the location of the
850     * encountered parser issue within the script.
851     */
852 schoenebeck 2581 struct ParserIssue {
853 schoenebeck 2727 String txt; ///< Human readable explanation text of the parser issue.
854 schoenebeck 2889 int firstLine; ///< The first line number within the script where this issue was encountered (indexed with 1 being the very first line).
855     int lastLine; ///< The last line number within the script where this issue was encountered.
856     int firstColumn; ///< The first column within the script where this issue was encountered (indexed with 1 being the very first column).
857     int lastColumn; ///< The last column within the script where this issue was encountered.
858 schoenebeck 2727 ParserIssueType_t type; ///< Whether this issue is either a parser error or just a parser warning.
859 schoenebeck 2581
860 schoenebeck 2727 /**
861     * Print this issue out to the console (stdio).
862     */
863 schoenebeck 2581 inline void dump() {
864     switch (type) {
865     case PARSER_ERROR:
866 schoenebeck 2889 printf("[ERROR] line %d, column %d: %s\n", firstLine, firstColumn, txt.c_str());
867 schoenebeck 2581 break;
868     case PARSER_WARNING:
869 schoenebeck 2889 printf("[Warning] line %d, column %d: %s\n", firstLine, firstColumn, txt.c_str());
870 schoenebeck 2581 break;
871     }
872     }
873 schoenebeck 2727
874     /**
875     * Returns true if this issue is a parser error. In this case the parsed
876     * script may not be executed!
877     */
878 schoenebeck 2581 inline bool isErr() const { return type == PARSER_ERROR; }
879 schoenebeck 2727
880     /**
881     * Returns true if this issue is just a parser warning. A parsed script
882     * that only raises warnings may be executed if desired, however the
883     * script may not behave exactly as intended by the script author.
884     */
885 schoenebeck 2581 inline bool isWrn() const { return type == PARSER_WARNING; }
886     };
887    
888 schoenebeck 2727 /**
889     * Convenience function used for converting an ExprType_t constant to a
890     * string, i.e. for generating error message by the parser.
891     */
892 schoenebeck 2581 inline String typeStr(const ExprType_t& type) {
893     switch (type) {
894     case EMPTY_EXPR: return "empty";
895     case INT_EXPR: return "integer";
896     case INT_ARR_EXPR: return "integer array";
897     case STRING_EXPR: return "string";
898     case STRING_ARR_EXPR: return "string array";
899     }
900     return "invalid";
901     }
902    
903 schoenebeck 2594 /** @brief Virtual machine representation of a script.
904     *
905     * An instance of this abstract base class represents a parsed script,
906 schoenebeck 2727 * translated into a virtual machine tree. You should first check if there
907     * were any parser errors. If there were any parser errors, you should
908     * refrain from executing the virtual machine. Otherwise if there were no
909     * parser errors (i.e. only warnings), then you might access one of the
910     * script's event handlers by i.e. calling eventHandlerByName() and pass the
911     * respective event handler to the ScriptVM class (or to one of the ScriptVM
912 schoenebeck 2594 * descendants) for execution.
913     *
914 schoenebeck 2727 * @see VMExecContext, ScriptVM
915 schoenebeck 2594 */
916 schoenebeck 2588 class VMParserContext {
917     public:
918     virtual ~VMParserContext() {}
919 schoenebeck 2727
920     /**
921     * Returns all noteworthy issues encountered when the script was parsed.
922     * These are parser errors and parser warnings.
923     */
924 schoenebeck 2588 virtual std::vector<ParserIssue> issues() const = 0;
925 schoenebeck 2727
926     /**
927     * Same as issues(), but this method only returns parser errors.
928     */
929 schoenebeck 2588 virtual std::vector<ParserIssue> errors() const = 0;
930 schoenebeck 2727
931     /**
932     * Same as issues(), but this method only returns parser warnings.
933     */
934 schoenebeck 2588 virtual std::vector<ParserIssue> warnings() const = 0;
935 schoenebeck 2727
936     /**
937     * Returns the translated virtual machine representation of an event
938     * handler block (i.e. "on note ... end on" code block) within the
939     * parsed script. This translated representation of the event handler
940     * can be executed by the virtual machine.
941     *
942     * @param index - index of the event handler within the script
943     */
944 schoenebeck 2588 virtual VMEventHandler* eventHandler(uint index) = 0;
945 schoenebeck 2727
946     /**
947     * Same as eventHandler(), but this method returns the event handler by
948     * its name. So for a "on note ... end on" code block of the parsed
949     * script you would pass "note" for argument @a name here.
950     *
951     * @param name - name of the event handler (i.e. "init", "note",
952     * "controller", "release")
953     */
954 schoenebeck 2588 virtual VMEventHandler* eventHandlerByName(const String& name) = 0;
955     };
956    
957 schoenebeck 2885 class SourceToken;
958    
959     /** @brief Recognized token of a script's source code.
960     *
961     * Represents one recognized token of a script's source code, for example
962     * a keyword, variable name, etc. and it provides further informations about
963     * that particular token, i.e. the precise location (line and column) of the
964     * token within the original script's source code.
965     *
966     * This class is not actually used by the sampler itself. It is rather
967     * provided for external script editor applications. Primary purpose of
968     * this class is syntax highlighting for external script editors.
969     */
970     class VMSourceToken {
971     public:
972     VMSourceToken();
973     VMSourceToken(SourceToken* ct);
974     VMSourceToken(const VMSourceToken& other);
975     virtual ~VMSourceToken();
976    
977     // original text of this token as it is in the script's source code
978     String text() const;
979    
980     // position of token in script
981 schoenebeck 2889 int firstLine() const; ///< First line this source token is located at in script source code (indexed with 0 being the very first line).
982     int firstColumn() const; ///< Last line this source token is located at in script source code.
983 schoenebeck 2885
984     // base types
985     bool isEOF() const;
986     bool isNewLine() const;
987     bool isKeyword() const;
988     bool isVariableName() const;
989     bool isIdentifier() const;
990     bool isNumberLiteral() const;
991     bool isStringLiteral() const;
992     bool isComment() const;
993     bool isPreprocessor() const;
994     bool isOther() const;
995    
996     // extended types
997     bool isIntegerVariable() const;
998     bool isStringVariable() const;
999     bool isArrayVariable() const;
1000     bool isEventHandlerName() const;
1001    
1002     VMSourceToken& operator=(const VMSourceToken& other);
1003    
1004     private:
1005     SourceToken* m_token;
1006     };
1007    
1008 schoenebeck 2581 } // namespace LinuxSampler
1009    
1010     #endif // LS_INSTR_SCRIPT_PARSER_COMMON_H

  ViewVC Help
Powered by ViewVC