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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2879 - (show annotations) (download) (as text)
Tue Apr 19 14:07:53 2016 UTC (3 years, 1 month ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 33200 byte(s)
* All engines: Active voices are now internally grouped to "Note" objects,
  instead of being directly assigned to a keyboard key. This allows more
  fine graded processing of voices, which is i.e. required for certain
  instrument script features.
* Built-in script function "play_note()": Added support for passing
  special value -1 for "duration-us" argument, which will cause the
  triggered note to be released once the original note was released.
* Bumped version (2.0.0.svn3).

1 /*
2 * Copyright (c) 2014-2016 Christian Schoenebeck
3 *
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 #include <vector>
19 #include <map>
20 #include <stddef.h> // offsetof()
21
22 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 {
29 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 };
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 {
41 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 };
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 {
59 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, 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 };
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 {
73 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 };
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;
93 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 {
111 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;
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;
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;
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 {
173 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;
179
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 {
194 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;
200
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 {
264 public:
265 /**
266 * Returns the amount of arguments going to be passed to the script
267 * function.
268 */
269 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;
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 {
291 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;
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; }
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 {
331 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;
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;
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;
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;
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;
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;
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
419 * used directly. Use VMIntRelPtr or VMInt8RelPtr instead.
420 *
421 * @see VMIntRelPtr, VMInt8RelPtr
422 */
423 struct VMRelPtr {
424 void** base; ///< Base pointer.
425 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).
429 *
430 * 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
433 * of type "int" (which on most systems is 32 bit in size). If the C/C++ int
434 * variable you want to reference is only 8 bit in size, then you @b must
435 * use VMInt8RelPtr instead!
436 *
437 * For efficiency reasons the actual native C/C++ int variable is referenced
438 * by two components here. The actual native int C/C++ variable in memory
439 * is dereferenced at VM run-time by taking the @c base pointer dereference
440 * and adding @c offset bytes. This has the advantage that for a large
441 * number of built-in int variables, only one (or few) base pointer need
442 * to be re-assigned before running a script, instead of updating each
443 * built-in variable each time before a script is executed.
444 *
445 * Refer to DECLARE_VMINT() for example code.
446 *
447 * @see VMInt8RelPtr, DECLARE_VMINT()
448 */
449 struct VMIntRelPtr : VMRelPtr {
450 VMIntRelPtr() {
451 base = NULL;
452 offset = 0;
453 }
454 VMIntRelPtr(const VMRelPtr& data) {
455 base = data.base;
456 offset = data.offset;
457 }
458 virtual int evalInt() { return *(int*)&(*(uint8_t**)base)[offset]; }
459 virtual void assign(int i) { *(int*)&(*(uint8_t**)base)[offset] = i; }
460 };
461
462 /** @brief Pointer to built-in VM integer variable (of C/C++ type int8_t).
463 *
464 * 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
467 * of type "int8_t" (8 bit integer). If the C/C++ int variable you want to
468 * reference is an "int" type (which is 32 bit on most systems), then you
469 * @b must use VMIntRelPtr instead!
470 *
471 * For efficiency reasons the actual native C/C++ int variable is referenced
472 * by two components here. The actual native int C/C++ variable in memory
473 * is dereferenced at VM run-time by taking the @c base pointer dereference
474 * and adding @c offset bytes. This has the advantage that for a large
475 * number of built-in int variables, only one (or few) base pointer need
476 * to be re-assigned before running a script, instead of updating each
477 * built-in variable each time before a script is executed.
478 *
479 * Refer to DECLARE_VMINT() for example code.
480 *
481 * @see VMIntRelPtr, DECLARE_VMINT()
482 */
483 struct VMInt8RelPtr : VMIntRelPtr {
484 VMInt8RelPtr() : VMIntRelPtr() {}
485 VMInt8RelPtr(const VMRelPtr& data) : VMIntRelPtr(data) {}
486 virtual int evalInt() OVERRIDE {
487 return *(uint8_t*)&(*(uint8_t**)base)[offset];
488 }
489 virtual void assign(int i) OVERRIDE {
490 *(uint8_t*)&(*(uint8_t**)base)[offset] = i;
491 }
492 };
493
494 /**
495 * Convenience macro for initializing VMIntRelPtr and VMInt8RelPtr
496 * structures. Usage example:
497 * @code
498 * struct Foo {
499 * uint8_t a; // native representation of a built-in integer script variable
500 * 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 * // initializing the built-in script variables to some values
506 * Foo foo1 = (Foo) { 1, 2000, 3000, 4 };
507 * Foo foo2 = (Foo) { 5, 6000, 7000, 8 };
508 *
509 * Foo* pFoo;
510 *
511 * VMInt8RelPtr varA = DECLARE_VMINT(pFoo, class Foo, a);
512 * 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;
517 * printf("%d\n", varA->evalInt()); // will print 1
518 * 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;
525 * printf("%d\n", varA->evalInt()); // will print 5
526 * 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
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) ( \
537 (VMRelPtr) { \
538 (void**) &basePtr, \
539 offsetof(T_struct, T_member) \
540 } \
541 ) \
542
543 /** @brief Built-in VM 8 bit integer array variable.
544 *
545 * 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 {
550 int8_t* data;
551 int size;
552
553 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 {
563 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;
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;
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;
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;
590 };
591
592 /** @brief Execution state of a virtual machine.
593 *
594 * An instance of this abstract base class represents exactly one execution
595 * state of a virtual machine. This encompasses most notably the VM
596 * execution stack, and VM polyphonic variables. It does not contain global
597 * 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
606 */
607 class VMExecContext {
608 public:
609 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;
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 {
640 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;
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 {
669 String txt; ///< Human readable explanation text of the parser issue.
670 int line; ///< Line number within the script where this issue was encountered.
671 ParserIssueType_t type; ///< Whether this issue is either a parser error or just a parser warning.
672
673 /**
674 * Print this issue out to the console (stdio).
675 */
676 inline void dump() {
677 switch (type) {
678 case PARSER_ERROR:
679 printf("[ERROR] line %d: %s\n", line, txt.c_str());
680 break;
681 case PARSER_WARNING:
682 printf("[Warning] line %d: %s\n", line, txt.c_str());
683 break;
684 }
685 }
686
687 /**
688 * Returns true if this issue is a parser error. In this case the parsed
689 * script may not be executed!
690 */
691 inline bool isErr() const { return type == PARSER_ERROR; }
692
693 /**
694 * Returns true if this issue is just a parser warning. A parsed script
695 * that only raises warnings may be executed if desired, however the
696 * script may not behave exactly as intended by the script author.
697 */
698 inline bool isWrn() const { return type == PARSER_WARNING; }
699 };
700
701 /**
702 * Convenience function used for converting an ExprType_t constant to a
703 * string, i.e. for generating error message by the parser.
704 */
705 inline String typeStr(const ExprType_t& type) {
706 switch (type) {
707 case EMPTY_EXPR: return "empty";
708 case INT_EXPR: return "integer";
709 case INT_ARR_EXPR: return "integer array";
710 case STRING_EXPR: return "string";
711 case STRING_ARR_EXPR: return "string array";
712 }
713 return "invalid";
714 }
715
716 /** @brief Virtual machine representation of a script.
717 *
718 * An instance of this abstract base class represents a parsed script,
719 * translated into a virtual machine tree. You should first check if there
720 * were any parser errors. If there were any parser errors, you should
721 * refrain from executing the virtual machine. Otherwise if there were no
722 * parser errors (i.e. only warnings), then you might access one of the
723 * script's event handlers by i.e. calling eventHandlerByName() and pass the
724 * respective event handler to the ScriptVM class (or to one of the ScriptVM
725 * descendants) for execution.
726 *
727 * @see VMExecContext, ScriptVM
728 */
729 class VMParserContext {
730 public:
731 virtual ~VMParserContext() {}
732
733 /**
734 * Returns all noteworthy issues encountered when the script was parsed.
735 * These are parser errors and parser warnings.
736 */
737 virtual std::vector<ParserIssue> issues() const = 0;
738
739 /**
740 * Same as issues(), but this method only returns parser errors.
741 */
742 virtual std::vector<ParserIssue> errors() const = 0;
743
744 /**
745 * Same as issues(), but this method only returns parser warnings.
746 */
747 virtual std::vector<ParserIssue> warnings() const = 0;
748
749 /**
750 * Returns the translated virtual machine representation of an event
751 * handler block (i.e. "on note ... end on" code block) within the
752 * parsed script. This translated representation of the event handler
753 * can be executed by the virtual machine.
754 *
755 * @param index - index of the event handler within the script
756 */
757 virtual VMEventHandler* eventHandler(uint index) = 0;
758
759 /**
760 * Same as eventHandler(), but this method returns the event handler by
761 * its name. So for a "on note ... end on" code block of the parsed
762 * script you would pass "note" for argument @a name here.
763 *
764 * @param name - name of the event handler (i.e. "init", "note",
765 * "controller", "release")
766 */
767 virtual VMEventHandler* eventHandlerByName(const String& name) = 0;
768 };
769
770 } // namespace LinuxSampler
771
772 #endif // LS_INSTR_SCRIPT_PARSER_COMMON_H

  ViewVC Help
Powered by ViewVC