/[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 2598 - (show 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 /*
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 #include <vector>
19 #include <map>
20 #include <stddef.h> // offsetof()
21
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 class VMIntExpr;
52 class VMStringExpr;
53
54 class VMExpr {
55 public:
56 virtual ExprType_t exprType() const = 0;
57 VMIntExpr* asInt() const;
58 VMStringExpr* asString() const;
59 };
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 void wrnMsg(const String& txt);
94 void errMsg(const String& txt);
95 };
96
97 /**
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 class VMFunctionProvider {
217 public:
218 virtual VMFunction* functionByName(const String& name) = 0;
219 virtual std::map<String,VMIntRelPtr*> builtInIntVariables() = 0;
220 virtual std::map<String,VMInt8Array*> builtInIntArrayVariables() = 0;
221 virtual std::map<String,int> builtInConstIntVariables() = 0;
222 };
223
224 /** @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 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 /** @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 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 } // namespace LinuxSampler
299
300 #endif // LS_INSTR_SCRIPT_PARSER_COMMON_H

  ViewVC Help
Powered by ViewVC