1 /*                                                              -*- c++ -*-
2  *
3  * Copyright (c) 2014 - 2019 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 <string.h> // for memset()
24 #include <assert.h>
25 #include "../common/global.h"
26 #include "../common/Ref.h"
27 #include "../common/ArrayList.h"
28 #include "../common/optional.h"
29 #include "common.h"
30 
31 namespace LinuxSampler {
32 
33 class ParserContext;
34 class ExecContext;
35 
36 enum StmtType_t {
37     STMT_LEAF,
38     STMT_LIST,
39     STMT_BRANCH,
40     STMT_LOOP,
41     STMT_SYNC,
42     STMT_NOOP,
43 };
44 
45 enum Qualifier_t {
46     QUALIFIER_NONE = 0,
47     QUALIFIER_CONST = 1,
48     QUALIFIER_POLYPHONIC = (1<<1),
49     QUALIFIER_PATCH = (1<<2),
50 };
51 
52 struct PatchVarBlock {
53     CodeBlock nameBlock;
54     optional<CodeBlock> exprBlock;
55 };
56 
57 /**
58  * Convenience function used for retrieving the (assumed) data type of a given
59  * script variable name.
60  *
61  * @param name - some script variable name (e.g. "$foo")
62  * @return variable's assumed data type (e.g. INT_EXPR for example above)
63  */
exprTypeOfVarName(const String & name)64 inline ExprType_t exprTypeOfVarName(const String& name) {
65     if (name.empty()) return (ExprType_t) -1;
66     const char prefix = name[0];
67     switch (prefix) {
68         case '$': return INT_EXPR;
69         case '%': return INT_ARR_EXPR;
70         case '~': return REAL_EXPR;
71         case '?': return REAL_ARR_EXPR;
72         case '@': return STRING_EXPR;
73         case '!': return STRING_ARR_EXPR;
74     }
75     return (ExprType_t) -1;
76 }
77 
scalarTypeOfArray(ExprType_t arrayType)78 inline ExprType_t scalarTypeOfArray(ExprType_t arrayType) {
79     if (arrayType == INT_ARR_EXPR) return INT_EXPR;
80     if (arrayType == REAL_ARR_EXPR) return REAL_EXPR;
81     if (arrayType == STRING_ARR_EXPR) return STRING_EXPR;
82     assert(false);
83     return EMPTY_EXPR; // just to shut up the compiler
84 }
85 
qualifierStr(Qualifier_t qualifier)86 inline String qualifierStr(Qualifier_t qualifier) {
87     switch (qualifier) {
88         case QUALIFIER_NONE:          return "none";
89         case QUALIFIER_CONST:         return "const";
90         case QUALIFIER_POLYPHONIC:    return "polyphonic";
91         case QUALIFIER_PATCH:         return "patch";
92     }
93     return "unknown";
94 }
95 
96 /**
97  * Used by parser for parser error messages to provide a text with all data
98  * types accepted by the given built-in function @a fn for the respective
99  * function argument @a iArg.
100  */
101 String acceptedArgTypesStr(VMFunction* fn, vmint iArg);
102 
103 class Node {
104 public:
105     Node();
106     virtual ~Node();
107     virtual void dump(int level = 0) = 0;
108     virtual bool isPolyphonic() const = 0;
109     void printIndents(int n);
110 };
111 typedef Ref<Node> NodeRef;
112 
113 class Expression : virtual public VMExpr, virtual public Node {
114 public:
115     virtual ExprType_t exprType() const = 0;
116     virtual bool isConstExpr() const = 0;
117     virtual String evalCastToStr() = 0;
118 };
119 typedef Ref<Expression,Node> ExpressionRef;
120 
121 class Unit : virtual public VMUnit, virtual public Node {
122     StdUnit_t unit;
123 public:
Unit(StdUnit_t type)124     Unit(StdUnit_t type) : unit(type) {}
unitType()125     StdUnit_t unitType() const OVERRIDE { return unit; }
126     static vmint convIntToUnitFactor(vmint iValue, VMUnit* srcUnit, VMUnit* dstUnit);
127     static vmint convIntToUnitFactor(vmint iValue, vmfloat srcFactor, vmfloat dstFactor);
128     static vmfloat convRealToUnitFactor(vmfloat fValue, VMUnit* srcUnit, VMUnit* dstUnit);
129     static vmfloat convRealToUnitFactor(vmfloat fValue, vmfloat srcFactor, vmfloat dstFactor);
130 };
131 typedef Ref<Unit,Node> UnitRef;
132 
133 class NumberExpr : virtual public Unit, virtual public VMNumberExpr, virtual public Expression {
134 public:
135 };
136 typedef Ref<NumberExpr,Node> NumberExprRef;
137 
138 class IntExpr : virtual public NumberExpr, virtual public VMIntExpr {
139 public:
exprType()140     ExprType_t exprType() const OVERRIDE { return INT_EXPR; }
141     vmint evalIntToUnitFactor(vmfloat unitFactor);
142     String evalCastToStr() OVERRIDE;
143 };
144 typedef Ref<IntExpr,Node> IntExprRef;
145 
146 class RealExpr : virtual public NumberExpr, virtual public VMRealExpr  {
147 public:
exprType()148     ExprType_t exprType() const OVERRIDE { return REAL_EXPR; }
149     vmfloat evalRealToUnitFactor(vmfloat unitFactor);
150     String evalCastToStr() OVERRIDE;
151 };
152 typedef Ref<RealExpr,Node> RealExprRef;
153 
154 class ArrayExpr : virtual public VMArrayExpr, virtual public Expression {
155 public:
156 };
157 typedef Ref<ArrayExpr,Node> ArrayExprRef;
158 
159 class IntArrayExpr : virtual public VMIntArrayExpr, virtual public ArrayExpr {
160 public:
exprType()161     ExprType_t exprType() const OVERRIDE { return INT_ARR_EXPR; }
162     String evalCastToStr() OVERRIDE;
163 };
164 typedef Ref<IntArrayExpr,Node> IntArrayExprRef;
165 
166 class RealArrayExpr : virtual public VMRealArrayExpr, virtual public ArrayExpr {
167 public:
exprType()168     ExprType_t exprType() const OVERRIDE { return REAL_ARR_EXPR; }
169     String evalCastToStr() OVERRIDE;
170 };
171 typedef Ref<RealArrayExpr,Node> RealArrayExprRef;
172 
173 class StringExpr : virtual public VMStringExpr, virtual public Expression {
174 public:
exprType()175     ExprType_t exprType() const OVERRIDE { return STRING_EXPR; }
evalCastToStr()176     String evalCastToStr() OVERRIDE { return evalStr(); }
177 };
178 typedef Ref<StringExpr,Node> StringExprRef;
179 
180 struct IntLitDef {
181     vmint value; //NOTE: sequence matters! Since this is usually initialized with VMIntExpr::evalInt() it should be before member unitFactor, since the latter is usually initialized with VMIntExpr::unitFactor() which does not evaluate the expression.
182     vmfloat unitFactor = VM_NO_FACTOR;
183     StdUnit_t unitType = VM_NO_UNIT;
184     bool isFinal;
185 };
186 
187 class IntLiteral FINAL : public IntExpr {
188     bool finalVal;
189     vmfloat unitPrefixFactor;
190     vmint value;
191 public:
192     IntLiteral(const IntLitDef& def);
193     vmint evalInt() OVERRIDE;
unitFactor()194     vmfloat unitFactor() const OVERRIDE { return unitPrefixFactor; }
195     void dump(int level = 0) OVERRIDE;
isConstExpr()196     bool isConstExpr() const OVERRIDE { return true; }
isPolyphonic()197     bool isPolyphonic() const OVERRIDE { return false; }
isFinal()198     bool isFinal() const OVERRIDE { return finalVal; }
199 };
200 typedef Ref<IntLiteral,Node> IntLiteralRef;
201 
202 struct RealLitDef {
203     vmfloat value; //NOTE: sequence matters! Since this is usually initialized with VMRealExpr::evalReal() it should be before member unitFactor, since the latter is usually initialized with VMRealExpr::unitFactor() which does not evaluate the expression.
204     vmfloat unitFactor = VM_NO_FACTOR;
205     StdUnit_t unitType = VM_NO_UNIT;
206     bool isFinal;
207 };
208 
209 class RealLiteral FINAL : public RealExpr {
210     bool finalVal;
211     vmfloat unitPrefixFactor;
212     vmfloat value;
213 public:
214     RealLiteral(const RealLitDef& def);
215     vmfloat evalReal() OVERRIDE;
unitFactor()216     vmfloat unitFactor() const OVERRIDE { return unitPrefixFactor; }
217     void dump(int level = 0) OVERRIDE;
isConstExpr()218     bool isConstExpr() const OVERRIDE { return true; }
isPolyphonic()219     bool isPolyphonic() const OVERRIDE { return false; }
isFinal()220     bool isFinal() const OVERRIDE { return finalVal; }
221 };
222 typedef Ref<RealLiteral,Node> RealLiteralRef;
223 
224 class StringLiteral FINAL : public StringExpr {
225     String value;
226 public:
StringLiteral(const String & value)227     StringLiteral(const String& value) : value(value) { }
isConstExpr()228     bool isConstExpr() const OVERRIDE { return true; }
229     void dump(int level = 0) OVERRIDE;
evalStr()230     String evalStr() OVERRIDE { return value; }
isPolyphonic()231     bool isPolyphonic() const OVERRIDE { return false; }
232 };
233 typedef Ref<StringLiteral,Node> StringLiteralRef;
234 
235 class Args FINAL : virtual public VMFnArgs, virtual public Node {
236 public:
237     std::vector<ExpressionRef> args;
add(ExpressionRef arg)238     void add(ExpressionRef arg) { args.push_back(arg); }
239     void dump(int level = 0) OVERRIDE;
argsCount()240     vmint argsCount() const OVERRIDE { return (vmint) args.size(); }
arg(vmint i)241     VMExpr* arg(vmint i) OVERRIDE { return (i >= 0 && i < argsCount()) ? &*args.at(i) : NULL; }
242     bool isPolyphonic() const OVERRIDE;
243 };
244 typedef Ref<Args,Node> ArgsRef;
245 
246 struct VariableDecl {
247     ParserContext* ctx;
248     bool isPolyphonic;
249     bool isConst;
250     vmint elements = 1;
251     vmint memPos;
252     vmint unitFactorMemPos;
253     StdUnit_t unitType = VM_NO_UNIT;
254     bool isFinal;
255 };
256 
257 class Variable : virtual public VMVariable, virtual public Expression {
258 public:
isConstExpr()259     bool isConstExpr() const OVERRIDE { return bConst; }
isAssignable()260     bool isAssignable() const OVERRIDE { return !bConst; }
261     virtual void assign(Expression* expr) = 0;
assignExpr(VMExpr * expr)262     void assignExpr(VMExpr* expr) OVERRIDE { Expression* e = dynamic_cast<Expression*>(expr); if (e) assign(e); }
263 protected:
264     Variable(const VariableDecl& decl);
265 
266     ParserContext* context;
267     vmint memPos;
268     bool bConst;
269 };
270 typedef Ref<Variable,Node> VariableRef;
271 
272 class NumberVariable : public Variable, virtual public NumberExpr {
273     bool polyphonic;
274     bool finalVal;
275 protected:
276     vmint unitFactorMemPos;
277 public:
isPolyphonic()278     bool isPolyphonic() const OVERRIDE { return polyphonic; }
isFinal()279     bool isFinal() const OVERRIDE { return finalVal; }
280     vmfloat unitFactor() const OVERRIDE;
281 protected:
282     NumberVariable(const VariableDecl& decl);
283 };
284 typedef Ref<NumberVariable,Node> NumberVariableRef;
285 
286 class IntVariable : public NumberVariable, virtual public IntExpr {
287 public:
288     IntVariable(const VariableDecl& decl);
289     void assign(Expression* expr) OVERRIDE;
290     vmint evalInt() OVERRIDE;
291     void dump(int level = 0) OVERRIDE;
292 };
293 typedef Ref<IntVariable,Node> IntVariableRef;
294 
295 class RealVariable : public NumberVariable, virtual public RealExpr {
296 public:
297     RealVariable(const VariableDecl& decl);
298     void assign(Expression* expr) OVERRIDE;
299     vmfloat evalReal() OVERRIDE;
300     void dump(int level = 0) OVERRIDE;
301 };
302 typedef Ref<RealVariable,Node> RealVariableRef;
303 
304 struct IntVarDef /* : VariableDecl*/ { //NOTE: derived, aggregate initializer-lists requires C++17
305     // additions for RealVarDef
306     vmint value = 0; //NOTE: sequence matters! Since this is usually initialized with VMIntExpr::evalInt() it should be before member unitFactor, since the latter is usually initialized with VMIntExpr::unitFactor() which does not evaluate the expression.
307     vmfloat unitFactor = VM_NO_FACTOR;
308     // copied from VariableDecl
309     ParserContext* ctx;
310     bool isPolyphonic;
311     bool isConst;
312     vmint elements = 1;
313     vmint memPos;
314     vmint unitFactorMemPos;
315     StdUnit_t unitType = VM_NO_UNIT;
316     bool isFinal;
317 };
318 
319 class ConstIntVariable FINAL : public IntVariable {
320     vmfloat unitPrefixFactor;
321     vmint value;
322 public:
323     ConstIntVariable(const IntVarDef& def);
324     void assign(Expression* expr) OVERRIDE;
325     vmint evalInt() OVERRIDE;
unitFactor()326     vmfloat unitFactor() const OVERRIDE { return unitPrefixFactor; }
327     void dump(int level = 0) OVERRIDE;
328 };
329 typedef Ref<ConstIntVariable,Node> ConstIntVariableRef;
330 
331 struct RealVarDef /* : VariableDecl*/ { //NOTE: derived, aggregate initializer-lists requires C++17
332     // additions for RealVarDef
333     vmfloat value = vmfloat(0); //NOTE: sequence matters! Since this is usually initialized with VMRealExpr::evalReal() it should be before member unitFactor, since the latter is usually initialized with VMRealExpr::unitFactor() which does not evaluate the expression.
334     vmfloat unitFactor = VM_NO_FACTOR;
335     // copied from VariableDecl
336     ParserContext* ctx;
337     bool isPolyphonic;
338     bool isConst;
339     vmint elements = 1;
340     vmint memPos;
341     vmint unitFactorMemPos;
342     StdUnit_t unitType = VM_NO_UNIT;
343     bool isFinal;
344 };
345 
346 class ConstRealVariable FINAL : public RealVariable {
347     vmfloat unitPrefixFactor;
348     vmfloat value;
349 public:
350     ConstRealVariable(const RealVarDef& def);
351     void assign(Expression* expr) OVERRIDE;
352     vmfloat evalReal() OVERRIDE;
unitFactor()353     vmfloat unitFactor() const OVERRIDE { return unitPrefixFactor; }
354     void dump(int level = 0) OVERRIDE;
355 };
356 typedef Ref<ConstRealVariable,Node> ConstRealVariableRef;
357 
358 class BuiltInIntVariable FINAL : public IntVariable {
359     String name;
360     VMIntPtr* ptr;
361 public:
362     BuiltInIntVariable(const String& name, VMIntPtr* ptr);
isAssignable()363     bool isAssignable() const OVERRIDE { return ptr->isAssignable(); }
364     void assign(Expression* expr) OVERRIDE;
365     vmint evalInt() OVERRIDE;
unitFactor()366     vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; }
367     void dump(int level = 0) OVERRIDE;
368 };
369 typedef Ref<BuiltInIntVariable,Node> BuiltInIntVariableRef;
370 
371 class PolyphonicIntVariable FINAL : public IntVariable {
372 public:
373     PolyphonicIntVariable(const VariableDecl& decl);
374     void dump(int level = 0) OVERRIDE;
375 };
376 typedef Ref<PolyphonicIntVariable,Node> PolyphonicIntVariableRef;
377 
378 class PolyphonicRealVariable FINAL : public RealVariable {
379 public:
380     PolyphonicRealVariable(const VariableDecl& decl);
381     void dump(int level = 0) OVERRIDE;
382 };
383 typedef Ref<PolyphonicRealVariable,Node> PolyphonicRealVariableRef;
384 
385 class IntArrayVariable : public Variable, virtual public IntArrayExpr {
386     ArrayList<vmint> values;
387     ArrayList<vmfloat> unitFactors;
388 public:
389     IntArrayVariable(ParserContext* ctx, vmint size);
390     IntArrayVariable(ParserContext* ctx, vmint size, ArgsRef values, bool _bConst = false);
assign(Expression * expr)391     void assign(Expression* expr) OVERRIDE {} // ignore scalar assignment
exprType()392     ExprType_t exprType() const OVERRIDE { return INT_ARR_EXPR; }
arraySize()393     virtual vmint arraySize() const OVERRIDE { return values.size(); }
394     virtual vmint evalIntElement(vmuint i) OVERRIDE;
395     virtual void assignIntElement(vmuint i, vmint value) OVERRIDE;
396     vmfloat unitFactorOfElement(vmuint i) const OVERRIDE;
397     void assignElementUnitFactor(vmuint i, vmfloat factor) OVERRIDE;
398     void dump(int level = 0) OVERRIDE;
isPolyphonic()399     bool isPolyphonic() const OVERRIDE { return false; }
400 protected:
401     IntArrayVariable(ParserContext* ctx, bool bConst);
402 };
403 typedef Ref<IntArrayVariable,Node> IntArrayVariableRef;
404 
405 class RealArrayVariable FINAL : public Variable, virtual public RealArrayExpr {
406     ArrayList<vmfloat> values;
407     ArrayList<vmfloat> unitFactors;
408 public:
409     RealArrayVariable(ParserContext* ctx, vmint size);
410     RealArrayVariable(ParserContext* ctx, vmint size, ArgsRef values, bool _bConst = false);
assign(Expression * expr)411     void assign(Expression* expr) OVERRIDE {} // ignore scalar assignment
exprType()412     ExprType_t exprType() const OVERRIDE { return REAL_ARR_EXPR; }
arraySize()413     virtual vmint arraySize() const OVERRIDE { return values.size(); }
414     virtual vmfloat evalRealElement(vmuint i) OVERRIDE;
415     virtual void assignRealElement(vmuint i, vmfloat value) OVERRIDE;
416     vmfloat unitFactorOfElement(vmuint i) const OVERRIDE;
417     void assignElementUnitFactor(vmuint i, vmfloat factor) OVERRIDE;
418     void dump(int level = 0) OVERRIDE;
isPolyphonic()419     bool isPolyphonic() const OVERRIDE { return false; }
420 protected:
421     RealArrayVariable(ParserContext* ctx, bool bConst);
422 };
423 typedef Ref<RealArrayVariable,Node> RealArrayVariableRef;
424 
425 class BuiltInIntArrayVariable FINAL : public IntArrayVariable {
426     String name;
427     VMInt8Array* array;
428 public:
429     BuiltInIntArrayVariable(const String& name, VMInt8Array* array);
arraySize()430     vmint arraySize() const OVERRIDE { return array->size; }
431     vmint evalIntElement(vmuint i) OVERRIDE;
432     void assignIntElement(vmuint i, vmint value) OVERRIDE;
unitFactorOfElement(vmuint i)433     vmfloat unitFactorOfElement(vmuint i) const OVERRIDE { return VM_NO_FACTOR; }
assignElementUnitFactor(vmuint i,vmfloat factor)434     void assignElementUnitFactor(vmuint i, vmfloat factor) OVERRIDE {}
isAssignable()435     bool isAssignable() const OVERRIDE { return !array->readonly; }
436     void dump(int level = 0) OVERRIDE;
437 };
438 typedef Ref<BuiltInIntArrayVariable,Node> BuiltInIntArrayVariableRef;
439 
440 class IntArrayElement FINAL : public IntVariable {
441     IntArrayExprRef array;
442     IntExprRef index;
443     vmint currentIndex;
444 public:
445     IntArrayElement(IntArrayExprRef array, IntExprRef arrayIndex);
446     void assign(Expression* expr) OVERRIDE;
447     vmint evalInt() OVERRIDE;
448     vmfloat unitFactor() const OVERRIDE;
449     void dump(int level = 0) OVERRIDE;
450 };
451 typedef Ref<IntArrayElement,Node> IntArrayElementRef;
452 
453 class RealArrayElement FINAL : public RealVariable {
454     RealArrayExprRef array;
455     IntExprRef index;
456     vmint currentIndex;
457 public:
458     RealArrayElement(RealArrayExprRef array, IntExprRef arrayIndex);
459     void assign(Expression* expr) OVERRIDE;
460     vmfloat evalReal() OVERRIDE;
461     vmfloat unitFactor() const OVERRIDE;
462     void dump(int level = 0) OVERRIDE;
463 };
464 typedef Ref<RealArrayElement,Node> RealArrayElementRef;
465 
466 class StringVariable : public Variable, virtual public StringExpr {
467 public:
468     StringVariable(ParserContext* ctx);
469     void assign(Expression* expr) OVERRIDE;
470     String evalStr() OVERRIDE;
471     void dump(int level = 0) OVERRIDE;
isPolyphonic()472     bool isPolyphonic() const OVERRIDE { return false; }
473 protected:
474     StringVariable(ParserContext* ctx, bool bConst);
475 };
476 typedef Ref<StringVariable,Node> StringVariableRef;
477 
478 class ConstStringVariable FINAL : public StringVariable {
479     String value;
480 public:
481     ConstStringVariable(ParserContext* ctx, String value = "");
482     void assign(Expression* expr) OVERRIDE;
483     String evalStr() OVERRIDE;
484     void dump(int level = 0) OVERRIDE;
485 };
486 typedef Ref<ConstStringVariable,Node> ConstStringVariableRef;
487 
488 class BinaryOp : virtual public Expression {
489 protected:
490     ExpressionRef lhs;
491     ExpressionRef rhs;
492 public:
BinaryOp(ExpressionRef lhs,ExpressionRef rhs)493     BinaryOp(ExpressionRef lhs, ExpressionRef rhs) : lhs(lhs), rhs(rhs) { }
isConstExpr()494     bool isConstExpr() const OVERRIDE { return lhs->isConstExpr() && rhs->isConstExpr(); }
isPolyphonic()495     bool isPolyphonic() const OVERRIDE { return lhs->isPolyphonic() || rhs->isPolyphonic(); }
496 };
497 typedef Ref<BinaryOp,Node> BinaryOpRef;
498 
499 class NumberBinaryOp : public BinaryOp, virtual public NumberExpr {
500 public:
NumberBinaryOp(NumberExprRef lhs,NumberExprRef rhs)501     NumberBinaryOp(NumberExprRef lhs, NumberExprRef rhs) : BinaryOp(lhs, rhs) { }
502     bool isFinal() const OVERRIDE;
503 };
504 typedef Ref<NumberBinaryOp,Node> NumberBinaryOpRef;
505 
506 class IntBinaryOp : public NumberBinaryOp, virtual public IntExpr {
507 public:
IntBinaryOp(IntExprRef lhs,IntExprRef rhs)508     IntBinaryOp(IntExprRef lhs, IntExprRef rhs) : NumberBinaryOp(lhs, rhs) { }
509 };
510 typedef Ref<IntBinaryOp,Node> IntBinaryOpRef;
511 
512 class VaritypeScalarBinaryOp : public NumberBinaryOp, virtual public IntExpr, virtual public RealExpr {
513 public:
VaritypeScalarBinaryOp(NumberExprRef lhs,NumberExprRef rhs)514     VaritypeScalarBinaryOp(NumberExprRef lhs, NumberExprRef rhs) : NumberBinaryOp(lhs, rhs) { }
515     ExprType_t exprType() const OVERRIDE;
516     String evalCastToStr() OVERRIDE;
517 };
518 typedef Ref<VaritypeScalarBinaryOp,Node> VaritypeScalarBinaryOpRef;
519 
520 class Add FINAL : public VaritypeScalarBinaryOp {
521 public:
522     Add(NumberExprRef lhs, NumberExprRef rhs);
523     vmint evalInt() OVERRIDE;
524     vmfloat evalReal() OVERRIDE;
525     vmfloat unitFactor() const OVERRIDE;
526     void dump(int level = 0) OVERRIDE;
527 };
528 typedef Ref<Add,Node> AddRef;
529 
530 class Sub FINAL : public VaritypeScalarBinaryOp {
531 public:
532     Sub(NumberExprRef lhs, NumberExprRef rhs);
533     vmint evalInt() OVERRIDE;
534     vmfloat evalReal() OVERRIDE;
535     vmfloat unitFactor() const OVERRIDE;
536     void dump(int level = 0) OVERRIDE;
537 };
538 typedef Ref<Sub,Node> SubRef;
539 
540 class Mul FINAL : public VaritypeScalarBinaryOp {
541 public:
542     Mul(NumberExprRef lhs, NumberExprRef rhs);
543     vmint evalInt() OVERRIDE;
544     vmfloat evalReal() OVERRIDE;
545     vmfloat unitFactor() const OVERRIDE;
546     void dump(int level = 0) OVERRIDE;
547 };
548 typedef Ref<Mul,Node> MulRef;
549 
550 class Div FINAL : public VaritypeScalarBinaryOp {
551 public:
552     Div(NumberExprRef lhs, NumberExprRef rhs);
553     vmint evalInt() OVERRIDE;
554     vmfloat evalReal() OVERRIDE;
555     void dump(int level = 0) OVERRIDE;
556     vmfloat unitFactor() const OVERRIDE;
557 };
558 typedef Ref<Div,Node> DivRef;
559 
560 class Mod FINAL : public IntBinaryOp {
561 public:
Mod(IntExprRef lhs,IntExprRef rhs)562     Mod(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs, rhs), Unit(VM_NO_UNIT) { }
563     vmint evalInt() OVERRIDE;
unitFactor()564     vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; }
565     void dump(int level = 0) OVERRIDE;
566 };
567 typedef Ref<Mod,Node> ModRef;
568 
569 class Statement : virtual public Node {
570 public:
571     virtual StmtType_t statementType() const = 0;
572 };
573 typedef Ref<Statement,Node> StatementRef;
574 
575 // Just used by parser to avoid "not a statement" parser warning, will be
576 // filtered out by parser. So it will not be part of the VM tree after parsing.
577 class NoOperation FINAL : public Statement {
578 public:
NoOperation()579     NoOperation() : Statement() {}
statementType()580     StmtType_t statementType() const OVERRIDE { return STMT_NOOP; }
581     void dump(int level = 0) OVERRIDE {}
isPolyphonic()582     bool isPolyphonic() const OVERRIDE { return false; }
583 };
584 typedef Ref<NoOperation,Node> NoOperationRef;
585 
586 bool isNoOperation(StatementRef statement);
587 
588 class LeafStatement : public Statement {
589 public:
590     virtual StmtFlags_t exec() = 0;
statementType()591     StmtType_t statementType() const OVERRIDE { return STMT_LEAF; }
592 };
593 typedef Ref<LeafStatement,Node> LeafStatementRef;
594 
595 class Statements : public Statement {
596     std::vector<StatementRef> args;
597 public:
add(StatementRef arg)598     void add(StatementRef arg) { args.push_back(arg); }
599     void dump(int level = 0) OVERRIDE;
statementType()600     StmtType_t statementType() const OVERRIDE { return STMT_LIST; }
601     virtual Statement* statement(uint i);
602     bool isPolyphonic() const OVERRIDE;
603 };
604 typedef Ref<Statements,Node> StatementsRef;
605 
606 class BranchStatement : public Statement {
607 public:
statementType()608     StmtType_t statementType() const OVERRIDE { return STMT_BRANCH; }
609     virtual vmint evalBranch() = 0;
610     virtual Statements* branch(vmuint i) const = 0;
611 };
612 
613 class DynamicVariableCall FINAL : public Variable, virtual public IntExpr, virtual public StringExpr, virtual public IntArrayExpr {
614     VMDynVar* dynVar;
615     String varName;
616 public:
617     DynamicVariableCall(const String& name, ParserContext* ctx, VMDynVar* v);
exprType()618     ExprType_t exprType() const OVERRIDE { return dynVar->exprType(); }
isConstExpr()619     bool isConstExpr() const OVERRIDE { return dynVar->isConstExpr(); }
isAssignable()620     bool isAssignable() const OVERRIDE { return dynVar->isAssignable(); }
isPolyphonic()621     bool isPolyphonic() const OVERRIDE { return false; }
assign(Expression * expr)622     void assign(Expression* expr) OVERRIDE { dynVar->assignExpr(expr); }
asIntArray()623     VMIntArrayExpr* asIntArray() const OVERRIDE { return dynVar->asIntArray(); }
624     vmint evalInt() OVERRIDE;
625     String evalStr() OVERRIDE;
626     String evalCastToStr() OVERRIDE;
arraySize()627     vmint arraySize() const OVERRIDE { return dynVar->asIntArray()->arraySize(); }
evalIntElement(vmuint i)628     vmint evalIntElement(vmuint i) OVERRIDE { return dynVar->asIntArray()->evalIntElement(i); }
assignIntElement(vmuint i,vmint value)629     void assignIntElement(vmuint i, vmint value) OVERRIDE { return dynVar->asIntArray()->assignIntElement(i, value); }
unitFactorOfElement(vmuint i)630     vmfloat unitFactorOfElement(vmuint i) const OVERRIDE { return VM_NO_FACTOR; }
assignElementUnitFactor(vmuint i,vmfloat factor)631     void assignElementUnitFactor(vmuint i, vmfloat factor) OVERRIDE {}
632     void dump(int level = 0) OVERRIDE;
unitFactor()633     vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; }
isFinal()634     bool isFinal() const OVERRIDE { return false; }
635 };
636 typedef Ref<DynamicVariableCall,Node> DynamicVariableCallRef;
637 
638 class FunctionCall : virtual public LeafStatement, virtual public IntExpr, virtual public RealExpr, virtual public StringExpr, virtual public ArrayExpr {
639     String functionName;
640     ArgsRef args;
641     VMFunction* fn;
642     VMFnResult* result;
643 public:
644     FunctionCall(const char* function, ArgsRef args, VMFunction* fn);
645     virtual ~FunctionCall();
646     void dump(int level = 0) OVERRIDE;
647     StmtFlags_t exec() OVERRIDE;
648     vmint evalInt() OVERRIDE;
649     vmfloat evalReal() OVERRIDE;
650     vmint arraySize() const OVERRIDE;
651     VMIntArrayExpr* asIntArray() const OVERRIDE;
652     VMRealArrayExpr* asRealArray() const OVERRIDE;
653     String evalStr() OVERRIDE;
isConstExpr()654     bool isConstExpr() const OVERRIDE { return false; }
655     ExprType_t exprType() const OVERRIDE;
656     String evalCastToStr() OVERRIDE;
isPolyphonic()657     bool isPolyphonic() const OVERRIDE { return args->isPolyphonic(); }
658     vmfloat unitFactor() const OVERRIDE;
659     bool isFinal() const OVERRIDE;
660 protected:
661     VMFnResult* execVMFn();
662 };
663 typedef Ref<FunctionCall,Node> FunctionCallRef;
664 
665 class NoFunctionCall FINAL : public FunctionCall {
666 public:
NoFunctionCall()667     NoFunctionCall() : FunctionCall("nothing", new Args, NULL), Unit(VM_NO_UNIT) {}
statementType()668     StmtType_t statementType() const OVERRIDE { return STMT_NOOP; }
669 };
670 typedef Ref<NoFunctionCall,Node> NoFunctionCallRef;
671 
672 class Subroutine : public Statements {
673     StatementsRef statements;
674 public:
675     Subroutine(StatementsRef statements);
statement(uint i)676     Statement* statement(uint i) OVERRIDE { return statements->statement(i); }
677     void dump(int level = 0) OVERRIDE;
678 };
679 typedef Ref<Subroutine,Node> SubroutineRef;
680 
681 class UserFunction : public Subroutine {
682 public:
683     UserFunction(StatementsRef statements);
684 };
685 typedef Ref<UserFunction,Node> UserFunctionRef;
686 
687 class EventHandler : public Subroutine, virtual public VMEventHandler {
688     bool usingPolyphonics;
689 public:
690     void dump(int level = 0) OVERRIDE;
691     EventHandler(StatementsRef statements);
isPolyphonic()692     bool isPolyphonic() const OVERRIDE { return usingPolyphonics; }
693 };
694 typedef Ref<EventHandler,Node> EventHandlerRef;
695 
696 class OnNote FINAL : public EventHandler {
697 public:
OnNote(StatementsRef statements)698     OnNote(StatementsRef statements) : EventHandler(statements) {}
eventHandlerType()699     VMEventHandlerType_t eventHandlerType() const OVERRIDE { return VM_EVENT_HANDLER_NOTE; }
eventHandlerName()700     String eventHandlerName() const OVERRIDE { return "note"; }
701 };
702 typedef Ref<OnNote,Node> OnNoteRef;
703 
704 class OnInit FINAL : public EventHandler {
705 public:
OnInit(StatementsRef statements)706     OnInit(StatementsRef statements) : EventHandler(statements) {}
eventHandlerType()707     VMEventHandlerType_t eventHandlerType() const OVERRIDE { return VM_EVENT_HANDLER_INIT; }
eventHandlerName()708     String eventHandlerName() const OVERRIDE { return "init"; }
709 };
710 typedef Ref<OnInit,Node> OnInitRef;
711 
712 class OnRelease FINAL : public EventHandler {
713 public:
OnRelease(StatementsRef statements)714     OnRelease(StatementsRef statements) : EventHandler(statements) {}
eventHandlerType()715     VMEventHandlerType_t eventHandlerType() const OVERRIDE { return VM_EVENT_HANDLER_RELEASE; }
eventHandlerName()716     String eventHandlerName() const OVERRIDE { return "release"; }
717 };
718 typedef Ref<OnRelease,Node> OnReleaseRef;
719 
720 class OnController FINAL : public EventHandler {
721 public:
OnController(StatementsRef statements)722     OnController(StatementsRef statements) : EventHandler(statements) {}
eventHandlerType()723     VMEventHandlerType_t eventHandlerType() const OVERRIDE { return VM_EVENT_HANDLER_CONTROLLER; }
eventHandlerName()724     String eventHandlerName() const OVERRIDE { return "controller"; }
725 };
726 typedef Ref<OnController,Node> OnControllerRef;
727 
728 class OnRpn FINAL : public EventHandler {
729 public:
OnRpn(StatementsRef statements)730     OnRpn(StatementsRef statements) : EventHandler(statements) {}
eventHandlerType()731     VMEventHandlerType_t eventHandlerType() const OVERRIDE { return VM_EVENT_HANDLER_RPN; }
eventHandlerName()732     String eventHandlerName() const OVERRIDE { return "rpn"; }
733 };
734 typedef Ref<OnRpn,Node> OnRpnRef;
735 
736 class OnNrpn FINAL : public EventHandler {
737 public:
OnNrpn(StatementsRef statements)738     OnNrpn(StatementsRef statements) : EventHandler(statements) {}
eventHandlerType()739     VMEventHandlerType_t eventHandlerType() const OVERRIDE { return VM_EVENT_HANDLER_NRPN; }
eventHandlerName()740     String eventHandlerName() const OVERRIDE { return "nrpn"; }
741 };
742 typedef Ref<OnNrpn,Node> OnNrpnRef;
743 
744 class EventHandlers FINAL : virtual public Node {
745     std::vector<EventHandlerRef> args;
746 public:
747     EventHandlers();
748     ~EventHandlers();
749     void add(EventHandlerRef arg);
750     void dump(int level = 0) OVERRIDE;
751     EventHandler* eventHandlerByName(const String& name) const;
752     EventHandler* eventHandler(uint index) const;
size()753     inline uint size() const { return (int) args.size(); }
754     bool isPolyphonic() const OVERRIDE;
755 };
756 typedef Ref<EventHandlers,Node> EventHandlersRef;
757 
758 class Assignment FINAL : public LeafStatement {
759 protected:
760     VariableRef variable;
761     ExpressionRef value;
762 public:
763     Assignment(VariableRef variable, ExpressionRef value);
764     void dump(int level = 0) OVERRIDE;
765     StmtFlags_t exec() OVERRIDE;
isPolyphonic()766     bool isPolyphonic() const OVERRIDE { return (variable && variable->isPolyphonic()) || (value && value->isPolyphonic()); }
767 };
768 typedef Ref<Assignment,Node> AssignmentRef;
769 
770 class If FINAL : public BranchStatement {
771     IntExprRef condition;
772     StatementsRef ifStatements;
773     StatementsRef elseStatements;
774 public:
If(IntExprRef condition,StatementsRef ifStatements,StatementsRef elseStatements)775     If(IntExprRef condition, StatementsRef ifStatements, StatementsRef elseStatements) :
776         condition(condition), ifStatements(ifStatements), elseStatements(elseStatements) { }
If(IntExprRef condition,StatementsRef statements)777     If(IntExprRef condition, StatementsRef statements) :
778         condition(condition), ifStatements(statements) { }
779     void dump(int level = 0) OVERRIDE;
780     vmint evalBranch() OVERRIDE;
781     Statements* branch(vmuint i) const OVERRIDE;
782     bool isPolyphonic() const OVERRIDE;
783 };
784 typedef Ref<If,Node> IfRef;
785 
786 struct CaseBranch FINAL {
787     IntExprRef from;
788     IntExprRef to;
789     StatementsRef statements;
790 };
791 typedef std::vector<CaseBranch> CaseBranches;
792 
793 class SelectCase FINAL : public BranchStatement {
794     IntExprRef select;
795     CaseBranches branches;
796 public:
SelectCase(IntExprRef select,const CaseBranches & branches)797     SelectCase(IntExprRef select, const CaseBranches& branches) : select(select), branches(branches) { }
798     void dump(int level = 0) OVERRIDE;
799     vmint evalBranch() OVERRIDE;
800     Statements* branch(vmuint i) const OVERRIDE;
801     bool isPolyphonic() const OVERRIDE;
802 };
803 typedef Ref<SelectCase,Node> SelectCaseRef;
804 
805 class While FINAL : public Statement {
806     IntExprRef m_condition;
807     StatementsRef m_statements;
808 public:
While(IntExprRef condition,StatementsRef statements)809     While(IntExprRef condition, StatementsRef statements) :
810         m_condition(condition), m_statements(statements) {}
statementType()811     StmtType_t statementType() const OVERRIDE { return STMT_LOOP; }
812     void dump(int level = 0) OVERRIDE;
813     bool evalLoopStartCondition();
814     Statements* statements() const;
isPolyphonic()815     bool isPolyphonic() const OVERRIDE { return m_condition->isPolyphonic() || m_statements->isPolyphonic(); }
816 };
817 
818 class SyncBlock FINAL : public Statement {
819     StatementsRef m_statements;
820 public:
SyncBlock(StatementsRef statements)821     SyncBlock(StatementsRef statements) : m_statements(statements) {}
statementType()822     StmtType_t statementType() const OVERRIDE { return STMT_SYNC; }
823     void dump(int level = 0) OVERRIDE;
824     Statements* statements() const;
isPolyphonic()825     bool isPolyphonic() const OVERRIDE { return m_statements->isPolyphonic(); }
826 };
827 typedef Ref<SyncBlock,Node> SyncBlockRef;
828 
829 class Neg FINAL : virtual public IntExpr, virtual public RealExpr {
830     NumberExprRef expr;
831 public:
Neg(NumberExprRef expr)832     Neg(NumberExprRef expr) : Unit(expr->unitType()), expr(expr) { }
exprType()833     ExprType_t exprType() const OVERRIDE { return expr->exprType(); }
evalInt()834     vmint evalInt() OVERRIDE { return (expr) ? -(expr->asInt()->evalInt()) : 0; }
evalReal()835     vmfloat evalReal() OVERRIDE { return (expr) ? -(expr->asReal()->evalReal()) : vmfloat(0); }
836     String evalCastToStr() OVERRIDE;
837     void dump(int level = 0) OVERRIDE;
isConstExpr()838     bool isConstExpr() const OVERRIDE { return expr->isConstExpr(); }
isPolyphonic()839     bool isPolyphonic() const OVERRIDE { return expr->isPolyphonic(); }
unitFactor()840     vmfloat unitFactor() const OVERRIDE { return expr->unitFactor(); }
isFinal()841     bool isFinal() const OVERRIDE { return expr->isFinal(); }
842 };
843 typedef Ref<Neg,Node> NegRef;
844 
845 class ConcatString FINAL : public StringExpr {
846     ExpressionRef lhs;
847     ExpressionRef rhs;
848 public:
ConcatString(ExpressionRef lhs,ExpressionRef rhs)849     ConcatString(ExpressionRef lhs, ExpressionRef rhs) : lhs(lhs), rhs(rhs) {}
850     String evalStr() OVERRIDE;
851     void dump(int level = 0) OVERRIDE;
852     bool isConstExpr() const OVERRIDE;
isPolyphonic()853     bool isPolyphonic() const OVERRIDE { return lhs->isPolyphonic() || rhs->isPolyphonic(); }
854 };
855 typedef Ref<ConcatString,Node> ConcatStringRef;
856 
857 class Relation FINAL : public IntExpr {
858 public:
859     enum Type {
860         LESS_THAN,
861         GREATER_THAN,
862         LESS_OR_EQUAL,
863         GREATER_OR_EQUAL,
864         EQUAL,
865         NOT_EQUAL
866     };
867     Relation(ExpressionRef lhs, Type type, ExpressionRef rhs);
868     vmint evalInt() OVERRIDE;
869     void dump(int level = 0) OVERRIDE;
870     bool isConstExpr() const OVERRIDE;
isPolyphonic()871     bool isPolyphonic() const OVERRIDE { return lhs->isPolyphonic() || rhs->isPolyphonic(); }
unitFactor()872     vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; }
isFinal()873     bool isFinal() const OVERRIDE { return false; }
874 private:
875     ExpressionRef lhs;
876     ExpressionRef rhs;
877     Type type;
878 };
879 typedef Ref<Relation,Node> RelationRef;
880 
881 class Or FINAL : public IntBinaryOp {
882 public:
Or(IntExprRef lhs,IntExprRef rhs)883     Or(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs,rhs), Unit(VM_NO_UNIT) {}
884     vmint evalInt() OVERRIDE;
unitFactor()885     vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; }
886     void dump(int level = 0) OVERRIDE;
887 };
888 typedef Ref<Or,Node> OrRef;
889 
890 class BitwiseOr FINAL : public IntBinaryOp {
891 public:
BitwiseOr(IntExprRef lhs,IntExprRef rhs)892     BitwiseOr(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs,rhs), Unit(VM_NO_UNIT) {}
893     vmint evalInt() OVERRIDE;
894     void dump(int level = 0) OVERRIDE;
unitFactor()895     vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; }
896 };
897 typedef Ref<BitwiseOr,Node> BitwiseOrRef;
898 
899 class And FINAL : public IntBinaryOp {
900 public:
And(IntExprRef lhs,IntExprRef rhs)901     And(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs,rhs), Unit(VM_NO_UNIT) {}
902     vmint evalInt() OVERRIDE;
unitFactor()903     vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; }
904     void dump(int level = 0) OVERRIDE;
905 };
906 typedef Ref<And,Node> AndRef;
907 
908 class BitwiseAnd FINAL : public IntBinaryOp {
909 public:
BitwiseAnd(IntExprRef lhs,IntExprRef rhs)910     BitwiseAnd(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs,rhs), Unit(VM_NO_UNIT) {}
911     vmint evalInt() OVERRIDE;
912     void dump(int level = 0) OVERRIDE;
unitFactor()913     vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; }
914 };
915 typedef Ref<BitwiseAnd,Node> BitwiseAndRef;
916 
917 class Not FINAL : virtual public IntExpr {
918     IntExprRef expr;
919 public:
Not(IntExprRef expr)920     Not(IntExprRef expr) : Unit(VM_NO_UNIT), expr(expr) {}
evalInt()921     vmint evalInt() OVERRIDE { return !expr->evalInt(); }
922     void dump(int level = 0) OVERRIDE;
isConstExpr()923     bool isConstExpr() const OVERRIDE { return expr->isConstExpr(); }
isPolyphonic()924     bool isPolyphonic() const OVERRIDE { return expr->isPolyphonic(); }
unitFactor()925     vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; }
isFinal()926     bool isFinal() const OVERRIDE { return expr->isFinal(); }
927 };
928 typedef Ref<Not,Node> NotRef;
929 
930 class BitwiseNot FINAL : virtual public IntExpr {
931     IntExprRef expr;
932 public:
BitwiseNot(IntExprRef expr)933     BitwiseNot(IntExprRef expr) : Unit(VM_NO_UNIT), expr(expr) {}
evalInt()934     vmint evalInt() OVERRIDE { return ~expr->evalInt(); }
935     void dump(int level = 0) OVERRIDE;
isConstExpr()936     bool isConstExpr() const OVERRIDE { return expr->isConstExpr(); }
isPolyphonic()937     bool isPolyphonic() const OVERRIDE { return expr->isPolyphonic(); }
unitFactor()938     vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; }
isFinal()939     bool isFinal() const OVERRIDE { return expr->isFinal(); }
940 };
941 typedef Ref<BitwiseNot,Node> BitwiseNotRef;
942 
943 class Final FINAL : virtual public IntExpr, virtual public RealExpr {
944     NumberExprRef expr;
945 public:
Final(NumberExprRef expr)946     Final(NumberExprRef expr) : Unit(expr->unitType()), expr(expr) {}
exprType()947     ExprType_t exprType() const OVERRIDE { return expr->exprType(); }
evalInt()948     vmint evalInt() OVERRIDE { return expr->asInt()->evalInt(); }
evalReal()949     vmfloat evalReal() OVERRIDE { return expr->asReal()->evalReal(); }
950     String evalCastToStr() OVERRIDE;
951     void dump(int level = 0) OVERRIDE;
isConstExpr()952     bool isConstExpr() const OVERRIDE { return expr->isConstExpr(); }
isPolyphonic()953     bool isPolyphonic() const OVERRIDE { return expr->isPolyphonic(); }
unitFactor()954     vmfloat unitFactor() const OVERRIDE { return expr->unitFactor(); }
isFinal()955     bool isFinal() const OVERRIDE { return true; }
956 };
957 typedef Ref<Final,Node> FinalRef;
958 
959 class ParserContext FINAL : public VMParserContext {
960 public:
961     struct Error {
962         String txt;
963         int line;
964     };
965     typedef Error Warning;
966 
967     void* scanner;
968     std::istream* is;
969     int nbytes;
970     std::vector<ParserIssue> vErrors;
971     std::vector<ParserIssue> vWarnings;
972     std::vector<ParserIssue> vIssues;
973     std::vector<CodeBlock>   vPreprocessorComments;
974     std::vector<void*>       vAutoFreeAfterParse;
975     std::map<String,PatchVarBlock> patchVars;
976 
977     std::set<String> builtinPreprocessorConditions;
978     std::set<String> userPreprocessorConditions;
979 
980     std::map<String,VariableRef> vartable;
981     std::map<String,UserFunctionRef> userFnTable;
982     vmint globalIntVarCount;
983     vmint globalRealVarCount;
984     vmint globalStrVarCount;
985     vmint globalUnitFactorCount;
986     vmint polyphonicIntVarCount;
987     vmint polyphonicRealVarCount;
988     vmint polyphonicUnitFactorCount;
989 
990     EventHandlersRef handlers;
991 
992     OnInitRef onInit;
993     OnNoteRef onNote;
994     OnReleaseRef onRelease;
995     OnControllerRef onController;
996     OnRpnRef onRpn;
997     OnNrpnRef onNrpn;
998 
999     ArrayList<vmint>* globalIntMemory;
1000     ArrayList<vmfloat>* globalRealMemory;
1001     ArrayList<String>* globalStrMemory;
1002     ArrayList<vmfloat>* globalUnitFactorMemory;
1003     vmint requiredMaxStackSize;
1004 
1005     VMFunctionProvider* functionProvider;
1006 
1007     ExecContext* execContext;
1008 
ParserContext(VMFunctionProvider * parent)1009     ParserContext(VMFunctionProvider* parent) :
1010         scanner(NULL), is(NULL), nbytes(0),
1011         globalIntVarCount(0), globalRealVarCount(0), globalStrVarCount(0),
1012         globalUnitFactorCount(0),
1013         polyphonicIntVarCount(0), polyphonicRealVarCount(0),
1014         polyphonicUnitFactorCount(0),
1015         globalIntMemory(NULL), globalRealMemory(NULL), globalStrMemory(NULL),
1016         globalUnitFactorMemory(NULL),
1017         requiredMaxStackSize(-1),
1018         functionProvider(parent), execContext(NULL)
1019     {
1020     }
1021     virtual ~ParserContext();
1022     VariableRef globalVar(const String& name);
1023     IntVariableRef globalIntVar(const String& name);
1024     RealVariableRef globalRealVar(const String& name);
1025     StringVariableRef globalStrVar(const String& name);
1026     VariableRef variableByName(const String& name);
1027     UserFunctionRef userFunctionByName(const String& name);
1028     void addErr(int firstLine, int lastLine, int firstColumn, int lastColumn,
1029                 int firstByte, int lengthBytes, const char* txt);
1030     void addWrn(int firstLine, int lastLine, int firstColumn, int lastColumn,
1031                 int firstByte, int lengthBytes, const char* txt);
1032     void addPreprocessorComment(int firstLine, int lastLine, int firstColumn,
1033                                 int lastColumn, int firstByte, int lengthBytes);
1034     void createScanner(std::istream* is);
1035     void destroyScanner();
1036     bool setPreprocessorCondition(const char* name);
1037     bool resetPreprocessorCondition(const char* name);
1038     bool isPreprocessorConditionSet(const char* name);
1039     void autoFreeAfterParse(void* data);
1040     std::vector<ParserIssue> issues() const OVERRIDE;
1041     std::vector<ParserIssue> errors() const OVERRIDE;
1042     std::vector<ParserIssue> warnings() const OVERRIDE;
1043     std::vector<CodeBlock> preprocessorComments() const OVERRIDE;
1044     VMEventHandler* eventHandler(uint index) OVERRIDE;
1045     VMEventHandler* eventHandlerByName(const String& name) OVERRIDE;
1046     void registerBuiltInConstIntVariables(const std::map<String,vmint>& vars);
1047     void registerBuiltInConstRealVariables(const std::map<String,vmfloat>& vars);
1048     void registerBuiltInIntVariables(const std::map<String,VMIntPtr*>& vars);
1049     void registerBuiltInIntArrayVariables(const std::map<String,VMInt8Array*>& vars);
1050     void registerBuiltInDynVariables(const std::map<String,VMDynVar*>& vars);
1051 };
1052 
1053 class ExecContext FINAL : public VMExecContext {
1054 public:
1055     struct StackFrame {
1056         Statement* statement;
1057         int subindex;
1058 
StackFrameStackFrame1059         StackFrame() {
1060             statement = NULL;
1061             subindex  = -1;
1062         }
1063     };
1064 
1065     ArrayList<vmint> polyphonicIntMemory;
1066     ArrayList<vmfloat> polyphonicRealMemory;
1067     ArrayList<vmfloat> polyphonicUnitFactorMemory;
1068     VMExecStatus_t status;
1069     StmtFlags_t flags;
1070     ArrayList<StackFrame> stack;
1071     int stackFrame;
1072     vmint suspendMicroseconds;
1073     size_t instructionsCount;
1074     struct ExitRes {
1075         Expression* value;
1076         IntLiteral intLiteral;
1077         RealLiteral realLiteral;
1078         StringLiteral stringLiteral;
1079 
ExitResExitRes1080         ExitRes() :
1081             intLiteral({ .value = 0 }), realLiteral({ .value = 0.0 }),
1082             stringLiteral("") { }
1083     } exitRes;
1084 
1085     ExecContext();
~ExecContext()1086     virtual ~ExecContext() {}
1087 
pushStack(Statement * stmt)1088     inline void pushStack(Statement* stmt) {
1089         stackFrame++;
1090         //printf("pushStack() -> %d\n", stackFrame);
1091         if (stackFrame >= stack.size()) return;
1092         stack[stackFrame].statement = stmt;
1093         stack[stackFrame].subindex  = 0;
1094     }
1095 
popStack()1096     inline void popStack() {
1097         stack[stackFrame].statement = NULL;
1098         stack[stackFrame].subindex  = -1;
1099         stackFrame--;
1100         //printf("popStack() -> %d\n", stackFrame);
1101     }
1102 
reset()1103     inline void reset() {
1104         stack[0].statement = NULL;
1105         stack[0].subindex  = -1;
1106         stackFrame = -1;
1107         flags = STMT_SUCCESS;
1108     }
1109 
clearExitRes()1110     inline void clearExitRes() {
1111         exitRes.value = NULL;
1112     }
1113 
suspensionTimeMicroseconds()1114     vmint suspensionTimeMicroseconds() const OVERRIDE {
1115         return suspendMicroseconds;
1116     }
1117 
resetPolyphonicData()1118     void resetPolyphonicData() OVERRIDE {
1119         if (!polyphonicIntMemory.empty())
1120             memset(&polyphonicIntMemory[0], 0, polyphonicIntMemory.size() * sizeof(vmint));
1121         if (!polyphonicRealMemory.empty())
1122             memset(&polyphonicRealMemory[0], 0, polyphonicRealMemory.size() * sizeof(vmfloat));
1123         if (!polyphonicUnitFactorMemory.empty()) {
1124             const vmint sz = polyphonicUnitFactorMemory.size();
1125             for (vmint i = 0; i < sz; ++i)
1126                 polyphonicUnitFactorMemory[i] = VM_NO_FACTOR;
1127         }
1128     }
1129 
1130     void copyPolyphonicDataFrom(VMExecContext* ectx) OVERRIDE;
1131 
instructionsPerformed()1132     size_t instructionsPerformed() const OVERRIDE {
1133         return instructionsCount;
1134     }
1135 
signalAbort()1136     void signalAbort() OVERRIDE {
1137         flags = StmtFlags_t(flags | STMT_ABORT_SIGNALLED);
1138     }
1139 
1140     void forkTo(VMExecContext* ectx) const OVERRIDE;
1141 
exitResult()1142     VMExpr* exitResult() OVERRIDE {
1143         return exitRes.value;
1144     }
1145 };
1146 
1147 } // namespace LinuxSampler
1148 
1149 #endif // LS_INSTRPARSERTREE_H
1150