/[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 2596 - (hide annotations) (download) (as text)
Thu Jun 5 19:39:12 2014 UTC (9 years, 10 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 10264 byte(s)
* ScriptVM (WIP): Implemented execution of script event
  handlers "note" and "release".
* ScriptVM (WIP): Implemented built-in script function
  "play_note()" (only two of the max. four function
  arguments are currently implemented yet though).
* ScriptVM (WIP): Fixed incorrect handling of
  suspended scripts.
* Bumped version (1.0.0.svn43).

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     };
94    
95 schoenebeck 2594 /**
96     * POD base of VMIntRelPtr and VMInt8RelPtr structures. Not intended to be
97     * used directly. Use VMIntRelPtr or VMInt8RelPtr instead.
98     */
99     struct VMRelPtr {
100     void** base; ///< Base pointer.
101     int offset; ///< Offset (in bytes) to base pointer.
102     };
103    
104     /** @brief Pointer to built-in VM integer variable (of C/C++ type int).
105     *
106     * Used for defining built-in integer script variables.
107     *
108     * @b CAUTION: You may only use this class for pointing to C/C++ variables
109     * of type "int" (which on most systems is 32 bit in size). If the C/C++ int
110     * variable you want to reference is only 8 bit in size, then you @b must
111     * use VMInt8RelPtr instead!
112     *
113     * For efficiency reasons the actual native C/C++ int variable is referenced
114     * by two components here. The actual native int C/C++ variable in memory
115     * is dereferenced at VM run-time by taking the @c base pointer dereference
116     * and adding @c offset bytes. This has the advantage that for a large
117     * number of built-in int variables, only one (or few) base pointer need
118     * to be re-assigned before running a script, instead of updating each
119     * built-in variable each time before a script is executed.
120     *
121     * Refer to DECLARE_VMINT() for example code.
122     *
123     * @see VMInt8RelPtr, DECLARE_VMINT()
124     */
125     struct VMIntRelPtr : VMRelPtr {
126     VMIntRelPtr() {
127     base = NULL;
128     offset = 0;
129     }
130     VMIntRelPtr(const VMRelPtr& data) {
131     base = data.base;
132     offset = data.offset;
133     }
134     virtual int evalInt() { return *(int*)&(*(uint8_t**)base)[offset]; }
135     virtual void assign(int i) { *(int*)&(*(uint8_t**)base)[offset] = i; }
136     };
137    
138     /** @brief Pointer to built-in VM integer variable (of C/C++ type int8_t).
139     *
140     * Used for defining built-in integer script variables.
141     *
142     * @b CAUTION: You may only use this class for pointing to C/C++ variables
143     * of type "int8_t" (8 bit integer). If the C/C++ int variable you want to
144     * reference is an "int" type (which is 32 bit on most systems), then you
145     * @b must use VMIntRelPtr instead!
146     *
147     * For efficiency reasons the actual native C/C++ int variable is referenced
148     * by two components here. The actual native int C/C++ variable in memory
149     * is dereferenced at VM run-time by taking the @c base pointer dereference
150     * and adding @c offset bytes. This has the advantage that for a large
151     * number of built-in int variables, only one (or few) base pointer need
152     * to be re-assigned before running a script, instead of updating each
153     * built-in variable each time before a script is executed.
154     *
155     * Refer to DECLARE_VMINT() for example code.
156     *
157     * @see VMIntRelPtr, DECLARE_VMINT()
158     */
159     struct VMInt8RelPtr : VMIntRelPtr {
160     VMInt8RelPtr() : VMIntRelPtr() {}
161     VMInt8RelPtr(const VMRelPtr& data) : VMIntRelPtr(data) {}
162     virtual int evalInt() OVERRIDE {
163     return *(uint8_t*)&(*(uint8_t**)base)[offset];
164     }
165     virtual void assign(int i) OVERRIDE {
166     *(uint8_t*)&(*(uint8_t**)base)[offset] = i;
167     }
168     };
169    
170     /**
171     * Convenience macro for initializing VMIntRelPtr and VMInt8RelPtr
172     * structures. Example:
173     * @code
174     * struct Foo {
175     * uint8_t a;
176     * int b;
177     * };
178     *
179     * Foo foo1 = (Foo) { 1, 3000 };
180     * Foo foo2 = (Foo) { 2, 4000 };
181     *
182     * Foo* pFoo;
183     *
184     * VMInt8RelPtr var1 = DECLARE_VMINT(pFoo, class Foo, a);
185     * VMIntRelPtr var2 = DECLARE_VMINT(pFoo, class Foo, b);
186     *
187     * pFoo = &foo1;
188     * printf("%d\n", var1->evalInt()); // will print 1
189     * printf("%d\n", var2->evalInt()); // will print 3000
190     *
191     * pFoo = &foo2;
192     * printf("%d\n", var1->evalInt()); // will print 2
193     * printf("%d\n", var2->evalInt()); // will print 4000
194     * @endcode
195     */
196     #define DECLARE_VMINT(basePtr, T_struct, T_member) ( \
197     (VMRelPtr) { \
198     (void**) &basePtr, \
199     offsetof(T_struct, T_member) \
200     } \
201     ) \
202    
203     /** @brief Built-in VM 8 bit integer array variable.
204     *
205     * Used for defining built-in integer array script variables.
206     */
207     struct VMInt8Array {
208     int8_t* data;
209     int size;
210    
211     VMInt8Array() : data(NULL), size(0) {}
212     };
213    
214 schoenebeck 2581 class VMFunctionProvider {
215     public:
216     virtual VMFunction* functionByName(const String& name) = 0;
217 schoenebeck 2594 virtual std::map<String,VMIntRelPtr*> builtInIntVariables() = 0;
218     virtual std::map<String,VMInt8Array*> builtInIntArrayVariables() = 0;
219     virtual std::map<String,int> builtInConstIntVariables() = 0;
220 schoenebeck 2581 };
221    
222 schoenebeck 2594 /** @brief Execution state of a virtual machine.
223     *
224     * An instance of this abstract base class represents exactly one execution
225     * state of a virtual machine. This encompasses most notably the VM
226     * execution stack, and VM polyphonic variables. You might see it as one
227     * virtual thread of the virtual machine.
228     *
229     * @see VMParserContext
230     */
231 schoenebeck 2581 class VMExecContext {
232     public:
233     virtual ~VMExecContext() {}
234     virtual int suspensionTimeMicroseconds() const = 0;
235     };
236    
237     class VMEventHandler {
238     public:
239     virtual String eventHandlerName() const = 0;
240     };
241    
242     struct ParserIssue {
243     String txt;
244     int line;
245     ParserIssueType_t type;
246    
247     inline void dump() {
248     switch (type) {
249     case PARSER_ERROR:
250     printf("[ERROR] line %d: %s\n", line, txt.c_str());
251     break;
252     case PARSER_WARNING:
253     printf("[Warning] line %d: %s\n", line, txt.c_str());
254     break;
255     }
256     }
257    
258     inline bool isErr() const { return type == PARSER_ERROR; }
259     inline bool isWrn() const { return type == PARSER_WARNING; }
260     };
261    
262     inline String typeStr(const ExprType_t& type) {
263     switch (type) {
264     case EMPTY_EXPR: return "empty";
265     case INT_EXPR: return "integer";
266     case INT_ARR_EXPR: return "integer array";
267     case STRING_EXPR: return "string";
268     case STRING_ARR_EXPR: return "string array";
269     }
270     return "invalid";
271     }
272    
273 schoenebeck 2594 /** @brief Virtual machine representation of a script.
274     *
275     * An instance of this abstract base class represents a parsed script,
276     * translated into a virtual machine. You should first check if there were
277     * any parser errors. If there were any parser errors, you should refrain
278     * from executing the virtual machine. Otherwise if there were no parser
279     * errors (i.e. only warnings), then you might access one of the script's
280     * event handlers by i.e. calling eventHandlerByName() and pass the
281     * respective event handler to the ScriptVM class (or to one of its
282     * descendants) for execution.
283     *
284     * @see VMExecContext
285     */
286 schoenebeck 2588 class VMParserContext {
287     public:
288     virtual ~VMParserContext() {}
289     virtual std::vector<ParserIssue> issues() const = 0;
290     virtual std::vector<ParserIssue> errors() const = 0;
291     virtual std::vector<ParserIssue> warnings() const = 0;
292     virtual VMEventHandler* eventHandler(uint index) = 0;
293     virtual VMEventHandler* eventHandlerByName(const String& name) = 0;
294     };
295    
296 schoenebeck 2581 } // namespace LinuxSampler
297    
298     #endif // LS_INSTR_SCRIPT_PARSER_COMMON_H

  ViewVC Help
Powered by ViewVC