/[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 2598 - (hide annotations) (download) (as text)
Fri Jun 6 12:38:54 2014 UTC (9 years, 9 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 10344 byte(s)
* ScriptVM (WIP): Built-in script function "play_note()" now returns the
  event ID of the triggered note.
* ScriptVM (WIP): Implemented built-in script int variable $EVENT_ID.
* ScriptVM (WIP): Implemented built-in script function "ignore_event()".
* ScriptVM (WIP): Implemented built-in script function
  "ignore_controller()" (accepts one and no argument).
* Bumped version (1.0.0.svn44).

1 schoenebeck 2581 /*
2     * Copyright (c) 2014 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 schoenebeck 2588 #include <vector>
19 schoenebeck 2594 #include <map>
20     #include <stddef.h> // offsetof()
21 schoenebeck 2581
22     namespace LinuxSampler {
23    
24     enum ParserIssueType_t {
25     PARSER_ERROR,
26     PARSER_WARNING
27     };
28    
29     enum ExprType_t {
30     EMPTY_EXPR, ///< i.e. on invalid expressions or i.e. a function call that does not return a result value
31     INT_EXPR,
32     INT_ARR_EXPR,
33     STRING_EXPR,
34     STRING_ARR_EXPR,
35     };
36    
37     enum StmtFlags_t {
38     STMT_SUCCESS = 0, ///< Function / statement was executed successfully, no error occurred.
39     STMT_ABORT_SIGNALLED = 1, ///< VM should stop the current callback execution (usually because of an error, but might also be without an error reason).
40     STMT_SUSPEND_SIGNALLED = (1<<1),
41     STMT_ERROR_OCCURRED = (1<<2),
42     };
43    
44     enum VMExecStatus_t {
45     VM_EXEC_NOT_RUNNING = 0,
46     VM_EXEC_RUNNING = 1,
47     VM_EXEC_SUSPENDED = (1<<1),
48     VM_EXEC_ERROR = (1<<2),
49     };
50    
51 schoenebeck 2596 class VMIntExpr;
52     class VMStringExpr;
53    
54 schoenebeck 2581 class VMExpr {
55     public:
56     virtual ExprType_t exprType() const = 0;
57 schoenebeck 2596 VMIntExpr* asInt() const;
58     VMStringExpr* asString() const;
59 schoenebeck 2581 };
60    
61     class VMIntExpr : virtual public VMExpr {
62     public:
63     virtual int evalInt() = 0;
64     ExprType_t exprType() const { return INT_EXPR; }
65     };
66    
67     class VMStringExpr : virtual public VMExpr {
68     public:
69     virtual String evalStr() = 0;
70     ExprType_t exprType() const { return STRING_EXPR; }
71     };
72    
73     class VMFnArgs {
74     public:
75     virtual int argsCount() const = 0;
76     virtual VMExpr* arg(int i) = 0;
77     };
78    
79     class VMFnResult {
80     public:
81     virtual VMExpr* resultValue() = 0;
82     virtual StmtFlags_t resultFlags() { return STMT_SUCCESS; }
83     };
84    
85     class VMFunction {
86     public:
87     virtual ExprType_t returnType() = 0;
88     virtual int minRequiredArgs() const = 0;
89     virtual int maxAllowedArgs() const = 0;
90     virtual ExprType_t argType(int iArg) const = 0;
91     virtual bool acceptsArgType(int iArg, ExprType_t type) const = 0;
92     virtual VMFnResult* exec(VMFnArgs* args) = 0;
93 schoenebeck 2598 void wrnMsg(const String& txt);
94     void errMsg(const String& txt);
95 schoenebeck 2581 };
96    
97 schoenebeck 2594 /**
98     * POD base of VMIntRelPtr and VMInt8RelPtr structures. Not intended to be
99     * used directly. Use VMIntRelPtr or VMInt8RelPtr instead.
100     */
101     struct VMRelPtr {
102     void** base; ///< Base pointer.
103     int offset; ///< Offset (in bytes) to base pointer.
104     };
105    
106     /** @brief Pointer to built-in VM integer variable (of C/C++ type int).
107     *
108     * Used for defining built-in integer script variables.
109     *
110     * @b CAUTION: You may only use this class for pointing to C/C++ variables
111     * of type "int" (which on most systems is 32 bit in size). If the C/C++ int
112     * variable you want to reference is only 8 bit in size, then you @b must
113     * use VMInt8RelPtr instead!
114     *
115     * For efficiency reasons the actual native C/C++ int variable is referenced
116     * by two components here. The actual native int C/C++ variable in memory
117     * is dereferenced at VM run-time by taking the @c base pointer dereference
118     * and adding @c offset bytes. This has the advantage that for a large
119     * number of built-in int variables, only one (or few) base pointer need
120     * to be re-assigned before running a script, instead of updating each
121     * built-in variable each time before a script is executed.
122     *
123     * Refer to DECLARE_VMINT() for example code.
124     *
125     * @see VMInt8RelPtr, DECLARE_VMINT()
126     */
127     struct VMIntRelPtr : VMRelPtr {
128     VMIntRelPtr() {
129     base = NULL;
130     offset = 0;
131     }
132     VMIntRelPtr(const VMRelPtr& data) {
133     base = data.base;
134     offset = data.offset;
135     }
136     virtual int evalInt() { return *(int*)&(*(uint8_t**)base)[offset]; }
137     virtual void assign(int i) { *(int*)&(*(uint8_t**)base)[offset] = i; }
138     };
139    
140     /** @brief Pointer to built-in VM integer variable (of C/C++ type int8_t).
141     *
142     * Used for defining built-in integer script variables.
143     *
144     * @b CAUTION: You may only use this class for pointing to C/C++ variables
145     * of type "int8_t" (8 bit integer). If the C/C++ int variable you want to
146     * reference is an "int" type (which is 32 bit on most systems), then you
147     * @b must use VMIntRelPtr instead!
148     *
149     * For efficiency reasons the actual native C/C++ int variable is referenced
150     * by two components here. The actual native int C/C++ variable in memory
151     * is dereferenced at VM run-time by taking the @c base pointer dereference
152     * and adding @c offset bytes. This has the advantage that for a large
153     * number of built-in int variables, only one (or few) base pointer need
154     * to be re-assigned before running a script, instead of updating each
155     * built-in variable each time before a script is executed.
156     *
157     * Refer to DECLARE_VMINT() for example code.
158     *
159     * @see VMIntRelPtr, DECLARE_VMINT()
160     */
161     struct VMInt8RelPtr : VMIntRelPtr {
162     VMInt8RelPtr() : VMIntRelPtr() {}
163     VMInt8RelPtr(const VMRelPtr& data) : VMIntRelPtr(data) {}
164     virtual int evalInt() OVERRIDE {
165     return *(uint8_t*)&(*(uint8_t**)base)[offset];
166     }
167     virtual void assign(int i) OVERRIDE {
168     *(uint8_t*)&(*(uint8_t**)base)[offset] = i;
169     }
170     };
171    
172     /**
173     * Convenience macro for initializing VMIntRelPtr and VMInt8RelPtr
174     * structures. Example:
175     * @code
176     * struct Foo {
177     * uint8_t a;
178     * int b;
179     * };
180     *
181     * Foo foo1 = (Foo) { 1, 3000 };
182     * Foo foo2 = (Foo) { 2, 4000 };
183     *
184     * Foo* pFoo;
185     *
186     * VMInt8RelPtr var1 = DECLARE_VMINT(pFoo, class Foo, a);
187     * VMIntRelPtr var2 = DECLARE_VMINT(pFoo, class Foo, b);
188     *
189     * pFoo = &foo1;
190     * printf("%d\n", var1->evalInt()); // will print 1
191     * printf("%d\n", var2->evalInt()); // will print 3000
192     *
193     * pFoo = &foo2;
194     * printf("%d\n", var1->evalInt()); // will print 2
195     * printf("%d\n", var2->evalInt()); // will print 4000
196     * @endcode
197     */
198     #define DECLARE_VMINT(basePtr, T_struct, T_member) ( \
199     (VMRelPtr) { \
200     (void**) &basePtr, \
201     offsetof(T_struct, T_member) \
202     } \
203     ) \
204    
205     /** @brief Built-in VM 8 bit integer array variable.
206     *
207     * Used for defining built-in integer array script variables.
208     */
209     struct VMInt8Array {
210     int8_t* data;
211     int size;
212    
213     VMInt8Array() : data(NULL), size(0) {}
214     };
215    
216 schoenebeck 2581 class VMFunctionProvider {
217     public:
218     virtual VMFunction* functionByName(const String& name) = 0;
219 schoenebeck 2594 virtual std::map<String,VMIntRelPtr*> builtInIntVariables() = 0;
220     virtual std::map<String,VMInt8Array*> builtInIntArrayVariables() = 0;
221     virtual std::map<String,int> builtInConstIntVariables() = 0;
222 schoenebeck 2581 };
223    
224 schoenebeck 2594 /** @brief Execution state of a virtual machine.
225     *
226     * An instance of this abstract base class represents exactly one execution
227     * state of a virtual machine. This encompasses most notably the VM
228     * execution stack, and VM polyphonic variables. You might see it as one
229     * virtual thread of the virtual machine.
230     *
231     * @see VMParserContext
232     */
233 schoenebeck 2581 class VMExecContext {
234     public:
235     virtual ~VMExecContext() {}
236     virtual int suspensionTimeMicroseconds() const = 0;
237     };
238    
239     class VMEventHandler {
240     public:
241     virtual String eventHandlerName() const = 0;
242     };
243    
244     struct ParserIssue {
245     String txt;
246     int line;
247     ParserIssueType_t type;
248    
249     inline void dump() {
250     switch (type) {
251     case PARSER_ERROR:
252     printf("[ERROR] line %d: %s\n", line, txt.c_str());
253     break;
254     case PARSER_WARNING:
255     printf("[Warning] line %d: %s\n", line, txt.c_str());
256     break;
257     }
258     }
259    
260     inline bool isErr() const { return type == PARSER_ERROR; }
261     inline bool isWrn() const { return type == PARSER_WARNING; }
262     };
263    
264     inline String typeStr(const ExprType_t& type) {
265     switch (type) {
266     case EMPTY_EXPR: return "empty";
267     case INT_EXPR: return "integer";
268     case INT_ARR_EXPR: return "integer array";
269     case STRING_EXPR: return "string";
270     case STRING_ARR_EXPR: return "string array";
271     }
272     return "invalid";
273     }
274    
275 schoenebeck 2594 /** @brief Virtual machine representation of a script.
276     *
277     * An instance of this abstract base class represents a parsed script,
278     * translated into a virtual machine. You should first check if there were
279     * any parser errors. If there were any parser errors, you should refrain
280     * from executing the virtual machine. Otherwise if there were no parser
281     * errors (i.e. only warnings), then you might access one of the script's
282     * event handlers by i.e. calling eventHandlerByName() and pass the
283     * respective event handler to the ScriptVM class (or to one of its
284     * descendants) for execution.
285     *
286     * @see VMExecContext
287     */
288 schoenebeck 2588 class VMParserContext {
289     public:
290     virtual ~VMParserContext() {}
291     virtual std::vector<ParserIssue> issues() const = 0;
292     virtual std::vector<ParserIssue> errors() const = 0;
293     virtual std::vector<ParserIssue> warnings() const = 0;
294     virtual VMEventHandler* eventHandler(uint index) = 0;
295     virtual VMEventHandler* eventHandlerByName(const String& name) = 0;
296     };
297    
298 schoenebeck 2581 } // namespace LinuxSampler
299    
300     #endif // LS_INSTR_SCRIPT_PARSER_COMMON_H

  ViewVC Help
Powered by ViewVC