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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2889 - (show annotations) (download) (as text)
Mon Apr 25 17:28:23 2016 UTC (5 years, 3 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 20278 byte(s)
* Added new C++ API class "ScriptVMFactory".
* Instrument Scripts: extended parser issues to provide not only first
  line and first column, but also last line and last column of issue
  (thus marking the precise span of the issue within the source code).
* Bumped version (2.0.0.svn7).

1 /* -*- c++ -*-
2 *
3 * Copyright (c) 2014 - 2016 Christian Schoenebeck and Andreas Persson
4 *
5 * http://www.linuxsampler.org
6 *
7 * This file is part of LinuxSampler and released under the same terms.
8 * See README file for details.
9 */
10
11 // This header defines VM core implementation internal data types only used
12 // inside the parser and core VM implementation of this source directory. Not
13 // intended to be used in other source code parts (other source code
14 // directories) of the sampler.
15
16 #ifndef LS_INSTRPARSERTREE_H
17 #define LS_INSTRPARSERTREE_H
18
19 #include <vector>
20 #include <iostream>
21 #include <map>
22 #include <set>
23 #include "../common/global.h"
24 #include "../common/Ref.h"
25 #include "../common/ArrayList.h"
26 #include "common.h"
27
28 namespace LinuxSampler {
29
30 class ParserContext;
31 class ExecContext;
32
33 enum StmtType_t {
34 STMT_LEAF,
35 STMT_LIST,
36 STMT_BRANCH,
37 STMT_LOOP,
38 };
39
40 class Node {
41 public:
42 Node();
43 virtual ~Node();
44 virtual void dump(int level = 0) = 0;
45 virtual bool isPolyphonic() const = 0;
46 void printIndents(int n);
47 };
48 typedef Ref<Node> NodeRef;
49
50 class Expression : virtual public VMExpr, virtual public Node {
51 public:
52 virtual ExprType_t exprType() const = 0;
53 virtual bool isConstExpr() const = 0;
54 virtual String evalCastToStr() = 0;
55 };
56 typedef Ref<Expression,Node> ExpressionRef;
57
58 class IntExpr : virtual public VMIntExpr, virtual public Expression {
59 public:
60 ExprType_t exprType() const { return INT_EXPR; }
61 virtual int evalInt() = 0;
62 String evalCastToStr();
63 };
64 typedef Ref<IntExpr,Node> IntExprRef;
65
66 class StringExpr : virtual public VMStringExpr, virtual public Expression {
67 public:
68 ExprType_t exprType() const { return STRING_EXPR; }
69 virtual String evalStr() = 0;
70 String evalCastToStr() { return evalStr(); }
71 };
72 typedef Ref<StringExpr,Node> StringExprRef;
73
74 class IntLiteral : virtual public IntExpr {
75 int value;
76 public:
77 IntLiteral(int value) : value(value) { }
78 int evalInt();
79 void dump(int level = 0);
80 bool isConstExpr() const { return true; }
81 bool isPolyphonic() const { return false; }
82 };
83 typedef Ref<IntLiteral,Node> IntLiteralRef;
84
85 class StringLiteral : virtual public StringExpr {
86 public:
87 String value;
88 StringLiteral(const String& value) : value(value) { }
89 bool isConstExpr() const { return true; }
90 void dump(int level = 0);
91 String evalStr() { return value; }
92 bool isPolyphonic() const { return false; }
93 };
94 typedef Ref<StringLiteral,Node> StringLiteralRef;
95
96 class Args : virtual public VMFnArgs, virtual public Node {
97 public:
98 std::vector<ExpressionRef> args;
99 void add(ExpressionRef arg) { args.push_back(arg); }
100 void dump(int level = 0);
101 int argsCount() const { return args.size(); }
102 VMExpr* arg(int i) { return (i >= 0 && i < argsCount()) ? &*args.at(i) : NULL; }
103 bool isPolyphonic() const;
104 };
105 typedef Ref<Args,Node> ArgsRef;
106
107 class Variable : virtual public Expression {
108 public:
109 virtual bool isConstExpr() const { return bConst; }
110 virtual void assign(Expression* expr) = 0;
111 protected:
112 Variable(ParserContext* ctx, int _memPos, bool _bConst)
113 : context(ctx), memPos(_memPos), bConst(_bConst) {}
114
115 ParserContext* context;
116 int memPos;
117 bool bConst;
118 };
119 typedef Ref<Variable,Node> VariableRef;
120
121 class IntVariable : public Variable, virtual public IntExpr {
122 bool polyphonic;
123 public:
124 IntVariable(ParserContext* ctx);
125 void assign(Expression* expr);
126 int evalInt();
127 void dump(int level = 0);
128 bool isPolyphonic() const { return polyphonic; }
129 protected:
130 IntVariable(ParserContext* ctx, bool polyphonic, bool bConst, int size = 1);
131 };
132 typedef Ref<IntVariable,Node> IntVariableRef;
133
134 class ConstIntVariable : public IntVariable {
135 public:
136 int value;
137
138 ConstIntVariable(int value);
139 //ConstIntVariable(ParserContext* ctx, int value = 0);
140 void assign(Expression* expr);
141 int evalInt();
142 void dump(int level = 0);
143 };
144 typedef Ref<ConstIntVariable,Node> ConstIntVariableRef;
145
146 class BuiltInIntVariable : public IntVariable {
147 String name;
148 VMIntRelPtr* ptr;
149 public:
150 BuiltInIntVariable(const String& name, VMIntRelPtr* ptr);
151 void assign(Expression* expr);
152 int evalInt();
153 void dump(int level = 0);
154 };
155 typedef Ref<BuiltInIntVariable,Node> BuiltInIntVariableRef;
156
157 class PolyphonicIntVariable : public IntVariable {
158 public:
159 PolyphonicIntVariable(ParserContext* ctx);
160 void dump(int level = 0);
161 };
162 typedef Ref<PolyphonicIntVariable,Node> PolyphonicIntVariableRef;
163
164 class IntArrayVariable : public Variable, virtual public VMIntArrayExpr {
165 ArrayList<int> values;
166 public:
167 IntArrayVariable(ParserContext* ctx, int size);
168 IntArrayVariable(ParserContext* ctx, int size, ArgsRef values);
169 void assign(Expression* expr) {} // ignore scalar assignment
170 String evalCastToStr() { return ""; } // ignore scalar cast to string
171 ExprType_t exprType() const { return INT_ARR_EXPR; }
172 virtual int arraySize() const { return values.size(); }
173 virtual int evalIntElement(uint i);
174 virtual void assignIntElement(uint i, int value);
175 void dump(int level = 0);
176 bool isPolyphonic() const { return false; }
177 protected:
178 IntArrayVariable(ParserContext* ctx, bool bConst);
179 };
180 typedef Ref<IntArrayVariable,Node> IntArrayVariableRef;
181
182 class BuiltInIntArrayVariable : public IntArrayVariable {
183 String name;
184 VMInt8Array* array;
185 public:
186 BuiltInIntArrayVariable(const String& name, VMInt8Array* array);
187 int arraySize() const { return array->size; }
188 int evalIntElement(uint i);
189 void assignIntElement(uint i, int value);
190 void dump(int level = 0);
191 };
192 typedef Ref<BuiltInIntArrayVariable,Node> BuiltInIntArrayVariableRef;
193
194 class IntArrayElement : public IntVariable {
195 IntArrayVariableRef array;
196 IntExprRef index;
197 public:
198 IntArrayElement(IntArrayVariableRef array, IntExprRef arrayIndex);
199 void assign(Expression* expr);
200 int evalInt();
201 void dump(int level = 0);
202 };
203 typedef Ref<IntArrayElement,Node> IntArrayElementRef;
204
205 class StringVariable : public Variable, virtual public StringExpr {
206 public:
207 StringVariable(ParserContext* ctx);
208 void assign(Expression* expr);
209 String evalStr();
210 void dump(int level = 0);
211 bool isPolyphonic() const { return false; }
212 protected:
213 StringVariable(ParserContext* ctx, bool bConst);
214 };
215 typedef Ref<StringVariable,Node> StringVariableRef;
216
217 class ConstStringVariable : public StringVariable {
218 public:
219 String value;
220
221 ConstStringVariable(ParserContext* ctx, String value = "");
222 void assign(Expression* expr);
223 String evalStr();
224 void dump(int level = 0);
225 };
226 typedef Ref<ConstStringVariable,Node> ConstStringVariableRef;
227
228 class BinaryOp : virtual public Expression {
229 protected:
230 ExpressionRef lhs;
231 ExpressionRef rhs;
232 public:
233 BinaryOp(ExpressionRef lhs, ExpressionRef rhs) : lhs(lhs), rhs(rhs) { }
234 bool isConstExpr() const { return lhs->isConstExpr() && rhs->isConstExpr(); }
235 bool isPolyphonic() const { return lhs->isPolyphonic() || rhs->isPolyphonic(); }
236 };
237 typedef Ref<BinaryOp,Node> BinaryOpRef;
238
239 class Add : virtual public BinaryOp, virtual public IntExpr {
240 public:
241 Add(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs, rhs) { }
242 int evalInt();
243 void dump(int level = 0);
244 };
245 typedef Ref<Add,Node> AddRef;
246
247 class Sub : virtual public BinaryOp, virtual public IntExpr {
248 public:
249 Sub(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs, rhs) { }
250 int evalInt();
251 void dump(int level = 0);
252 };
253 typedef Ref<Sub,Node> SubRef;
254
255 class Mul : virtual public BinaryOp, virtual public IntExpr {
256 public:
257 Mul(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs, rhs) { }
258 int evalInt();
259 void dump(int level = 0);
260 };
261 typedef Ref<Mul,Node> MulRef;
262
263 class Div : virtual public BinaryOp, virtual public IntExpr {
264 public:
265 Div(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs, rhs) { }
266 int evalInt();
267 void dump(int level = 0);
268 };
269 typedef Ref<Div,Node> DivRef;
270
271 class Mod : virtual public BinaryOp, virtual public IntExpr {
272 public:
273 Mod(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs, rhs) { }
274 int evalInt();
275 void dump(int level = 0);
276 };
277 typedef Ref<Mod,Node> ModRef;
278
279 class Statement : virtual public Node {
280 public:
281 virtual StmtType_t statementType() const = 0;
282 };
283 typedef Ref<Statement,Node> StatementRef;
284
285 // Just used by parser to avoid "not a statement" parser warning, will be
286 // filtered out by parser. So it will not be part of the VM tree after parsing.
287 class NoOperation : public Statement {
288 public:
289 NoOperation() : Statement() {}
290 StmtType_t statementType() const { return STMT_LEAF; }
291 void dump(int level = 0) {}
292 bool isPolyphonic() const { return false; }
293 };
294 typedef Ref<NoOperation,Node> NoOperationRef;
295
296 bool isNoOperation(StatementRef statement);
297
298 class LeafStatement : public Statement {
299 public:
300 virtual StmtFlags_t exec() = 0;
301 virtual StmtType_t statementType() const { return STMT_LEAF; }
302 };
303 typedef Ref<LeafStatement,Node> LeafStatementRef;
304
305 class Statements : public Statement {
306 std::vector<StatementRef> args;
307 public:
308 void add(StatementRef arg) { args.push_back(arg); }
309 void dump(int level = 0);
310 StmtType_t statementType() const { return STMT_LIST; }
311 virtual Statement* statement(uint i);
312 bool isPolyphonic() const;
313 };
314 typedef Ref<Statements,Node> StatementsRef;
315
316 class BranchStatement : public Statement {
317 public:
318 StmtType_t statementType() const { return STMT_BRANCH; }
319 virtual int evalBranch() = 0;
320 virtual Statements* branch(uint i) const = 0;
321 };
322
323 class FunctionCall : virtual public LeafStatement, virtual public IntExpr, virtual public StringExpr {
324 String functionName;
325 ArgsRef args;
326 VMFunction* fn;
327 public:
328 FunctionCall(const char* function, ArgsRef args, VMFunction* fn) :
329 functionName(function), args(args), fn(fn) { }
330 void dump(int level = 0);
331 StmtFlags_t exec();
332 int evalInt();
333 String evalStr();
334 bool isConstExpr() const { return false; }
335 ExprType_t exprType() const;
336 String evalCastToStr();
337 bool isPolyphonic() const { return args->isPolyphonic(); }
338 protected:
339 VMFnResult* execVMFn();
340 };
341 typedef Ref<FunctionCall,Node> FunctionCallRef;
342
343 class EventHandler : virtual public Statements, virtual public VMEventHandler {
344 StatementsRef statements;
345 bool usingPolyphonics;
346 public:
347 void dump(int level = 0);
348 StmtFlags_t exec();
349 EventHandler(StatementsRef statements);
350 Statement* statement(uint i) { return statements->statement(i); }
351 bool isPolyphonic() const { return usingPolyphonics; }
352 };
353 typedef Ref<EventHandler,Node> EventHandlerRef;
354
355 class OnNote : public EventHandler {
356 public:
357 OnNote(StatementsRef statements) : EventHandler(statements) {}
358 VMEventHandlerType_t eventHandlerType() const { return VM_EVENT_HANDLER_NOTE; }
359 String eventHandlerName() const { return "note"; }
360 };
361 typedef Ref<OnNote,Node> OnNoteRef;
362
363 class OnInit : public EventHandler {
364 public:
365 OnInit(StatementsRef statements) : EventHandler(statements) {}
366 VMEventHandlerType_t eventHandlerType() const { return VM_EVENT_HANDLER_INIT; }
367 String eventHandlerName() const { return "init"; }
368 };
369 typedef Ref<OnInit,Node> OnInitRef;
370
371 class OnRelease : public EventHandler {
372 public:
373 OnRelease(StatementsRef statements) : EventHandler(statements) {}
374 VMEventHandlerType_t eventHandlerType() const { return VM_EVENT_HANDLER_RELEASE; }
375 String eventHandlerName() const { return "release"; }
376 };
377 typedef Ref<OnRelease,Node> OnReleaseRef;
378
379 class OnController : public EventHandler {
380 public:
381 OnController(StatementsRef statements) : EventHandler(statements) {}
382 VMEventHandlerType_t eventHandlerType() const { return VM_EVENT_HANDLER_CONTROLLER; }
383 String eventHandlerName() const { return "controller"; }
384 };
385 typedef Ref<OnController,Node> OnControllerRef;
386
387 class EventHandlers : virtual public Node {
388 std::vector<EventHandlerRef> args;
389 public:
390 EventHandlers();
391 ~EventHandlers();
392 void add(EventHandlerRef arg);
393 void dump(int level = 0);
394 int evalInt() { return 0; }
395 EventHandler* eventHandlerByName(const String& name) const;
396 EventHandler* eventHandler(uint index) const;
397 inline uint size() const { return args.size(); }
398 bool isPolyphonic() const;
399 };
400 typedef Ref<EventHandlers,Node> EventHandlersRef;
401
402 class Assignment : public LeafStatement {
403 protected:
404 VariableRef variable;
405 ExpressionRef value;
406 public:
407 Assignment(VariableRef variable, ExpressionRef value);
408 void dump(int level = 0);
409 StmtFlags_t exec();
410 bool isPolyphonic() const { return (variable && variable->isPolyphonic()) || (value && value->isPolyphonic()); }
411 };
412 typedef Ref<Assignment,Node> AssignmentRef;
413
414 class If : public BranchStatement {
415 IntExprRef condition;
416 StatementsRef ifStatements;
417 StatementsRef elseStatements;
418 public:
419 If(IntExprRef condition, StatementsRef ifStatements, StatementsRef elseStatements) :
420 condition(condition), ifStatements(ifStatements), elseStatements(elseStatements) { }
421 If(IntExprRef condition, StatementsRef statements) :
422 condition(condition), ifStatements(statements) { }
423 void dump(int level = 0);
424 int evalBranch();
425 Statements* branch(uint i) const;
426 bool isPolyphonic() const;
427 };
428 typedef Ref<If,Node> IfRef;
429
430 struct CaseBranch {
431 IntExprRef from;
432 IntExprRef to;
433 StatementsRef statements;
434 };
435
436 typedef std::vector<CaseBranch> CaseBranches;
437
438 class SelectCase : public BranchStatement {
439 IntExprRef select;
440 CaseBranches branches;
441 public:
442 SelectCase(IntExprRef select, const CaseBranches& branches) : select(select), branches(branches) { }
443 void dump(int level = 0);
444 int evalBranch();
445 Statements* branch(uint i) const;
446 //void addBranch(IntExprRef condition, StatementsRef statements);
447 //void addBranch(IntExprRef from, IntExprRef to, StatementsRef statements);
448 //void addBranch(CaseBranchRef branch);
449 //void addBranches(CaseBranchesRef branches);
450 bool isPolyphonic() const;
451 };
452 typedef Ref<SelectCase,Node> SelectCaseRef;
453
454 class While : public Statement {
455 IntExprRef m_condition;
456 StatementsRef m_statements;
457 public:
458 While(IntExprRef condition, StatementsRef statements) :
459 m_condition(condition), m_statements(statements) {}
460 StmtType_t statementType() const { return STMT_LOOP; }
461 void dump(int level = 0);
462 bool evalLoopStartCondition();
463 Statements* statements() const;
464 bool isPolyphonic() const { return m_condition->isPolyphonic() || m_statements->isPolyphonic(); }
465 };
466
467 class Neg : public IntExpr {
468 IntExprRef expr;
469 public:
470 Neg(IntExprRef expr) : expr(expr) { }
471 int evalInt() { return (expr) ? -expr->evalInt() : 0; }
472 void dump(int level = 0);
473 bool isConstExpr() const { return expr->isConstExpr(); }
474 bool isPolyphonic() const { return expr->isPolyphonic(); }
475 };
476 typedef Ref<Neg,Node> NegRef;
477
478 class ConcatString : public StringExpr {
479 ExpressionRef lhs;
480 ExpressionRef rhs;
481 public:
482 ConcatString(ExpressionRef lhs, ExpressionRef rhs) : lhs(lhs), rhs(rhs) {}
483 String evalStr();
484 void dump(int level = 0);
485 bool isConstExpr() const;
486 bool isPolyphonic() const { return lhs->isPolyphonic() || rhs->isPolyphonic(); }
487 };
488 typedef Ref<ConcatString,Node> ConcatStringRef;
489
490 class Relation : public IntExpr {
491 public:
492 enum Type {
493 LESS_THAN,
494 GREATER_THAN,
495 LESS_OR_EQUAL,
496 GREATER_OR_EQUAL,
497 EQUAL,
498 NOT_EQUAL
499 };
500 Relation(IntExprRef lhs, Type type, IntExprRef rhs) :
501 lhs(lhs), rhs(rhs), type(type) {}
502 int evalInt();
503 void dump(int level = 0);
504 bool isConstExpr() const;
505 bool isPolyphonic() const { return lhs->isPolyphonic() || rhs->isPolyphonic(); }
506 private:
507 IntExprRef lhs;
508 IntExprRef rhs;
509 Type type;
510 };
511 typedef Ref<Relation,Node> RelationRef;
512
513 class Or : virtual public BinaryOp, virtual public IntExpr {
514 public:
515 Or(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs,rhs) {}
516 int evalInt();
517 void dump(int level = 0);
518 };
519 typedef Ref<Or,Node> OrRef;
520
521 class And : virtual public BinaryOp, virtual public IntExpr {
522 public:
523 And(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs,rhs) {}
524 int evalInt();
525 void dump(int level = 0);
526 };
527 typedef Ref<And,Node> AndRef;
528
529 class Not : virtual public IntExpr {
530 IntExprRef expr;
531 public:
532 Not(IntExprRef expr) : expr(expr) {}
533 int evalInt() { return !expr->evalInt(); }
534 void dump(int level = 0);
535 bool isConstExpr() const { return expr->isConstExpr(); }
536 bool isPolyphonic() const { return expr->isPolyphonic(); }
537 };
538 typedef Ref<Not,Node> NotRef;
539
540 class ParserContext : public VMParserContext {
541 public:
542 struct Error {
543 String txt;
544 int line;
545 };
546 typedef Error Warning;
547
548 void* scanner;
549 std::istream* is;
550 std::vector<ParserIssue> vErrors;
551 std::vector<ParserIssue> vWarnings;
552 std::vector<ParserIssue> vIssues;
553
554 std::set<String> builtinPreprocessorConditions;
555 std::set<String> userPreprocessorConditions;
556
557 std::map<String,VariableRef> vartable;
558 int globalIntVarCount;
559 int globalStrVarCount;
560 int polyphonicIntVarCount;
561
562 EventHandlersRef handlers;
563
564 OnInitRef onInit;
565 OnNoteRef onNote;
566 OnReleaseRef onRelease;
567 OnControllerRef onController;
568
569 ArrayList<int>* globalIntMemory;
570 ArrayList<String>* globalStrMemory;
571 int requiredMaxStackSize;
572
573 VMFunctionProvider* functionProvider;
574
575 ExecContext* execContext;
576
577 ParserContext(VMFunctionProvider* parent) :
578 scanner(NULL), is(NULL),
579 globalIntVarCount(0), globalStrVarCount(0), polyphonicIntVarCount(0),
580 globalIntMemory(NULL), globalStrMemory(NULL), requiredMaxStackSize(-1),
581 functionProvider(parent), execContext(NULL)
582 {
583 }
584 virtual ~ParserContext();
585 VariableRef globalVar(const String& name);
586 IntVariableRef globalIntVar(const String& name);
587 StringVariableRef globalStrVar(const String& name);
588 VariableRef variableByName(const String& name);
589 void addErr(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt);
590 void addWrn(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt);
591 void createScanner(std::istream* is);
592 void destroyScanner();
593 bool setPreprocessorCondition(const char* name);
594 bool resetPreprocessorCondition(const char* name);
595 bool isPreprocessorConditionSet(const char* name);
596 std::vector<ParserIssue> issues() const OVERRIDE;
597 std::vector<ParserIssue> errors() const OVERRIDE;
598 std::vector<ParserIssue> warnings() const OVERRIDE;
599 VMEventHandler* eventHandler(uint index) OVERRIDE;
600 VMEventHandler* eventHandlerByName(const String& name) OVERRIDE;
601 void registerBuiltInConstIntVariables(const std::map<String,int>& vars);
602 void registerBuiltInIntVariables(const std::map<String,VMIntRelPtr*>& vars);
603 void registerBuiltInIntArrayVariables(const std::map<String,VMInt8Array*>& vars);
604 };
605
606 class ExecContext : public VMExecContext {
607 public:
608 struct StackFrame {
609 Statement* statement;
610 int subindex;
611
612 StackFrame() {
613 statement = NULL;
614 subindex = -1;
615 }
616 };
617
618 ArrayList<int> polyphonicIntMemory;
619 VMExecStatus_t status;
620 ArrayList<StackFrame> stack;
621 int stackFrame;
622 int suspendMicroseconds;
623
624 ExecContext() :
625 status(VM_EXEC_NOT_RUNNING), stackFrame(-1), suspendMicroseconds(0) {}
626
627 virtual ~ExecContext() {}
628
629 inline void pushStack(Statement* stmt) {
630 stackFrame++;
631 //printf("pushStack() -> %d\n", stackFrame);
632 if (stackFrame >= stack.size()) return;
633 stack[stackFrame].statement = stmt;
634 stack[stackFrame].subindex = 0;
635 }
636
637 inline void popStack() {
638 stack[stackFrame].statement = NULL;
639 stack[stackFrame].subindex = -1;
640 stackFrame--;
641 //printf("popStack() -> %d\n", stackFrame);
642 }
643
644 inline void reset() {
645 stack[0].statement = NULL;
646 stack[0].subindex = -1;
647 stackFrame = -1;
648 }
649
650 int suspensionTimeMicroseconds() const OVERRIDE {
651 return suspendMicroseconds;
652 }
653 };
654
655 } // namespace LinuxSampler
656
657 #endif // LS_INSTRPARSERTREE_H

  ViewVC Help
Powered by ViewVC