--- linuxsampler/trunk/src/scriptvm/tree.h 2016/04/19 14:07:53 2879 +++ linuxsampler/trunk/src/scriptvm/tree.h 2019/08/01 10:22:56 3551 @@ -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 { @@ -63,6 +66,13 @@ }; typedef Ref IntExprRef; +class IntArrayExpr : virtual public VMIntArrayExpr, virtual public Expression { +public: + ExprType_t exprType() const { return INT_ARR_EXPR; } + String evalCastToStr(); +}; +typedef Ref IntArrayExprRef; + class StringExpr : virtual public VMStringExpr, virtual public Expression { public: ExprType_t exprType() const { return STRING_EXPR; } @@ -72,8 +82,8 @@ typedef Ref StringExprRef; class IntLiteral : virtual public IntExpr { - int value; public: + int value; IntLiteral(int value) : value(value) { } int evalInt(); void dump(int level = 0); @@ -98,16 +108,18 @@ std::vector args; void add(ExpressionRef arg) { args.push_back(arg); } void dump(int level = 0); - int argsCount() const { return args.size(); } + int argsCount() const { return (int) args.size(); } VMExpr* arg(int i) { return (i >= 0 && i < argsCount()) ? &*args.at(i) : NULL; } bool isPolyphonic() const; }; typedef Ref ArgsRef; -class Variable : virtual public Expression { +class Variable : virtual public VMVariable, virtual public Expression { public: - virtual bool isConstExpr() const { return bConst; } + bool isConstExpr() const OVERRIDE { return bConst; } + bool isAssignable() const OVERRIDE { return !bConst; } 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) {} @@ -148,9 +160,10 @@ VMIntRelPtr* ptr; public: BuiltInIntVariable(const String& name, VMIntRelPtr* ptr); - void assign(Expression* expr); - int evalInt(); - void dump(int level = 0); + bool isAssignable() const OVERRIDE { return !ptr->readonly; } + void assign(Expression* expr) OVERRIDE; + int evalInt() OVERRIDE; + void dump(int level = 0) OVERRIDE; }; typedef Ref BuiltInIntVariableRef; @@ -161,11 +174,11 @@ }; typedef Ref PolyphonicIntVariableRef; -class IntArrayVariable : public Variable, virtual public VMIntArrayExpr { +class IntArrayVariable : public Variable, virtual public IntArrayExpr { ArrayList values; public: IntArrayVariable(ParserContext* ctx, int size); - IntArrayVariable(ParserContext* ctx, int size, ArgsRef values); + 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; } @@ -184,18 +197,19 @@ 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); + int arraySize() const OVERRIDE { return array->size; } + int evalIntElement(uint i) OVERRIDE; + bool isAssignable() const OVERRIDE { return !array->readonly; } + void assignIntElement(uint i, int 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); + IntArrayElement(IntArrayExprRef array, IntExprRef arrayIndex); void assign(Expression* expr); int evalInt(); void dump(int level = 0); @@ -287,7 +301,7 @@ class NoOperation : public Statement { public: NoOperation() : Statement() {} - StmtType_t statementType() const { return STMT_LEAF; } + StmtType_t statementType() const { return STMT_NOOP; } void dump(int level = 0) {} bool isPolyphonic() const { return false; } }; @@ -320,6 +334,27 @@ virtual Statements* branch(uint i) const = 0; }; +class DynamicVariableCall : public Variable, virtual public IntExpr, virtual public StringExpr, virtual public IntArrayExpr { + VMDynVar* dynVar; + String varName; +public: + DynamicVariableCall(const String& name, ParserContext* ctx, VMDynVar* v); + ExprType_t exprType() const OVERRIDE { return dynVar->exprType(); } + bool isConstExpr() const OVERRIDE { return dynVar->isConstExpr(); } + bool isAssignable() const OVERRIDE { return dynVar->isAssignable(); } + bool isPolyphonic() const OVERRIDE { return false; } + void assign(Expression* expr) OVERRIDE { dynVar->assignExpr(expr); } + VMIntArrayExpr* asIntArray() const OVERRIDE { return dynVar->asIntArray(); } + int 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) OVERRIDE { return dynVar->asIntArray()->assignIntElement(i, value); } + void dump(int level = 0) OVERRIDE; +}; +typedef Ref DynamicVariableCallRef; + class FunctionCall : virtual public LeafStatement, virtual public IntExpr, virtual public StringExpr { String functionName; ArgsRef args; @@ -327,19 +362,27 @@ 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; + int 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(); } protected: VMFnResult* execVMFn(); }; typedef Ref FunctionCallRef; +class NoFunctionCall : public FunctionCall { +public: + NoFunctionCall() : FunctionCall("nothing", new Args, NULL) {} + StmtType_t statementType() const { return STMT_NOOP; } +}; +typedef Ref NoFunctionCallRef; + class EventHandler : virtual public Statements, virtual public VMEventHandler { StatementsRef statements; bool usingPolyphonics; @@ -394,7 +437,7 @@ int evalInt() { return 0; } EventHandler* eventHandlerByName(const String& name) const; EventHandler* eventHandler(uint index) const; - inline uint size() const { return args.size(); } + inline uint size() const { return (int) args.size(); } bool isPolyphonic() const; }; typedef Ref EventHandlersRef; @@ -464,6 +507,17 @@ bool isPolyphonic() const { 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 { return STMT_SYNC; } + void dump(int level = 0); + Statements* statements() const; + bool isPolyphonic() const { return m_statements->isPolyphonic(); } +}; +typedef Ref SyncBlockRef; + class Neg : public IntExpr { IntExprRef expr; public: @@ -518,6 +572,14 @@ }; typedef Ref OrRef; +class BitwiseOr : virtual public BinaryOp, virtual public IntExpr { +public: + BitwiseOr(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs,rhs) {} + int evalInt(); + void dump(int level = 0); +}; +typedef Ref BitwiseOrRef; + class And : virtual public BinaryOp, virtual public IntExpr { public: And(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs,rhs) {} @@ -526,6 +588,14 @@ }; typedef Ref AndRef; +class BitwiseAnd : virtual public BinaryOp, virtual public IntExpr { +public: + BitwiseAnd(IntExprRef lhs, IntExprRef rhs) : BinaryOp(lhs,rhs) {} + int evalInt(); + void dump(int level = 0); +}; +typedef Ref BitwiseAndRef; + class Not : virtual public IntExpr { IntExprRef expr; public: @@ -537,6 +607,17 @@ }; typedef Ref NotRef; +class BitwiseNot : 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(); } +}; +typedef Ref BitwiseNotRef; + class ParserContext : public VMParserContext { public: struct Error { @@ -550,11 +631,13 @@ std::vector vErrors; std::vector vWarnings; std::vector vIssues; + std::vector vPreprocessorComments; std::set builtinPreprocessorConditions; std::set userPreprocessorConditions; std::map vartable; + std::map userFnTable; int globalIntVarCount; int globalStrVarCount; int polyphonicIntVarCount; @@ -586,8 +669,10 @@ IntVariableRef globalIntVar(const String& name); StringVariableRef globalStrVar(const String& name); VariableRef variableByName(const String& name); - void addErr(int line, const char* txt); - void addWrn(int line, const char* txt); + 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); @@ -596,11 +681,13 @@ 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 registerBuiltInIntArrayVariables(const std::map& vars); + void registerBuiltInDynVariables(const std::map& vars); }; class ExecContext : public VMExecContext { @@ -617,13 +704,20 @@ ArrayList polyphonicIntMemory; VMExecStatus_t status; + StmtFlags_t flags; ArrayList stack; int stackFrame; int 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) { @@ -645,11 +739,35 @@ stack[0].statement = NULL; stack[0].subindex = -1; stackFrame = -1; + flags = STMT_SUCCESS; + } + + inline void clearExitRes() { + exitRes.value = NULL; } int suspensionTimeMicroseconds() const OVERRIDE { return suspendMicroseconds; } + + void resetPolyphonicData() OVERRIDE { + if (polyphonicIntMemory.empty()) return; + memset(&polyphonicIntMemory[0], 0, polyphonicIntMemory.size() * sizeof(int)); + } + + 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