--- linuxsampler/trunk/src/scriptvm/tree.h 2017/06/27 22:19:19 3293 +++ linuxsampler/trunk/src/scriptvm/tree.h 2019/08/30 12:39:18 3583 @@ -1,6 +1,6 @@ /* -*- c++ -*- * - * Copyright (c) 2014 - 2017 Christian Schoenebeck and Andreas Persson + * Copyright (c) 2014 - 2019 Christian Schoenebeck and Andreas Persson * * http://www.linuxsampler.org * @@ -37,8 +37,30 @@ STMT_BRANCH, STMT_LOOP, STMT_SYNC, + STMT_NOOP, }; +/** + * Convenience function used for retrieving the (assumed) data type of a given + * script variable name. + * + * @param name - some script variable name (e.g. "$foo") + * @return variable's assumed data type (e.g. INT_EXPR for example above) + */ +inline ExprType_t exprTypeOfVarName(const String& name) { + if (name.empty()) return (ExprType_t) -1; + const char prefix = name[0]; + switch (prefix) { + case '$': return INT_EXPR; + case '%': return INT_ARR_EXPR; + case '~': return REAL_EXPR; + case '?': return REAL_ARR_EXPR; + case '@': return STRING_EXPR; + case '!': return STRING_ARR_EXPR; + } + return (ExprType_t) -1; +} + class Node { public: Node(); @@ -57,62 +79,142 @@ }; typedef Ref ExpressionRef; -class IntExpr : virtual public VMIntExpr, virtual public Expression { +class Unit : virtual public VMUnit, virtual public Node { + StdUnit_t unit; +public: + Unit(StdUnit_t type) : unit(type) {} + StdUnit_t unitType() const OVERRIDE { return unit; } + static vmint convIntToUnitFactor(vmint iValue, VMUnit* srcUnit, VMUnit* dstUnit); + static vmint convIntToUnitFactor(vmint iValue, vmfloat srcFactor, vmfloat dstFactor); + static vmfloat convRealToUnitFactor(vmfloat fValue, VMUnit* srcUnit, VMUnit* dstUnit); + static vmfloat convRealToUnitFactor(vmfloat fValue, vmfloat srcFactor, vmfloat dstFactor); +}; +typedef Ref UnitRef; + +class NumberExpr : virtual public Unit, virtual public VMNumberExpr, virtual public Expression { public: - ExprType_t exprType() const { return INT_EXPR; } - virtual int evalInt() = 0; - String evalCastToStr(); +}; +typedef Ref NumberExprRef; + +class IntExpr : virtual public NumberExpr, virtual public VMIntExpr { +public: + ExprType_t exprType() const OVERRIDE { return INT_EXPR; } + vmint evalIntToUnitFactor(vmfloat unitFactor); + String evalCastToStr() OVERRIDE; }; typedef Ref IntExprRef; -class IntArrayExpr : virtual public VMIntArrayExpr, virtual public Expression { +class RealExpr : virtual public NumberExpr, virtual public VMRealExpr { +public: + ExprType_t exprType() const OVERRIDE { return REAL_EXPR; } + vmfloat evalRealToUnitFactor(vmfloat unitFactor); + String evalCastToStr() OVERRIDE; +}; +typedef Ref RealExprRef; + +class ArrayExpr : virtual public VMArrayExpr, virtual public Expression { public: - ExprType_t exprType() const { return INT_ARR_EXPR; } - String evalCastToStr(); +}; +typedef Ref ArrayExprRef; + +class IntArrayExpr : virtual public VMIntArrayExpr, virtual public ArrayExpr { +public: + ExprType_t exprType() const OVERRIDE { return INT_ARR_EXPR; } + String evalCastToStr() OVERRIDE; }; typedef Ref IntArrayExprRef; +class RealArrayExpr : virtual public VMRealArrayExpr, virtual public ArrayExpr { +public: + ExprType_t exprType() const OVERRIDE { return REAL_ARR_EXPR; } + String evalCastToStr() OVERRIDE; +}; +typedef Ref RealArrayExprRef; + class StringExpr : virtual public VMStringExpr, virtual public Expression { public: - ExprType_t exprType() const { return STRING_EXPR; } - virtual String evalStr() = 0; - String evalCastToStr() { return evalStr(); } + ExprType_t exprType() const OVERRIDE { return STRING_EXPR; } + String evalCastToStr() OVERRIDE { return evalStr(); } }; typedef Ref StringExprRef; -class IntLiteral : virtual public IntExpr { - int value; -public: - IntLiteral(int value) : value(value) { } - int evalInt(); - void dump(int level = 0); - bool isConstExpr() const { return true; } - bool isPolyphonic() const { return false; } +struct IntLitDef { + 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. + vmfloat unitFactor = VM_NO_FACTOR; + StdUnit_t unitType = VM_NO_UNIT; + bool isFinal; +}; + +class IntLiteral FINAL : public IntExpr { + bool finalVal; + vmfloat unitPrefixFactor; + vmint value; +public: + IntLiteral(const IntLitDef& def); + vmint evalInt() OVERRIDE; + vmfloat unitFactor() const OVERRIDE { return unitPrefixFactor; } + void dump(int level = 0) OVERRIDE; + bool isConstExpr() const OVERRIDE { return true; } + bool isPolyphonic() const OVERRIDE { return false; } + bool isFinal() const OVERRIDE { return finalVal; } }; typedef Ref IntLiteralRef; -class StringLiteral : virtual public StringExpr { -public: +struct RealLitDef { + 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. + vmfloat unitFactor = VM_NO_FACTOR; + StdUnit_t unitType = VM_NO_UNIT; + bool isFinal; +}; + +class RealLiteral FINAL : public RealExpr { + bool finalVal; + vmfloat unitPrefixFactor; + vmfloat value; +public: + RealLiteral(const RealLitDef& def); + vmfloat evalReal() OVERRIDE; + vmfloat unitFactor() const OVERRIDE { return unitPrefixFactor; } + void dump(int level = 0) OVERRIDE; + bool isConstExpr() const OVERRIDE { return true; } + bool isPolyphonic() const OVERRIDE { return false; } + bool isFinal() const OVERRIDE { return finalVal; } +}; +typedef Ref RealLiteralRef; + +class StringLiteral FINAL : public StringExpr { String value; +public: StringLiteral(const String& value) : value(value) { } - bool isConstExpr() const { return true; } - void dump(int level = 0); - String evalStr() { return value; } - bool isPolyphonic() const { return false; } + bool isConstExpr() const OVERRIDE { return true; } + void dump(int level = 0) OVERRIDE; + String evalStr() OVERRIDE { return value; } + bool isPolyphonic() const OVERRIDE { return false; } }; typedef Ref StringLiteralRef; -class Args : virtual public VMFnArgs, virtual public Node { +class Args FINAL : virtual public VMFnArgs, virtual public Node { public: std::vector args; void add(ExpressionRef arg) { args.push_back(arg); } - void dump(int level = 0); - int argsCount() const { return (int) args.size(); } - VMExpr* arg(int i) { return (i >= 0 && i < argsCount()) ? &*args.at(i) : NULL; } - bool isPolyphonic() const; + void dump(int level = 0) OVERRIDE; + vmint argsCount() const OVERRIDE { return (vmint) args.size(); } + VMExpr* arg(vmint i) OVERRIDE { return (i >= 0 && i < argsCount()) ? &*args.at(i) : NULL; } + bool isPolyphonic() const OVERRIDE; }; typedef Ref ArgsRef; +struct VariableDecl { + ParserContext* ctx; + bool isPolyphonic; + bool isConst; + bool isFinal; + vmint elements = 1; + vmint memPos; + vmint unitFactorMemPos; + StdUnit_t unitType = VM_NO_UNIT; +}; + class Variable : virtual public VMVariable, virtual public Expression { public: bool isConstExpr() const OVERRIDE { return bConst; } @@ -120,121 +222,227 @@ virtual void assign(Expression* expr) = 0; void assignExpr(VMExpr* expr) OVERRIDE { Expression* e = dynamic_cast(expr); if (e) assign(e); } protected: - Variable(ParserContext* ctx, int _memPos, bool _bConst) - : context(ctx), memPos(_memPos), bConst(_bConst) {} + Variable(const VariableDecl& decl); ParserContext* context; - int memPos; + vmint memPos; bool bConst; }; typedef Ref VariableRef; -class IntVariable : public Variable, virtual public IntExpr { +class NumberVariable : public Variable, virtual public NumberExpr { bool polyphonic; + bool finalVal; +protected: + vmint unitFactorMemPos; public: - IntVariable(ParserContext* ctx); - void assign(Expression* expr); - int evalInt(); - void dump(int level = 0); - bool isPolyphonic() const { return polyphonic; } + bool isPolyphonic() const OVERRIDE { return polyphonic; } + bool isFinal() const OVERRIDE { return finalVal; } + vmfloat unitFactor() const OVERRIDE; protected: - IntVariable(ParserContext* ctx, bool polyphonic, bool bConst, int size = 1); + NumberVariable(const VariableDecl& decl); +}; +typedef Ref NumberVariableRef; + +class IntVariable : public NumberVariable, virtual public IntExpr { +public: + IntVariable(const VariableDecl& decl); + void assign(Expression* expr) OVERRIDE; + vmint evalInt() OVERRIDE; + void dump(int level = 0) OVERRIDE; }; typedef Ref IntVariableRef; -class ConstIntVariable : public IntVariable { +class RealVariable : public NumberVariable, virtual public RealExpr { public: - int value; + RealVariable(const VariableDecl& decl); + void assign(Expression* expr) OVERRIDE; + vmfloat evalReal() OVERRIDE; + void dump(int level = 0) OVERRIDE; +}; +typedef Ref RealVariableRef; - ConstIntVariable(int value); - //ConstIntVariable(ParserContext* ctx, int value = 0); - void assign(Expression* expr); - int evalInt(); - void dump(int level = 0); +struct IntVarDef /* : VariableDecl*/ { //NOTE: derived, aggregate initializer-lists requires C++17 + // copied from VariableDecl + ParserContext* ctx; + bool isPolyphonic; + bool isConst; + bool isFinal; + vmint elements = 1; + vmint memPos; + vmint unitFactorMemPos; + StdUnit_t unitType = VM_NO_UNIT; + // additions for RealVarDef + 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. + vmfloat unitFactor = VM_NO_FACTOR; +}; + +class ConstIntVariable FINAL : public IntVariable { + vmfloat unitPrefixFactor; + vmint value; +public: + ConstIntVariable(const IntVarDef& def); + void assign(Expression* expr) OVERRIDE; + vmint evalInt() OVERRIDE; + vmfloat unitFactor() const OVERRIDE { return unitPrefixFactor; } + void dump(int level = 0) OVERRIDE; }; typedef Ref ConstIntVariableRef; -class BuiltInIntVariable : public IntVariable { +struct RealVarDef /* : VariableDecl*/ { //NOTE: derived, aggregate initializer-lists requires C++17 + // copied from VariableDecl + ParserContext* ctx; + bool isPolyphonic; + bool isConst; + bool isFinal; + vmint elements = 1; + vmint memPos; + vmint unitFactorMemPos; + StdUnit_t unitType = VM_NO_UNIT; + // additions for RealVarDef + 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. + vmfloat unitFactor = VM_NO_FACTOR; +}; + +class ConstRealVariable FINAL : public RealVariable { + vmfloat unitPrefixFactor; + vmfloat value; +public: + ConstRealVariable(const RealVarDef& def); + void assign(Expression* expr) OVERRIDE; + vmfloat evalReal() OVERRIDE; + vmfloat unitFactor() const OVERRIDE { return unitPrefixFactor; } + void dump(int level = 0) OVERRIDE; +}; +typedef Ref ConstRealVariableRef; + +class BuiltInIntVariable FINAL : public IntVariable { String name; - VMIntRelPtr* ptr; + VMIntPtr* ptr; public: - BuiltInIntVariable(const String& name, VMIntRelPtr* ptr); - bool isAssignable() const OVERRIDE { return !ptr->readonly; } + BuiltInIntVariable(const String& name, VMIntPtr* ptr); + bool isAssignable() const OVERRIDE { return ptr->isAssignable(); } void assign(Expression* expr) OVERRIDE; - int evalInt() OVERRIDE; + vmint evalInt() OVERRIDE; + vmfloat unitFactor() const OVERRIDE { return VM_NO_UNIT; } void dump(int level = 0) OVERRIDE; }; typedef Ref BuiltInIntVariableRef; -class PolyphonicIntVariable : public IntVariable { +class PolyphonicIntVariable FINAL : public IntVariable { public: - PolyphonicIntVariable(ParserContext* ctx); - void dump(int level = 0); + PolyphonicIntVariable(const VariableDecl& decl); + void dump(int level = 0) OVERRIDE; }; typedef Ref PolyphonicIntVariableRef; +class PolyphonicRealVariable FINAL : public RealVariable { +public: + PolyphonicRealVariable(const VariableDecl& decl); + void dump(int level = 0) OVERRIDE; +}; +typedef Ref PolyphonicRealVariableRef; + class IntArrayVariable : public Variable, virtual public IntArrayExpr { - ArrayList values; + ArrayList values; + ArrayList unitFactors; public: - IntArrayVariable(ParserContext* ctx, int size); - IntArrayVariable(ParserContext* ctx, int size, ArgsRef values, bool _bConst = false); - void assign(Expression* expr) {} // ignore scalar assignment - String evalCastToStr() { return ""; } // ignore scalar cast to string - ExprType_t exprType() const { return INT_ARR_EXPR; } - virtual int arraySize() const { return values.size(); } - virtual int evalIntElement(uint i); - virtual void assignIntElement(uint i, int value); - void dump(int level = 0); - bool isPolyphonic() const { return false; } + IntArrayVariable(ParserContext* ctx, vmint size); + IntArrayVariable(ParserContext* ctx, vmint size, ArgsRef values, bool _bConst = false); + void assign(Expression* expr) OVERRIDE {} // ignore scalar assignment + ExprType_t exprType() const OVERRIDE { return INT_ARR_EXPR; } + virtual vmint arraySize() const OVERRIDE { return values.size(); } + virtual vmint evalIntElement(vmuint i) OVERRIDE; + virtual void assignIntElement(vmuint i, vmint value) OVERRIDE; + vmfloat unitFactorOfElement(vmuint i) const OVERRIDE; + void assignElementUnitFactor(vmuint i, vmfloat factor) OVERRIDE; + void dump(int level = 0) OVERRIDE; + bool isPolyphonic() const OVERRIDE { return false; } protected: IntArrayVariable(ParserContext* ctx, bool bConst); }; typedef Ref IntArrayVariableRef; -class BuiltInIntArrayVariable : public IntArrayVariable { +class RealArrayVariable FINAL : public Variable, virtual public RealArrayExpr { + ArrayList values; + ArrayList unitFactors; +public: + RealArrayVariable(ParserContext* ctx, vmint size); + RealArrayVariable(ParserContext* ctx, vmint size, ArgsRef values, bool _bConst = false); + void assign(Expression* expr) OVERRIDE {} // ignore scalar assignment + ExprType_t exprType() const OVERRIDE { return REAL_ARR_EXPR; } + virtual vmint arraySize() const OVERRIDE { return values.size(); } + virtual vmfloat evalRealElement(vmuint i) OVERRIDE; + virtual void assignRealElement(vmuint i, vmfloat value) OVERRIDE; + vmfloat unitFactorOfElement(vmuint i) const OVERRIDE; + void assignElementUnitFactor(vmuint i, vmfloat factor) OVERRIDE; + void dump(int level = 0) OVERRIDE; + bool isPolyphonic() const OVERRIDE { return false; } +protected: + RealArrayVariable(ParserContext* ctx, bool bConst); +}; +typedef Ref RealArrayVariableRef; + +class BuiltInIntArrayVariable FINAL : public IntArrayVariable { String name; VMInt8Array* array; public: BuiltInIntArrayVariable(const String& name, VMInt8Array* array); - int arraySize() const { return array->size; } - int evalIntElement(uint i); + vmint arraySize() const OVERRIDE { return array->size; } + vmint evalIntElement(vmuint i) OVERRIDE; + void assignIntElement(vmuint i, vmint value) OVERRIDE; + vmfloat unitFactorOfElement(vmuint i) const OVERRIDE { return VM_NO_FACTOR; } + void assignElementUnitFactor(vmuint i, vmfloat factor) OVERRIDE {} bool isAssignable() const OVERRIDE { return !array->readonly; } - void assignIntElement(uint i, int value); - void dump(int level = 0); + void dump(int level = 0) OVERRIDE; }; typedef Ref BuiltInIntArrayVariableRef; -class IntArrayElement : public IntVariable { +class IntArrayElement FINAL : public IntVariable { IntArrayExprRef array; IntExprRef index; + vmint currentIndex; public: IntArrayElement(IntArrayExprRef array, IntExprRef arrayIndex); - void assign(Expression* expr); - int evalInt(); - void dump(int level = 0); + void assign(Expression* expr) OVERRIDE; + vmint evalInt() OVERRIDE; + vmfloat unitFactor() const OVERRIDE; + void dump(int level = 0) OVERRIDE; }; typedef Ref IntArrayElementRef; +class RealArrayElement FINAL : public RealVariable { + RealArrayExprRef array; + IntExprRef index; + vmint currentIndex; +public: + RealArrayElement(RealArrayExprRef array, IntExprRef arrayIndex); + void assign(Expression* expr) OVERRIDE; + vmfloat evalReal() OVERRIDE; + vmfloat unitFactor() const OVERRIDE; + void dump(int level = 0) OVERRIDE; +}; +typedef Ref RealArrayElementRef; + class StringVariable : public Variable, virtual public StringExpr { public: StringVariable(ParserContext* ctx); - void assign(Expression* expr); - String evalStr(); - void dump(int level = 0); - bool isPolyphonic() const { return false; } + void assign(Expression* expr) OVERRIDE; + String evalStr() OVERRIDE; + void dump(int level = 0) OVERRIDE; + bool isPolyphonic() const OVERRIDE { return false; } protected: StringVariable(ParserContext* ctx, bool bConst); }; typedef Ref StringVariableRef; -class ConstStringVariable : public StringVariable { -public: +class ConstStringVariable FINAL : public StringVariable { String value; - +public: ConstStringVariable(ParserContext* ctx, String value = ""); - void assign(Expression* expr); - String evalStr(); - void dump(int level = 0); + void assign(Expression* expr) OVERRIDE; + String evalStr() OVERRIDE; + void dump(int level = 0) OVERRIDE; }; typedef Ref ConstStringVariableRef; @@ -244,48 +452,78 @@ ExpressionRef rhs; public: BinaryOp(ExpressionRef lhs, ExpressionRef rhs) : lhs(lhs), rhs(rhs) { } - bool isConstExpr() const { return lhs->isConstExpr() && rhs->isConstExpr(); } - bool isPolyphonic() const { return lhs->isPolyphonic() || rhs->isPolyphonic(); } + bool isConstExpr() const OVERRIDE { return lhs->isConstExpr() && rhs->isConstExpr(); } + bool isPolyphonic() const OVERRIDE { return lhs->isPolyphonic() || rhs->isPolyphonic(); } }; typedef Ref BinaryOpRef; -class Add : virtual public BinaryOp, virtual public IntExpr { +class NumberBinaryOp : public BinaryOp, virtual public NumberExpr { +public: + NumberBinaryOp(NumberExprRef lhs, NumberExprRef rhs) : BinaryOp(lhs, rhs) { } + bool isFinal() const OVERRIDE; +}; +typedef Ref NumberBinaryOpRef; + +class IntBinaryOp : public NumberBinaryOp, virtual public IntExpr { +public: + IntBinaryOp(IntExprRef lhs, IntExprRef rhs) : NumberBinaryOp(lhs, rhs) { } +}; +typedef Ref IntBinaryOpRef; + +class VaritypeScalarBinaryOp : public NumberBinaryOp, virtual public IntExpr, virtual public RealExpr { +public: + VaritypeScalarBinaryOp(NumberExprRef lhs, NumberExprRef rhs) : NumberBinaryOp(lhs, rhs) { } + ExprType_t exprType() const OVERRIDE; + String evalCastToStr() OVERRIDE; +}; +typedef Ref VaritypeScalarBinaryOpRef; + +class Add FINAL : public VaritypeScalarBinaryOp { public: - Add(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs, rhs) { } - int evalInt(); - void dump(int level = 0); + Add(NumberExprRef lhs, NumberExprRef rhs); + vmint evalInt() OVERRIDE; + vmfloat evalReal() OVERRIDE; + vmfloat unitFactor() const OVERRIDE; + void dump(int level = 0) OVERRIDE; }; typedef Ref AddRef; -class Sub : virtual public BinaryOp, virtual public IntExpr { +class Sub FINAL : public VaritypeScalarBinaryOp { public: - Sub(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs, rhs) { } - int evalInt(); - void dump(int level = 0); + Sub(NumberExprRef lhs, NumberExprRef rhs); + vmint evalInt() OVERRIDE; + vmfloat evalReal() OVERRIDE; + vmfloat unitFactor() const OVERRIDE; + void dump(int level = 0) OVERRIDE; }; typedef Ref SubRef; -class Mul : virtual public BinaryOp, virtual public IntExpr { +class Mul FINAL : public VaritypeScalarBinaryOp { public: - Mul(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs, rhs) { } - int evalInt(); - void dump(int level = 0); + Mul(NumberExprRef lhs, NumberExprRef rhs); + vmint evalInt() OVERRIDE; + vmfloat evalReal() OVERRIDE; + vmfloat unitFactor() const OVERRIDE; + void dump(int level = 0) OVERRIDE; }; typedef Ref MulRef; -class Div : virtual public BinaryOp, virtual public IntExpr { +class Div FINAL : public VaritypeScalarBinaryOp { public: - Div(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs, rhs) { } - int evalInt(); - void dump(int level = 0); + Div(NumberExprRef lhs, NumberExprRef rhs); + vmint evalInt() OVERRIDE; + vmfloat evalReal() OVERRIDE; + void dump(int level = 0) OVERRIDE; + vmfloat unitFactor() const OVERRIDE; }; typedef Ref DivRef; -class Mod : virtual public BinaryOp, virtual public IntExpr { +class Mod FINAL : public IntBinaryOp { public: - Mod(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs, rhs) { } - int evalInt(); - void dump(int level = 0); + Mod(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs, rhs), Unit(VM_NO_UNIT) { } + vmint evalInt() OVERRIDE; + vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; } + void dump(int level = 0) OVERRIDE; }; typedef Ref ModRef; @@ -297,12 +535,12 @@ // Just used by parser to avoid "not a statement" parser warning, will be // filtered out by parser. So it will not be part of the VM tree after parsing. -class NoOperation : public Statement { +class NoOperation FINAL : public Statement { public: NoOperation() : Statement() {} - StmtType_t statementType() const { return STMT_LEAF; } - void dump(int level = 0) {} - bool isPolyphonic() const { return false; } + StmtType_t statementType() const OVERRIDE { return STMT_NOOP; } + void dump(int level = 0) OVERRIDE {} + bool isPolyphonic() const OVERRIDE { return false; } }; typedef Ref NoOperationRef; @@ -311,7 +549,7 @@ class LeafStatement : public Statement { public: virtual StmtFlags_t exec() = 0; - virtual StmtType_t statementType() const { return STMT_LEAF; } + StmtType_t statementType() const OVERRIDE { return STMT_LEAF; } }; typedef Ref LeafStatementRef; @@ -319,21 +557,21 @@ std::vector args; public: void add(StatementRef arg) { args.push_back(arg); } - void dump(int level = 0); - StmtType_t statementType() const { return STMT_LIST; } + void dump(int level = 0) OVERRIDE; + StmtType_t statementType() const OVERRIDE { return STMT_LIST; } virtual Statement* statement(uint i); - bool isPolyphonic() const; + bool isPolyphonic() const OVERRIDE; }; typedef Ref StatementsRef; class BranchStatement : public Statement { public: - StmtType_t statementType() const { return STMT_BRANCH; } - virtual int evalBranch() = 0; - virtual Statements* branch(uint i) const = 0; + StmtType_t statementType() const OVERRIDE { return STMT_BRANCH; } + virtual vmint evalBranch() = 0; + virtual Statements* branch(vmuint i) const = 0; }; -class DynamicVariableCall : public Variable, virtual public IntExpr, virtual public StringExpr, virtual public IntArrayExpr { +class DynamicVariableCall FINAL : public Variable, virtual public IntExpr, virtual public StringExpr, virtual public IntArrayExpr { VMDynVar* dynVar; String varName; public: @@ -344,109 +582,123 @@ bool isPolyphonic() const OVERRIDE { return false; } void assign(Expression* expr) OVERRIDE { dynVar->assignExpr(expr); } VMIntArrayExpr* asIntArray() const OVERRIDE { return dynVar->asIntArray(); } - int evalInt() OVERRIDE; + vmint evalInt() OVERRIDE; String evalStr() OVERRIDE; String evalCastToStr() OVERRIDE; - int arraySize() const OVERRIDE { return dynVar->asIntArray()->arraySize(); } - int evalIntElement(uint i) OVERRIDE { return dynVar->asIntArray()->evalIntElement(i); } - void assignIntElement(uint i, int value) { return dynVar->asIntArray()->assignIntElement(i, value); } + vmint arraySize() const OVERRIDE { return dynVar->asIntArray()->arraySize(); } + vmint evalIntElement(vmuint i) OVERRIDE { return dynVar->asIntArray()->evalIntElement(i); } + void assignIntElement(vmuint i, vmint value) OVERRIDE { return dynVar->asIntArray()->assignIntElement(i, value); } + vmfloat unitFactorOfElement(vmuint i) const OVERRIDE { return VM_NO_FACTOR; } + void assignElementUnitFactor(vmuint i, vmfloat factor) OVERRIDE {} void dump(int level = 0) OVERRIDE; + vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; } + bool isFinal() const OVERRIDE { return false; } }; typedef Ref DynamicVariableCallRef; -class FunctionCall : virtual public LeafStatement, virtual public IntExpr, virtual public StringExpr { +class FunctionCall : virtual public LeafStatement, virtual public IntExpr, virtual public RealExpr, virtual public StringExpr { String functionName; ArgsRef args; VMFunction* fn; + VMFnResult* result; public: - FunctionCall(const char* function, ArgsRef args, VMFunction* fn) : - functionName(function), args(args), fn(fn) { } + FunctionCall(const char* function, ArgsRef args, VMFunction* fn); void dump(int level = 0) OVERRIDE; StmtFlags_t exec() OVERRIDE; - int evalInt() OVERRIDE; + vmint evalInt() OVERRIDE; + vmfloat evalReal() OVERRIDE; VMIntArrayExpr* asIntArray() const OVERRIDE; + VMRealArrayExpr* asRealArray() const OVERRIDE; String evalStr() OVERRIDE; bool isConstExpr() const OVERRIDE { return false; } ExprType_t exprType() const OVERRIDE; String evalCastToStr() OVERRIDE; bool isPolyphonic() const OVERRIDE { return args->isPolyphonic(); } + vmfloat unitFactor() const OVERRIDE; + bool isFinal() const OVERRIDE; protected: VMFnResult* execVMFn(); }; typedef Ref FunctionCallRef; +class NoFunctionCall FINAL : public FunctionCall { +public: + NoFunctionCall() : FunctionCall("nothing", new Args, NULL), Unit(VM_NO_UNIT) {} + StmtType_t statementType() const OVERRIDE { return STMT_NOOP; } +}; +typedef Ref NoFunctionCallRef; + class EventHandler : virtual public Statements, virtual public VMEventHandler { StatementsRef statements; bool usingPolyphonics; public: - void dump(int level = 0); + void dump(int level = 0) OVERRIDE; StmtFlags_t exec(); EventHandler(StatementsRef statements); - Statement* statement(uint i) { return statements->statement(i); } - bool isPolyphonic() const { return usingPolyphonics; } + Statement* statement(uint i) OVERRIDE { return statements->statement(i); } + bool isPolyphonic() const OVERRIDE { return usingPolyphonics; } }; typedef Ref EventHandlerRef; -class OnNote : public EventHandler { +class OnNote FINAL : public EventHandler { public: OnNote(StatementsRef statements) : EventHandler(statements) {} - VMEventHandlerType_t eventHandlerType() const { return VM_EVENT_HANDLER_NOTE; } - String eventHandlerName() const { return "note"; } + VMEventHandlerType_t eventHandlerType() const OVERRIDE { return VM_EVENT_HANDLER_NOTE; } + String eventHandlerName() const OVERRIDE { return "note"; } }; typedef Ref OnNoteRef; -class OnInit : public EventHandler { +class OnInit FINAL : public EventHandler { public: OnInit(StatementsRef statements) : EventHandler(statements) {} - VMEventHandlerType_t eventHandlerType() const { return VM_EVENT_HANDLER_INIT; } - String eventHandlerName() const { return "init"; } + VMEventHandlerType_t eventHandlerType() const OVERRIDE { return VM_EVENT_HANDLER_INIT; } + String eventHandlerName() const OVERRIDE { return "init"; } }; typedef Ref OnInitRef; -class OnRelease : public EventHandler { +class OnRelease FINAL : public EventHandler { public: OnRelease(StatementsRef statements) : EventHandler(statements) {} - VMEventHandlerType_t eventHandlerType() const { return VM_EVENT_HANDLER_RELEASE; } - String eventHandlerName() const { return "release"; } + VMEventHandlerType_t eventHandlerType() const OVERRIDE { return VM_EVENT_HANDLER_RELEASE; } + String eventHandlerName() const OVERRIDE { return "release"; } }; typedef Ref OnReleaseRef; -class OnController : public EventHandler { +class OnController FINAL : public EventHandler { public: OnController(StatementsRef statements) : EventHandler(statements) {} - VMEventHandlerType_t eventHandlerType() const { return VM_EVENT_HANDLER_CONTROLLER; } - String eventHandlerName() const { return "controller"; } + VMEventHandlerType_t eventHandlerType() const OVERRIDE { return VM_EVENT_HANDLER_CONTROLLER; } + String eventHandlerName() const OVERRIDE { return "controller"; } }; typedef Ref OnControllerRef; -class EventHandlers : virtual public Node { +class EventHandlers FINAL : virtual public Node { std::vector args; public: EventHandlers(); ~EventHandlers(); void add(EventHandlerRef arg); - void dump(int level = 0); - int evalInt() { return 0; } + void dump(int level = 0) OVERRIDE; EventHandler* eventHandlerByName(const String& name) const; EventHandler* eventHandler(uint index) const; inline uint size() const { return (int) args.size(); } - bool isPolyphonic() const; + bool isPolyphonic() const OVERRIDE; }; typedef Ref EventHandlersRef; -class Assignment : public LeafStatement { +class Assignment FINAL : public LeafStatement { protected: VariableRef variable; ExpressionRef value; public: Assignment(VariableRef variable, ExpressionRef value); - void dump(int level = 0); - StmtFlags_t exec(); - bool isPolyphonic() const { return (variable && variable->isPolyphonic()) || (value && value->isPolyphonic()); } + void dump(int level = 0) OVERRIDE; + StmtFlags_t exec() OVERRIDE; + bool isPolyphonic() const OVERRIDE { return (variable && variable->isPolyphonic()) || (value && value->isPolyphonic()); } }; typedef Ref AssignmentRef; -class If : public BranchStatement { +class If FINAL : public BranchStatement { IntExprRef condition; StatementsRef ifStatements; StatementsRef elseStatements; @@ -455,85 +707,85 @@ condition(condition), ifStatements(ifStatements), elseStatements(elseStatements) { } If(IntExprRef condition, StatementsRef statements) : condition(condition), ifStatements(statements) { } - void dump(int level = 0); - int evalBranch(); - Statements* branch(uint i) const; - bool isPolyphonic() const; + void dump(int level = 0) OVERRIDE; + vmint evalBranch() OVERRIDE; + Statements* branch(vmuint i) const OVERRIDE; + bool isPolyphonic() const OVERRIDE; }; typedef Ref IfRef; -struct CaseBranch { +struct CaseBranch FINAL { IntExprRef from; IntExprRef to; StatementsRef statements; }; - typedef std::vector CaseBranches; -class SelectCase : public BranchStatement { +class SelectCase FINAL : public BranchStatement { IntExprRef select; CaseBranches branches; public: SelectCase(IntExprRef select, const CaseBranches& branches) : select(select), branches(branches) { } - void dump(int level = 0); - int evalBranch(); - Statements* branch(uint i) const; - //void addBranch(IntExprRef condition, StatementsRef statements); - //void addBranch(IntExprRef from, IntExprRef to, StatementsRef statements); - //void addBranch(CaseBranchRef branch); - //void addBranches(CaseBranchesRef branches); - bool isPolyphonic() const; + void dump(int level = 0) OVERRIDE; + vmint evalBranch() OVERRIDE; + Statements* branch(vmuint i) const OVERRIDE; + bool isPolyphonic() const OVERRIDE; }; typedef Ref SelectCaseRef; -class While : public Statement { +class While FINAL : public Statement { IntExprRef m_condition; StatementsRef m_statements; public: While(IntExprRef condition, StatementsRef statements) : m_condition(condition), m_statements(statements) {} - StmtType_t statementType() const { return STMT_LOOP; } - void dump(int level = 0); + StmtType_t statementType() const OVERRIDE { return STMT_LOOP; } + void dump(int level = 0) OVERRIDE; bool evalLoopStartCondition(); Statements* statements() const; - bool isPolyphonic() const { return m_condition->isPolyphonic() || m_statements->isPolyphonic(); } + bool isPolyphonic() const OVERRIDE { return m_condition->isPolyphonic() || m_statements->isPolyphonic(); } }; -class SyncBlock : public Statement { +class SyncBlock FINAL : public Statement { StatementsRef m_statements; public: SyncBlock(StatementsRef statements) : m_statements(statements) {} - StmtType_t statementType() const { return STMT_SYNC; } - void dump(int level = 0); + StmtType_t statementType() const OVERRIDE { return STMT_SYNC; } + void dump(int level = 0) OVERRIDE; Statements* statements() const; - bool isPolyphonic() const { return m_statements->isPolyphonic(); } + bool isPolyphonic() const OVERRIDE { return m_statements->isPolyphonic(); } }; typedef Ref SyncBlockRef; -class Neg : public IntExpr { - IntExprRef expr; +class Neg FINAL : virtual public IntExpr, virtual public RealExpr { + NumberExprRef expr; public: - Neg(IntExprRef expr) : expr(expr) { } - int evalInt() { return (expr) ? -expr->evalInt() : 0; } - void dump(int level = 0); - bool isConstExpr() const { return expr->isConstExpr(); } - bool isPolyphonic() const { return expr->isPolyphonic(); } + Neg(NumberExprRef expr) : Unit(expr->unitType()), expr(expr) { } + ExprType_t exprType() const OVERRIDE { return expr->exprType(); } + vmint evalInt() OVERRIDE { return (expr) ? -(expr->asInt()->evalInt()) : 0; } + vmfloat evalReal() OVERRIDE { return (expr) ? -(expr->asReal()->evalReal()) : vmfloat(0); } + String evalCastToStr() OVERRIDE; + void dump(int level = 0) OVERRIDE; + bool isConstExpr() const OVERRIDE { return expr->isConstExpr(); } + bool isPolyphonic() const OVERRIDE { return expr->isPolyphonic(); } + vmfloat unitFactor() const OVERRIDE { return expr->unitFactor(); } + bool isFinal() const OVERRIDE { return expr->isFinal(); } }; typedef Ref NegRef; -class ConcatString : public StringExpr { +class ConcatString FINAL : public StringExpr { ExpressionRef lhs; ExpressionRef rhs; public: ConcatString(ExpressionRef lhs, ExpressionRef rhs) : lhs(lhs), rhs(rhs) {} - String evalStr(); - void dump(int level = 0); - bool isConstExpr() const; - bool isPolyphonic() const { return lhs->isPolyphonic() || rhs->isPolyphonic(); } + String evalStr() OVERRIDE; + void dump(int level = 0) OVERRIDE; + bool isConstExpr() const OVERRIDE; + bool isPolyphonic() const OVERRIDE { return lhs->isPolyphonic() || rhs->isPolyphonic(); } }; typedef Ref ConcatStringRef; -class Relation : public IntExpr { +class Relation FINAL : public IntExpr { public: enum Type { LESS_THAN, @@ -543,74 +795,99 @@ EQUAL, NOT_EQUAL }; - Relation(IntExprRef lhs, Type type, IntExprRef rhs) : - lhs(lhs), rhs(rhs), type(type) {} - int evalInt(); - void dump(int level = 0); - bool isConstExpr() const; - bool isPolyphonic() const { return lhs->isPolyphonic() || rhs->isPolyphonic(); } + Relation(ExpressionRef lhs, Type type, ExpressionRef rhs); + vmint evalInt() OVERRIDE; + void dump(int level = 0) OVERRIDE; + bool isConstExpr() const OVERRIDE; + bool isPolyphonic() const OVERRIDE { return lhs->isPolyphonic() || rhs->isPolyphonic(); } + vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; } + bool isFinal() const OVERRIDE { return false; } private: - IntExprRef lhs; - IntExprRef rhs; + ExpressionRef lhs; + ExpressionRef rhs; Type type; }; typedef Ref RelationRef; -class Or : virtual public BinaryOp, virtual public IntExpr { +class Or FINAL : public IntBinaryOp { public: - Or(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs,rhs) {} - int evalInt(); - void dump(int level = 0); + Or(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs,rhs), Unit(VM_NO_UNIT) {} + vmint evalInt() OVERRIDE; + vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; } + void dump(int level = 0) OVERRIDE; }; typedef Ref OrRef; -class BitwiseOr : virtual public BinaryOp, virtual public IntExpr { +class BitwiseOr FINAL : public IntBinaryOp { public: - BitwiseOr(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs,rhs) {} - int evalInt(); - void dump(int level = 0); + BitwiseOr(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs,rhs), Unit(VM_NO_UNIT) {} + vmint evalInt() OVERRIDE; + void dump(int level = 0) OVERRIDE; + vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; } }; typedef Ref BitwiseOrRef; -class And : virtual public BinaryOp, virtual public IntExpr { +class And FINAL : public IntBinaryOp { public: - And(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs,rhs) {} - int evalInt(); - void dump(int level = 0); + And(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs,rhs), Unit(VM_NO_UNIT) {} + vmint evalInt() OVERRIDE; + vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; } + void dump(int level = 0) OVERRIDE; }; typedef Ref AndRef; -class BitwiseAnd : virtual public BinaryOp, virtual public IntExpr { +class BitwiseAnd FINAL : public IntBinaryOp { public: - BitwiseAnd(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs,rhs) {} - int evalInt(); - void dump(int level = 0); + BitwiseAnd(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs,rhs), Unit(VM_NO_UNIT) {} + vmint evalInt() OVERRIDE; + void dump(int level = 0) OVERRIDE; + vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; } }; typedef Ref BitwiseAndRef; -class Not : virtual public IntExpr { +class Not FINAL : virtual public IntExpr { IntExprRef expr; public: - Not(IntExprRef expr) : expr(expr) {} - int evalInt() { return !expr->evalInt(); } - void dump(int level = 0); - bool isConstExpr() const { return expr->isConstExpr(); } - bool isPolyphonic() const { return expr->isPolyphonic(); } + Not(IntExprRef expr) : Unit(VM_NO_UNIT), expr(expr) {} + vmint evalInt() OVERRIDE { return !expr->evalInt(); } + void dump(int level = 0) OVERRIDE; + bool isConstExpr() const OVERRIDE { return expr->isConstExpr(); } + bool isPolyphonic() const OVERRIDE { return expr->isPolyphonic(); } + vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; } + bool isFinal() const OVERRIDE { return expr->isFinal(); } }; typedef Ref NotRef; -class BitwiseNot : virtual public IntExpr { +class BitwiseNot FINAL : virtual public IntExpr { IntExprRef expr; public: - BitwiseNot(IntExprRef expr) : expr(expr) {} - int evalInt() { return ~expr->evalInt(); } - void dump(int level = 0); - bool isConstExpr() const { return expr->isConstExpr(); } - bool isPolyphonic() const { return expr->isPolyphonic(); } + BitwiseNot(IntExprRef expr) : Unit(VM_NO_UNIT), expr(expr) {} + vmint evalInt() OVERRIDE { return ~expr->evalInt(); } + void dump(int level = 0) OVERRIDE; + bool isConstExpr() const OVERRIDE { return expr->isConstExpr(); } + bool isPolyphonic() const OVERRIDE { return expr->isPolyphonic(); } + vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; } + bool isFinal() const OVERRIDE { return expr->isFinal(); } }; typedef Ref BitwiseNotRef; -class ParserContext : public VMParserContext { +class Final FINAL : virtual public IntExpr, virtual public RealExpr { + NumberExprRef expr; +public: + Final(NumberExprRef expr) : Unit(expr->unitType()), expr(expr) {} + ExprType_t exprType() const OVERRIDE { return expr->exprType(); } + vmint evalInt() OVERRIDE { return expr->asInt()->evalInt(); } + vmfloat evalReal() OVERRIDE { return expr->asReal()->evalReal(); } + String evalCastToStr() OVERRIDE; + void dump(int level = 0) OVERRIDE; + bool isConstExpr() const OVERRIDE { return expr->isConstExpr(); } + bool isPolyphonic() const OVERRIDE { return expr->isPolyphonic(); } + vmfloat unitFactor() const OVERRIDE { return expr->unitFactor(); } + bool isFinal() const OVERRIDE { return true; } +}; +typedef Ref FinalRef; + +class ParserContext FINAL : public VMParserContext { public: struct Error { String txt; @@ -630,9 +907,13 @@ std::map vartable; std::map userFnTable; - int globalIntVarCount; - int globalStrVarCount; - int polyphonicIntVarCount; + vmint globalIntVarCount; + vmint globalRealVarCount; + vmint globalStrVarCount; + vmint globalUnitFactorCount; + vmint polyphonicIntVarCount; + vmint polyphonicRealVarCount; + vmint polyphonicUnitFactorCount; EventHandlersRef handlers; @@ -641,9 +922,11 @@ OnReleaseRef onRelease; OnControllerRef onController; - ArrayList* globalIntMemory; + ArrayList* globalIntMemory; + ArrayList* globalRealMemory; ArrayList* globalStrMemory; - int requiredMaxStackSize; + ArrayList* globalUnitFactorMemory; + vmint requiredMaxStackSize; VMFunctionProvider* functionProvider; @@ -651,14 +934,20 @@ ParserContext(VMFunctionProvider* parent) : scanner(NULL), is(NULL), - globalIntVarCount(0), globalStrVarCount(0), polyphonicIntVarCount(0), - globalIntMemory(NULL), globalStrMemory(NULL), requiredMaxStackSize(-1), + globalIntVarCount(0), globalRealVarCount(0), globalStrVarCount(0), + globalUnitFactorCount(0), + polyphonicIntVarCount(0), polyphonicRealVarCount(0), + polyphonicUnitFactorCount(0), + globalIntMemory(NULL), globalRealMemory(NULL), globalStrMemory(NULL), + globalUnitFactorMemory(NULL), + requiredMaxStackSize(-1), functionProvider(parent), execContext(NULL) { } virtual ~ParserContext(); VariableRef globalVar(const String& name); IntVariableRef globalIntVar(const String& name); + RealVariableRef globalRealVar(const String& name); StringVariableRef globalStrVar(const String& name); VariableRef variableByName(const String& name); StatementsRef userFunctionByName(const String& name); @@ -676,13 +965,13 @@ std::vector preprocessorComments() const OVERRIDE; VMEventHandler* eventHandler(uint index) OVERRIDE; VMEventHandler* eventHandlerByName(const String& name) OVERRIDE; - void registerBuiltInConstIntVariables(const std::map& vars); - void registerBuiltInIntVariables(const std::map& vars); + void registerBuiltInConstIntVariables(const std::map& vars); + void registerBuiltInIntVariables(const std::map& vars); void registerBuiltInIntArrayVariables(const std::map& vars); void registerBuiltInDynVariables(const std::map& vars); }; -class ExecContext : public VMExecContext { +class ExecContext FINAL : public VMExecContext { public: struct StackFrame { Statement* statement; @@ -694,18 +983,27 @@ } }; - ArrayList polyphonicIntMemory; + ArrayList polyphonicIntMemory; + ArrayList polyphonicRealMemory; + ArrayList polyphonicUnitFactorMemory; VMExecStatus_t status; StmtFlags_t flags; ArrayList stack; int stackFrame; - int suspendMicroseconds; + vmint suspendMicroseconds; size_t instructionsCount; + struct ExitRes { + Expression* value; + IntLiteral intLiteral; + RealLiteral realLiteral; + StringLiteral stringLiteral; + + ExitRes() : + intLiteral({ .value = 0 }), realLiteral({ .value = 0.0 }), + stringLiteral("") { } + } exitRes; - ExecContext() : - status(VM_EXEC_NOT_RUNNING), flags(STMT_SUCCESS), stackFrame(-1), - suspendMicroseconds(0), instructionsCount(0) {} - + ExecContext(); virtual ~ExecContext() {} inline void pushStack(Statement* stmt) { @@ -730,13 +1028,24 @@ flags = STMT_SUCCESS; } - int suspensionTimeMicroseconds() const OVERRIDE { + inline void clearExitRes() { + exitRes.value = NULL; + } + + vmint suspensionTimeMicroseconds() const OVERRIDE { return suspendMicroseconds; } void resetPolyphonicData() OVERRIDE { - if (polyphonicIntMemory.empty()) return; - memset(&polyphonicIntMemory[0], 0, polyphonicIntMemory.size() * sizeof(int)); + if (!polyphonicIntMemory.empty()) + memset(&polyphonicIntMemory[0], 0, polyphonicIntMemory.size() * sizeof(vmint)); + if (!polyphonicRealMemory.empty()) + memset(&polyphonicRealMemory[0], 0, polyphonicRealMemory.size() * sizeof(vmfloat)); + if (!polyphonicUnitFactorMemory.empty()) { + const vmint sz = polyphonicUnitFactorMemory.size(); + for (vmint i = 0; i < sz; ++i) + polyphonicUnitFactorMemory[i] = VM_NO_FACTOR; + } } size_t instructionsPerformed() const OVERRIDE { @@ -748,6 +1057,10 @@ } void forkTo(VMExecContext* ectx) const OVERRIDE; + + VMExpr* exitResult() OVERRIDE { + return exitRes.value; + } }; } // namespace LinuxSampler