--- linuxsampler/trunk/src/scriptvm/tree.h 2016/07/14 00:22:26 2945 +++ linuxsampler/trunk/src/scriptvm/tree.h 2019/08/23 11:44:00 3561 @@ -1,6 +1,6 @@ /* -*- c++ -*- * - * Copyright (c) 2014 - 2016 Christian Schoenebeck and Andreas Persson + * Copyright (c) 2014 - 2019 Christian Schoenebeck and Andreas Persson * * http://www.linuxsampler.org * @@ -20,6 +20,7 @@ #include #include #include +#include // for memset() #include "../common/global.h" #include "../common/Ref.h" #include "../common/ArrayList.h" @@ -35,6 +36,8 @@ STMT_LIST, STMT_BRANCH, STMT_LOOP, + STMT_SYNC, + STMT_NOOP, }; class Node { @@ -57,28 +60,49 @@ class IntExpr : virtual public VMIntExpr, virtual public Expression { public: - ExprType_t exprType() const { return INT_EXPR; } - virtual int evalInt() = 0; - String evalCastToStr(); + ExprType_t exprType() const OVERRIDE { return INT_EXPR; } + String evalCastToStr() OVERRIDE; }; typedef Ref IntExprRef; +class IntArrayExpr : virtual public VMIntArrayExpr, virtual public Expression { +public: + ExprType_t exprType() const OVERRIDE { return INT_ARR_EXPR; } + String evalCastToStr() OVERRIDE; +}; +typedef Ref IntArrayExprRef; + 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; } +class Unit : virtual public VMUnit { + ArrayList prefix; + StdUnit_t unit; +public: + Unit() : unit(VM_NO_UNIT) {} + MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE; + 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 IntExprRef& src); +}; + +class IntLiteral : public Unit, virtual public IntExpr { + bool finalVal; +public: + vmint value; + IntLiteral(vmint value) : Unit(), + value(value), finalVal(false) { } + vmint evalInt() OVERRIDE; + 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; @@ -86,10 +110,10 @@ public: String value; 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; @@ -97,10 +121,10 @@ public: std::vector args; void add(ExpressionRef arg) { args.push_back(arg); } - void dump(int level = 0); - int argsCount() const { return 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; @@ -111,71 +135,75 @@ 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) + Variable(ParserContext* ctx, vmint _memPos, bool _bConst) : context(ctx), memPos(_memPos), bConst(_bConst) {} ParserContext* context; - int memPos; + vmint memPos; bool bConst; }; typedef Ref VariableRef; -class IntVariable : public Variable, virtual public IntExpr { +class IntVariable : public Variable, public Unit, virtual public IntExpr { bool polyphonic; + bool finalVal; public: IntVariable(ParserContext* ctx); - void assign(Expression* expr); - int evalInt(); - void dump(int level = 0); - bool isPolyphonic() const { return polyphonic; } + void assign(Expression* expr) OVERRIDE; + vmint evalInt() OVERRIDE; + void dump(int level = 0) OVERRIDE; + bool isPolyphonic() const OVERRIDE { return polyphonic; } + bool isFinal() const OVERRIDE { return finalVal; } + void setFinal(bool b = true) { finalVal = b; } protected: - IntVariable(ParserContext* ctx, bool polyphonic, bool bConst, int size = 1); + IntVariable(ParserContext* ctx, bool polyphonic, bool bConst, vmint size = 1); }; typedef Ref IntVariableRef; class ConstIntVariable : public IntVariable { public: - int value; + vmint value; - ConstIntVariable(int value); + ConstIntVariable(vmint value); //ConstIntVariable(ParserContext* ctx, int value = 0); - void assign(Expression* expr); - int evalInt(); - void dump(int level = 0); + void assign(Expression* expr) OVERRIDE; + vmint evalInt() OVERRIDE; + void dump(int level = 0) OVERRIDE; }; typedef Ref ConstIntVariableRef; class BuiltInIntVariable : public IntVariable { String name; - VMIntRelPtr* ptr; + VMIntPtr* ptr; public: - BuiltInIntVariable(const String& name, VMIntRelPtr* ptr); - void assign(Expression* expr); - int evalInt(); - void dump(int level = 0); + BuiltInIntVariable(const String& name, VMIntPtr* ptr); + bool isAssignable() const OVERRIDE { return ptr->isAssignable(); } + void assign(Expression* expr) OVERRIDE; + vmint evalInt() OVERRIDE; + void dump(int level = 0) OVERRIDE; }; typedef Ref BuiltInIntVariableRef; class PolyphonicIntVariable : public IntVariable { public: PolyphonicIntVariable(ParserContext* ctx); - void dump(int level = 0); + void dump(int level = 0) OVERRIDE; }; typedef Ref PolyphonicIntVariableRef; -class IntArrayVariable : public Variable, virtual public VMIntArrayExpr { - ArrayList values; +class IntArrayVariable : public Variable, virtual public IntArrayExpr { + ArrayList values; public: - IntArrayVariable(ParserContext* ctx, int size); - IntArrayVariable(ParserContext* ctx, int size, ArgsRef values); - 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 + 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; + void dump(int level = 0) OVERRIDE; + bool isPolyphonic() const OVERRIDE { return false; } protected: IntArrayVariable(ParserContext* ctx, bool bConst); }; @@ -186,31 +214,32 @@ VMInt8Array* array; public: BuiltInIntArrayVariable(const String& name, VMInt8Array* array); - int arraySize() const { return array->size; } - int evalIntElement(uint i); - void assignIntElement(uint i, int value); - void dump(int level = 0); + 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; + void dump(int level = 0) OVERRIDE; }; typedef Ref BuiltInIntArrayVariableRef; class IntArrayElement : public IntVariable { - IntArrayVariableRef array; + IntArrayExprRef array; IntExprRef index; public: - IntArrayElement(IntArrayVariableRef array, IntExprRef arrayIndex); - void assign(Expression* expr); - int evalInt(); - void dump(int level = 0); + IntArrayElement(IntArrayExprRef array, IntExprRef arrayIndex); + void assign(Expression* expr) OVERRIDE; + vmint evalInt() OVERRIDE; + void dump(int level = 0) OVERRIDE; }; typedef Ref IntArrayElementRef; 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); }; @@ -221,9 +250,9 @@ String value; 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; @@ -233,48 +262,61 @@ 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 IntBinaryOp : public BinaryOp, virtual public IntExpr { +public: + IntBinaryOp(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs, rhs) { } + MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE; + StdUnit_t unitType() const OVERRIDE; + bool isFinal() const OVERRIDE; +}; +typedef Ref IntBinaryOpRef; + +class Add : public IntBinaryOp { public: - Add(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs, rhs) { } - int evalInt(); - void dump(int level = 0); + Add(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs, rhs) { } + vmint evalInt() OVERRIDE; + void dump(int level = 0) OVERRIDE; }; typedef Ref AddRef; -class Sub : virtual public BinaryOp, virtual public IntExpr { +class Sub : public IntBinaryOp { public: - Sub(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs, rhs) { } - int evalInt(); - void dump(int level = 0); + Sub(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs, rhs) { } + vmint evalInt() OVERRIDE; + void dump(int level = 0) OVERRIDE; }; typedef Ref SubRef; -class Mul : virtual public BinaryOp, virtual public IntExpr { +class Mul : public IntBinaryOp { public: - Mul(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs, rhs) { } - int evalInt(); - void dump(int level = 0); + Mul(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs, rhs) { } + vmint evalInt() OVERRIDE; + void dump(int level = 0) OVERRIDE; + MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE; + StdUnit_t unitType() const OVERRIDE; }; typedef Ref MulRef; -class Div : virtual public BinaryOp, virtual public IntExpr { +class Div : public IntBinaryOp { public: - Div(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs, rhs) { } - int evalInt(); - void dump(int level = 0); + Div(IntExprRef lhs, IntExprRef rhs) : IntBinaryOp(lhs, rhs) { } + vmint evalInt() OVERRIDE; + void dump(int level = 0) OVERRIDE; + MetricPrefix_t unitPrefix(vmuint i) const OVERRIDE; + StdUnit_t unitType() const OVERRIDE; }; typedef Ref DivRef; -class Mod : virtual public BinaryOp, virtual public IntExpr { +class Mod : 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) { } + vmint evalInt() OVERRIDE; + void dump(int level = 0) OVERRIDE; }; typedef Ref ModRef; @@ -289,9 +331,9 @@ class NoOperation : 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; @@ -300,7 +342,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; @@ -308,21 +350,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 { +class DynamicVariableCall : public Variable, virtual public IntExpr, virtual public StringExpr, virtual public IntArrayExpr { VMDynVar* dynVar; String varName; public: @@ -332,10 +374,17 @@ bool isAssignable() const OVERRIDE { return dynVar->isAssignable(); } bool isPolyphonic() const OVERRIDE { return false; } void assign(Expression* expr) OVERRIDE { dynVar->assignExpr(expr); } - int evalInt() OVERRIDE; + VMIntArrayExpr* asIntArray() const OVERRIDE { return dynVar->asIntArray(); } + vmint evalInt() OVERRIDE; String evalStr() OVERRIDE; String evalCastToStr() OVERRIDE; + 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); } 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; } + bool isFinal() const OVERRIDE { return false; } }; typedef Ref DynamicVariableCallRef; @@ -346,60 +395,71 @@ public: FunctionCall(const char* function, ArgsRef args, VMFunction* fn) : functionName(function), args(args), fn(fn) { } - void dump(int level = 0); - StmtFlags_t exec(); - int evalInt(); - String evalStr(); - bool isConstExpr() const { return false; } - ExprType_t exprType() const; - String evalCastToStr(); - bool isPolyphonic() const { return args->isPolyphonic(); } + void dump(int level = 0) OVERRIDE; + StmtFlags_t exec() OVERRIDE; + vmint evalInt() OVERRIDE; + VMIntArrayExpr* asIntArray() 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(); } + 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; } protected: VMFnResult* execVMFn(); }; typedef Ref FunctionCallRef; +class NoFunctionCall : public FunctionCall { +public: + NoFunctionCall() : FunctionCall("nothing", new Args, NULL) {} + 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 { 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 { 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 { 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 { 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; @@ -409,12 +469,11 @@ 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 args.size(); } - bool isPolyphonic() const; + inline uint size() const { return (int) args.size(); } + bool isPolyphonic() const OVERRIDE; }; typedef Ref EventHandlersRef; @@ -424,9 +483,9 @@ 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; @@ -439,10 +498,10 @@ 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; @@ -459,14 +518,14 @@ 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 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; + bool isPolyphonic() const OVERRIDE; }; typedef Ref SelectCaseRef; @@ -476,21 +535,35 @@ 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 { + StatementsRef m_statements; +public: + SyncBlock(StatementsRef statements) : m_statements(statements) {} + StmtType_t statementType() const OVERRIDE { return STMT_SYNC; } + void dump(int level = 0) OVERRIDE; + Statements* statements() const; + bool isPolyphonic() const OVERRIDE { return m_statements->isPolyphonic(); } }; +typedef Ref SyncBlockRef; class Neg : public IntExpr { IntExprRef 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(); } + vmint evalInt() OVERRIDE { return (expr) ? -expr->evalInt() : 0; } + 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(); } + bool isFinal() const OVERRIDE { return expr->isFinal(); } }; typedef Ref NegRef; @@ -499,10 +572,10 @@ 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; @@ -518,10 +591,13 @@ }; 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(); } + 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; } + bool isFinal() const OVERRIDE { return false; } private: IntExprRef lhs; IntExprRef rhs; @@ -529,35 +605,39 @@ }; typedef Ref RelationRef; -class Or : virtual public BinaryOp, virtual public IntExpr { +class Or : 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) {} + vmint evalInt() OVERRIDE; + void dump(int level = 0) OVERRIDE; }; typedef Ref OrRef; -class BitwiseOr : virtual public BinaryOp, virtual public IntExpr { +class BitwiseOr : 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) {} + 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; } }; typedef Ref BitwiseOrRef; -class And : virtual public BinaryOp, virtual public IntExpr { +class And : 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) {} + vmint evalInt() OVERRIDE; + void dump(int level = 0) OVERRIDE; }; typedef Ref AndRef; -class BitwiseAnd : virtual public BinaryOp, virtual public IntExpr { +class BitwiseAnd : 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) {} + 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; } }; typedef Ref BitwiseAndRef; @@ -565,10 +645,13 @@ 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(); } + 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; } + bool isFinal() const OVERRIDE { return expr->isFinal(); } }; typedef Ref NotRef; @@ -576,13 +659,30 @@ 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(); } + 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; } + bool isFinal() const OVERRIDE { return expr->isFinal(); } }; typedef Ref BitwiseNotRef; +class Final : virtual public IntExpr { + IntExprRef expr; +public: + Final(IntExprRef expr) : 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 expr->unitPrefix(i); } + StdUnit_t unitType() const OVERRIDE { return expr->unitType(); } + bool isFinal() const OVERRIDE { return true; } +}; +typedef Ref FinalRef; + class ParserContext : public VMParserContext { public: struct Error { @@ -596,14 +696,16 @@ std::vector vErrors; std::vector vWarnings; std::vector vIssues; + std::vector vPreprocessorComments; std::set builtinPreprocessorConditions; std::set userPreprocessorConditions; std::map vartable; - int globalIntVarCount; - int globalStrVarCount; - int polyphonicIntVarCount; + std::map userFnTable; + vmint globalIntVarCount; + vmint globalStrVarCount; + vmint polyphonicIntVarCount; EventHandlersRef handlers; @@ -612,9 +714,9 @@ OnReleaseRef onRelease; OnControllerRef onController; - ArrayList* globalIntMemory; + ArrayList* globalIntMemory; ArrayList* globalStrMemory; - int requiredMaxStackSize; + vmint requiredMaxStackSize; VMFunctionProvider* functionProvider; @@ -632,8 +734,10 @@ IntVariableRef globalIntVar(const String& name); StringVariableRef globalStrVar(const String& name); VariableRef variableByName(const String& name); + StatementsRef userFunctionByName(const String& name); void addErr(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt); void addWrn(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt); + void addPreprocessorComment(int firstLine, int lastLine, int firstColumn, int lastColumn); void createScanner(std::istream* is); void destroyScanner(); bool setPreprocessorCondition(const char* name); @@ -642,10 +746,11 @@ std::vector issues() const OVERRIDE; std::vector errors() const OVERRIDE; std::vector warnings() const OVERRIDE; + 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); }; @@ -662,15 +767,22 @@ } }; - ArrayList polyphonicIntMemory; + ArrayList polyphonicIntMemory; VMExecStatus_t status; + StmtFlags_t flags; ArrayList stack; int stackFrame; - int suspendMicroseconds; + vmint suspendMicroseconds; + size_t instructionsCount; + struct ExitRes { + Expression* value; + IntLiteral intLiteral; + StringLiteral stringLiteral; - ExecContext() : - status(VM_EXEC_NOT_RUNNING), stackFrame(-1), suspendMicroseconds(0) {} + ExitRes() : intLiteral(0), stringLiteral("") { } + } exitRes; + ExecContext(); virtual ~ExecContext() {} inline void pushStack(Statement* stmt) { @@ -692,11 +804,35 @@ stack[0].statement = NULL; stack[0].subindex = -1; stackFrame = -1; + flags = STMT_SUCCESS; + } + + inline void clearExitRes() { + exitRes.value = NULL; } - int suspensionTimeMicroseconds() const OVERRIDE { + vmint suspensionTimeMicroseconds() const OVERRIDE { return suspendMicroseconds; } + + void resetPolyphonicData() OVERRIDE { + if (polyphonicIntMemory.empty()) return; + memset(&polyphonicIntMemory[0], 0, polyphonicIntMemory.size() * sizeof(vmint)); + } + + size_t instructionsPerformed() const OVERRIDE { + return instructionsCount; + } + + void signalAbort() OVERRIDE { + flags = StmtFlags_t(flags | STMT_ABORT_SIGNALLED); + } + + void forkTo(VMExecContext* ectx) const OVERRIDE; + + VMExpr* exitResult() OVERRIDE { + return exitRes.value; + } }; } // namespace LinuxSampler