--- linuxsampler/trunk/src/scriptvm/tree.h 2019/08/27 21:36:53 3573 +++ linuxsampler/trunk/src/scriptvm/tree.h 2019/08/30 12:39:18 3583 @@ -40,6 +40,27 @@ 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(); @@ -59,33 +80,34 @@ typedef Ref ExpressionRef; class Unit : virtual public VMUnit, virtual public Node { - ArrayList prefix; StdUnit_t unit; public: - Unit() : unit(VM_NO_UNIT) {} - MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE; + Unit(StdUnit_t type) : unit(type) {} StdUnit_t unitType() const OVERRIDE { return unit; } - void setUnit(const std::vector& prefix, StdUnit_t type); - void setUnit(const MetricPrefix_t* prefixes, StdUnit_t type); - void copyUnitFrom(const Ref& src); + 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 ScalarNumberExpr : virtual public Unit, virtual public VMScalarNumberExpr, virtual public Expression { +class NumberExpr : virtual public Unit, virtual public VMNumberExpr, virtual public Expression { public: }; -typedef Ref ScalarNumberExprRef; +typedef Ref NumberExprRef; -class IntExpr : virtual public ScalarNumberExpr, virtual public VMIntExpr { +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 RealExpr : virtual public ScalarNumberExpr, virtual public VMRealExpr { +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; @@ -116,39 +138,53 @@ }; typedef Ref StringExprRef; -class IntLiteral : public IntExpr { +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; -public: + vmfloat unitPrefixFactor; vmint value; - IntLiteral(vmint value) : IntExpr(), - value(value), finalVal(false) { } +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; } - void setFinal(bool b = true) { finalVal = b; } }; typedef Ref IntLiteralRef; -class RealLiteral : public RealExpr { - vmfloat value; +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(vmfloat value) : RealExpr(), - value(value), finalVal(false) { } + 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; } - void setFinal(bool b = true) { finalVal = b; } }; typedef Ref RealLiteralRef; -class StringLiteral : virtual public StringExpr { -public: +class StringLiteral FINAL : public StringExpr { String value; +public: StringLiteral(const String& value) : value(value) { } bool isConstExpr() const OVERRIDE { return true; } void dump(int level = 0) OVERRIDE; @@ -157,7 +193,7 @@ }; 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); } @@ -168,6 +204,17 @@ }; 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; } @@ -175,8 +222,7 @@ virtual void assign(Expression* expr) = 0; void assignExpr(VMExpr* expr) OVERRIDE { Expression* e = dynamic_cast(expr); if (e) assign(e); } protected: - Variable(ParserContext* ctx, vmint _memPos, bool _bConst) - : context(ctx), memPos(_memPos), bConst(_bConst) {} + Variable(const VariableDecl& decl); ParserContext* context; vmint memPos; @@ -184,65 +230,93 @@ }; typedef Ref VariableRef; -class ScalarNumberVariable : public Variable, virtual public ScalarNumberExpr { +class NumberVariable : public Variable, virtual public NumberExpr { bool polyphonic; bool finalVal; +protected: + vmint unitFactorMemPos; public: bool isPolyphonic() const OVERRIDE { return polyphonic; } bool isFinal() const OVERRIDE { return finalVal; } - void setFinal(bool b = true) { finalVal = b; } + vmfloat unitFactor() const OVERRIDE; protected: - ScalarNumberVariable(ParserContext* ctx, vmint _memPos, - bool _bConst = false, bool _bPolyphonic = false, - bool _bFinal = false); + NumberVariable(const VariableDecl& decl); }; -typedef Ref ScalarNumberVariableRef; +typedef Ref NumberVariableRef; -class IntVariable : public ScalarNumberVariable, virtual public IntExpr { +class IntVariable : public NumberVariable, virtual public IntExpr { public: - IntVariable(ParserContext* ctx); + IntVariable(const VariableDecl& decl); void assign(Expression* expr) OVERRIDE; vmint evalInt() OVERRIDE; void dump(int level = 0) OVERRIDE; -protected: - IntVariable(ParserContext* ctx, bool polyphonic, bool bConst, vmint size = 1); }; typedef Ref IntVariableRef; -class RealVariable : public ScalarNumberVariable, virtual public RealExpr { +class RealVariable : public NumberVariable, virtual public RealExpr { public: - RealVariable(ParserContext* ctx); + RealVariable(const VariableDecl& decl); void assign(Expression* expr) OVERRIDE; vmfloat evalReal() OVERRIDE; void dump(int level = 0) OVERRIDE; -protected: - RealVariable(ParserContext* ctx, bool polyphonic, bool bConst, vmint size = 1); }; typedef Ref RealVariableRef; -class ConstIntVariable : public IntVariable { -public: - vmint value; +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; +}; - ConstIntVariable(vmint value); +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 ConstRealVariable : public RealVariable { -public: - vmfloat value; +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; +}; - ConstRealVariable(vmfloat value); +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 : public IntVariable { +class BuiltInIntVariable FINAL : public IntVariable { String name; VMIntPtr* ptr; public: @@ -250,35 +324,38 @@ bool isAssignable() const OVERRIDE { return ptr->isAssignable(); } void assign(Expression* expr) 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); + PolyphonicIntVariable(const VariableDecl& decl); void dump(int level = 0) OVERRIDE; }; typedef Ref PolyphonicIntVariableRef; -class PolyphonicRealVariable : public RealVariable { +class PolyphonicRealVariable FINAL : public RealVariable { public: - PolyphonicRealVariable(ParserContext* ctx); + PolyphonicRealVariable(const VariableDecl& decl); void dump(int level = 0) OVERRIDE; }; typedef Ref PolyphonicRealVariableRef; class IntArrayVariable : public Variable, virtual public IntArrayExpr { ArrayList values; + ArrayList unitFactors; public: IntArrayVariable(ParserContext* ctx, vmint size); IntArrayVariable(ParserContext* ctx, vmint size, ArgsRef values, bool _bConst = false); void assign(Expression* expr) OVERRIDE {} // ignore scalar assignment - String evalCastToStr() OVERRIDE { return ""; } // ignore scalar cast to string 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: @@ -286,17 +363,19 @@ }; typedef Ref IntArrayVariableRef; -class RealArrayVariable : public Variable, virtual public RealArrayExpr { +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 - String evalCastToStr() OVERRIDE { return ""; } // ignore scalar cast to string 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: @@ -304,37 +383,43 @@ }; typedef Ref RealArrayVariableRef; -class BuiltInIntArrayVariable : public IntArrayVariable { +class BuiltInIntArrayVariable FINAL : public IntArrayVariable { String name; VMInt8Array* array; public: BuiltInIntArrayVariable(const String& name, VMInt8Array* array); vmint arraySize() const OVERRIDE { return array->size; } vmint evalIntElement(vmuint i) OVERRIDE; - bool isAssignable() const OVERRIDE { return !array->readonly; } 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 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) OVERRIDE; vmint evalInt() OVERRIDE; + vmfloat unitFactor() const OVERRIDE; void dump(int level = 0) OVERRIDE; }; typedef Ref IntArrayElementRef; -class RealArrayElement : public RealVariable { +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; @@ -351,10 +436,9 @@ }; 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) OVERRIDE; String evalStr() OVERRIDE; @@ -373,73 +457,72 @@ }; typedef Ref BinaryOpRef; -class ScalarNumberBinaryOp : public BinaryOp, virtual public ScalarNumberExpr { +class NumberBinaryOp : public BinaryOp, virtual public NumberExpr { public: - ScalarNumberBinaryOp(ScalarNumberExprRef lhs, ScalarNumberExprRef rhs) : BinaryOp(lhs, rhs) { } - MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE; - StdUnit_t unitType() const OVERRIDE; + NumberBinaryOp(NumberExprRef lhs, NumberExprRef rhs) : BinaryOp(lhs, rhs) { } bool isFinal() const OVERRIDE; }; -typedef Ref ScalarNumberBinaryOpRef; +typedef Ref NumberBinaryOpRef; -class IntBinaryOp : public ScalarNumberBinaryOp, virtual public IntExpr { +class IntBinaryOp : public NumberBinaryOp, virtual public IntExpr { public: - IntBinaryOp(IntExprRef lhs, IntExprRef rhs) : ScalarNumberBinaryOp(lhs, rhs) { } + IntBinaryOp(IntExprRef lhs, IntExprRef rhs) : NumberBinaryOp(lhs, rhs) { } }; typedef Ref IntBinaryOpRef; -class VaritypeScalarBinaryOp : public ScalarNumberBinaryOp, virtual public IntExpr, virtual public RealExpr { +class VaritypeScalarBinaryOp : public NumberBinaryOp, virtual public IntExpr, virtual public RealExpr { public: - VaritypeScalarBinaryOp(ScalarNumberExprRef lhs, ScalarNumberExprRef rhs) : ScalarNumberBinaryOp(lhs, rhs) { } + VaritypeScalarBinaryOp(NumberExprRef lhs, NumberExprRef rhs) : NumberBinaryOp(lhs, rhs) { } ExprType_t exprType() const OVERRIDE; String evalCastToStr() OVERRIDE; }; typedef Ref VaritypeScalarBinaryOpRef; -class Add : public VaritypeScalarBinaryOp { +class Add FINAL : public VaritypeScalarBinaryOp { public: - Add(ScalarNumberExprRef lhs, ScalarNumberExprRef rhs) : VaritypeScalarBinaryOp(lhs, rhs) { } + 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 : public VaritypeScalarBinaryOp { +class Sub FINAL : public VaritypeScalarBinaryOp { public: - Sub(ScalarNumberExprRef lhs, ScalarNumberExprRef rhs) : VaritypeScalarBinaryOp(lhs, rhs) { } + 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 : public VaritypeScalarBinaryOp { +class Mul FINAL : public VaritypeScalarBinaryOp { public: - Mul(ScalarNumberExprRef lhs, ScalarNumberExprRef rhs) : VaritypeScalarBinaryOp(lhs, rhs) { } + Mul(NumberExprRef lhs, NumberExprRef rhs); vmint evalInt() OVERRIDE; vmfloat evalReal() OVERRIDE; + vmfloat unitFactor() const OVERRIDE; void dump(int level = 0) OVERRIDE; - MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE; - StdUnit_t unitType() const OVERRIDE; }; typedef Ref MulRef; -class Div : public VaritypeScalarBinaryOp { +class Div FINAL : public VaritypeScalarBinaryOp { public: - Div(ScalarNumberExprRef lhs, ScalarNumberExprRef rhs) : VaritypeScalarBinaryOp(lhs, rhs) { } + Div(NumberExprRef lhs, NumberExprRef rhs); vmint evalInt() OVERRIDE; vmfloat evalReal() OVERRIDE; void dump(int level = 0) OVERRIDE; - MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE; - StdUnit_t unitType() const OVERRIDE; + vmfloat unitFactor() const OVERRIDE; }; typedef Ref DivRef; -class Mod : public IntBinaryOp { +class Mod FINAL : public IntBinaryOp { public: - Mod(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs, rhs) { } + 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; @@ -452,7 +535,7 @@ // 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 OVERRIDE { return STMT_NOOP; } @@ -488,7 +571,7 @@ 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: @@ -505,9 +588,10 @@ 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; - MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE { return VM_NO_PREFIX; } - StdUnit_t unitType() const OVERRIDE { return VM_NO_UNIT; } + vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; } bool isFinal() const OVERRIDE { return false; } }; typedef Ref DynamicVariableCallRef; @@ -516,9 +600,9 @@ 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; vmint evalInt() OVERRIDE; @@ -530,17 +614,16 @@ ExprType_t exprType() const OVERRIDE; String evalCastToStr() OVERRIDE; bool isPolyphonic() const OVERRIDE { return args->isPolyphonic(); } - MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE { return VM_NO_PREFIX; } - StdUnit_t unitType() const OVERRIDE { return VM_NO_UNIT; } - bool isFinal() const OVERRIDE { return false; } + vmfloat unitFactor() const OVERRIDE; + bool isFinal() const OVERRIDE; protected: VMFnResult* execVMFn(); }; typedef Ref FunctionCallRef; -class NoFunctionCall : public FunctionCall { +class NoFunctionCall FINAL : public FunctionCall { public: - NoFunctionCall() : FunctionCall("nothing", new Args, NULL) {} + NoFunctionCall() : FunctionCall("nothing", new Args, NULL), Unit(VM_NO_UNIT) {} StmtType_t statementType() const OVERRIDE { return STMT_NOOP; } }; typedef Ref NoFunctionCallRef; @@ -557,7 +640,7 @@ }; typedef Ref EventHandlerRef; -class OnNote : public EventHandler { +class OnNote FINAL : public EventHandler { public: OnNote(StatementsRef statements) : EventHandler(statements) {} VMEventHandlerType_t eventHandlerType() const OVERRIDE { return VM_EVENT_HANDLER_NOTE; } @@ -565,7 +648,7 @@ }; typedef Ref OnNoteRef; -class OnInit : public EventHandler { +class OnInit FINAL : public EventHandler { public: OnInit(StatementsRef statements) : EventHandler(statements) {} VMEventHandlerType_t eventHandlerType() const OVERRIDE { return VM_EVENT_HANDLER_INIT; } @@ -573,7 +656,7 @@ }; typedef Ref OnInitRef; -class OnRelease : public EventHandler { +class OnRelease FINAL : public EventHandler { public: OnRelease(StatementsRef statements) : EventHandler(statements) {} VMEventHandlerType_t eventHandlerType() const OVERRIDE { return VM_EVENT_HANDLER_RELEASE; } @@ -581,7 +664,7 @@ }; typedef Ref OnReleaseRef; -class OnController : public EventHandler { +class OnController FINAL : public EventHandler { public: OnController(StatementsRef statements) : EventHandler(statements) {} VMEventHandlerType_t eventHandlerType() const OVERRIDE { return VM_EVENT_HANDLER_CONTROLLER; } @@ -589,7 +672,7 @@ }; typedef Ref OnControllerRef; -class EventHandlers : virtual public Node { +class EventHandlers FINAL : virtual public Node { std::vector args; public: EventHandlers(); @@ -603,7 +686,7 @@ }; typedef Ref EventHandlersRef; -class Assignment : public LeafStatement { +class Assignment FINAL : public LeafStatement { protected: VariableRef variable; ExpressionRef value; @@ -615,7 +698,7 @@ }; typedef Ref AssignmentRef; -class If : public BranchStatement { +class If FINAL : public BranchStatement { IntExprRef condition; StatementsRef ifStatements; StatementsRef elseStatements; @@ -631,15 +714,14 @@ }; 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: @@ -647,15 +729,11 @@ void dump(int level = 0) OVERRIDE; vmint evalBranch() OVERRIDE; Statements* branch(vmuint i) const OVERRIDE; - //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 OVERRIDE; }; typedef Ref SelectCaseRef; -class While : public Statement { +class While FINAL : public Statement { IntExprRef m_condition; StatementsRef m_statements; public: @@ -668,7 +746,7 @@ 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) {} @@ -679,21 +757,23 @@ }; 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) { } - vmint evalInt() OVERRIDE { return (expr) ? -expr->evalInt() : 0; } + 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(); } - MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE { return expr->unitPrefix(i); } - StdUnit_t unitType() const OVERRIDE { return expr->unitType(); } + 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: @@ -705,7 +785,7 @@ }; typedef Ref ConcatStringRef; -class Relation : public IntExpr { +class Relation FINAL : public IntExpr { public: enum Type { LESS_THAN, @@ -715,14 +795,12 @@ EQUAL, NOT_EQUAL }; - Relation(ExpressionRef lhs, Type type, ExpressionRef rhs) : - lhs(lhs), rhs(rhs), type(type) {} + 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(); } - MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE { return VM_NO_PREFIX; } - StdUnit_t unitType() const OVERRIDE { return VM_NO_UNIT; } + vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; } bool isFinal() const OVERRIDE { return false; } private: ExpressionRef lhs; @@ -731,74 +809,72 @@ }; typedef Ref RelationRef; -class Or : public IntBinaryOp { +class Or FINAL : public IntBinaryOp { public: - Or(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs,rhs) {} + 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 : public IntBinaryOp { +class BitwiseOr FINAL : public IntBinaryOp { public: - BitwiseOr(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs,rhs) {} + BitwiseOr(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs,rhs), Unit(VM_NO_UNIT) {} vmint evalInt() OVERRIDE; void dump(int level = 0) OVERRIDE; - MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE { return VM_NO_PREFIX; } - StdUnit_t unitType() const OVERRIDE { return VM_NO_UNIT; } + vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; } }; typedef Ref BitwiseOrRef; -class And : public IntBinaryOp { +class And FINAL : public IntBinaryOp { public: - And(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs,rhs) {} + 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 : public IntBinaryOp { +class BitwiseAnd FINAL : public IntBinaryOp { public: - BitwiseAnd(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs,rhs) {} + BitwiseAnd(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs,rhs), Unit(VM_NO_UNIT) {} vmint evalInt() OVERRIDE; void dump(int level = 0) OVERRIDE; - MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE { return VM_NO_PREFIX; } - StdUnit_t unitType() const OVERRIDE { return VM_NO_UNIT; } + 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) {} + 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(); } - MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE { return VM_NO_PREFIX; } - StdUnit_t unitType() const OVERRIDE { return VM_NO_UNIT; } + 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) {} + 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(); } - MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE { return VM_NO_PREFIX; } - StdUnit_t unitType() const OVERRIDE { return VM_NO_UNIT; } + vmfloat unitFactor() const OVERRIDE { return VM_NO_FACTOR; } bool isFinal() const OVERRIDE { return expr->isFinal(); } }; typedef Ref BitwiseNotRef; -class Final : virtual public IntExpr, virtual public RealExpr { - ScalarNumberExprRef expr; +class Final FINAL : virtual public IntExpr, virtual public RealExpr { + NumberExprRef expr; public: - Final(ScalarNumberExprRef expr) : expr(expr) {} + 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(); } @@ -806,13 +882,12 @@ void dump(int level = 0) OVERRIDE; bool isConstExpr() const OVERRIDE { return expr->isConstExpr(); } bool isPolyphonic() const OVERRIDE { return expr->isPolyphonic(); } - MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE { return expr->unitPrefix(i); } - StdUnit_t unitType() const OVERRIDE { return expr->unitType(); } + vmfloat unitFactor() const OVERRIDE { return expr->unitFactor(); } bool isFinal() const OVERRIDE { return true; } }; typedef Ref FinalRef; -class ParserContext : public VMParserContext { +class ParserContext FINAL : public VMParserContext { public: struct Error { String txt; @@ -835,8 +910,10 @@ vmint globalIntVarCount; vmint globalRealVarCount; vmint globalStrVarCount; + vmint globalUnitFactorCount; vmint polyphonicIntVarCount; vmint polyphonicRealVarCount; + vmint polyphonicUnitFactorCount; EventHandlersRef handlers; @@ -848,6 +925,7 @@ ArrayList* globalIntMemory; ArrayList* globalRealMemory; ArrayList* globalStrMemory; + ArrayList* globalUnitFactorMemory; vmint requiredMaxStackSize; VMFunctionProvider* functionProvider; @@ -857,8 +935,11 @@ ParserContext(VMFunctionProvider* parent) : scanner(NULL), is(NULL), 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) { @@ -890,7 +971,7 @@ void registerBuiltInDynVariables(const std::map& vars); }; -class ExecContext : public VMExecContext { +class ExecContext FINAL : public VMExecContext { public: struct StackFrame { Statement* statement; @@ -904,6 +985,7 @@ ArrayList polyphonicIntMemory; ArrayList polyphonicRealMemory; + ArrayList polyphonicUnitFactorMemory; VMExecStatus_t status; StmtFlags_t flags; ArrayList stack; @@ -913,9 +995,12 @@ struct ExitRes { Expression* value; IntLiteral intLiteral; + RealLiteral realLiteral; StringLiteral stringLiteral; - ExitRes() : intLiteral(0), stringLiteral("") { } + ExitRes() : + intLiteral({ .value = 0 }), realLiteral({ .value = 0.0 }), + stringLiteral("") { } } exitRes; ExecContext(); @@ -956,6 +1041,11 @@ 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 {