/[svn]/linuxsampler/trunk/src/scriptvm/tree.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/scriptvm/tree.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2588 by schoenebeck, Sun Jun 1 14:44:38 2014 UTC revision 3551 by schoenebeck, Thu Aug 1 10:22:56 2019 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (c) 2014 Christian Schoenebeck and Andreas Persson   * Copyright (c) 2014 - 2019 Christian Schoenebeck and Andreas Persson
3   *   *
4   * http://www.linuxsampler.org   * http://www.linuxsampler.org
5   *   *
# Line 16  Line 16 
16  namespace LinuxSampler {  namespace LinuxSampler {
17            
18  bool isNoOperation(StatementRef statement) {  bool isNoOperation(StatementRef statement) {
19      NoOperation* noOp = dynamic_cast<NoOperation*>(&*statement);      return statement->statementType() == STMT_NOOP;
     return noOp;  
20  }  }
21            
22  Node::Node() {  Node::Node() {
# Line 35  String IntExpr::evalCastToStr() { Line 34  String IntExpr::evalCastToStr() {
34      return ToString(evalInt());      return ToString(evalInt());
35  }  }
36    
37    String IntArrayExpr::evalCastToStr() {
38        String s = "{";
39        for (int i = 0; i < arraySize(); ++i) {
40            int val = evalIntElement(i);
41            if (i) s += ",";
42            s += ToString(val);
43        }
44        s += "}";
45        return s;
46    }
47    
48  int IntLiteral::evalInt() {  int IntLiteral::evalInt() {
49      return value;      return value;
50  }  }
# Line 102  void Mul::dump(int level) { Line 112  void Mul::dump(int level) {
112    
113  int Div::evalInt() {  int Div::evalInt() {
114      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
115      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
116      return (pLHS && pRHS) ? pRHS->evalInt() == 0 ? 0 : pLHS->evalInt() / pRHS->evalInt() : 0;      if (!pLHS || !pRHS) return 0;
117        int l = pLHS->evalInt();
118        int r = pRHS->evalInt();
119        if (r == 0) return 0;
120        return l / r;
121  }  }
122    
123  void Div::dump(int level) {  void Div::dump(int level) {
# Line 144  void Args::dump(int level) { Line 158  void Args::dump(int level) {
158      printf(")\n");      printf(")\n");
159  }  }
160    
161    bool Args::isPolyphonic() const {
162        for (int i = 0; i < args.size(); ++i)
163            if (args[i]->isPolyphonic())
164                return true;
165        return false;
166    }
167    
168  EventHandlers::EventHandlers() {  EventHandlers::EventHandlers() {
169      //printf("EventHandlers::Constructor 0x%lx\n", (long long)this);      //printf("EventHandlers::Constructor 0x%lx\n", (long long)this);
170  }  }
# Line 177  EventHandler* EventHandlers::eventHandle Line 198  EventHandler* EventHandlers::eventHandle
198      return const_cast<EventHandler*>(&*args.at(index));      return const_cast<EventHandler*>(&*args.at(index));
199  }  }
200    
201    bool EventHandlers::isPolyphonic() const {
202        for (int i = 0; i < args.size(); ++i)
203            if (args[i]->isPolyphonic())
204                return true;
205        return false;
206    }
207    
208  Assignment::Assignment(VariableRef variable, ExpressionRef value)  Assignment::Assignment(VariableRef variable, ExpressionRef value)
209     : variable(variable), value(value)     : variable(variable), value(value)
210  {  {
# Line 194  StmtFlags_t Assignment::exec() { Line 222  StmtFlags_t Assignment::exec() {
222      return STMT_SUCCESS;      return STMT_SUCCESS;
223  }  }
224    
225    EventHandler::EventHandler(StatementsRef statements) {
226        this->statements = statements;
227        usingPolyphonics = statements->isPolyphonic();
228    }
229    
230  void EventHandler::dump(int level) {  void EventHandler::dump(int level) {
231      printIndents(level);      printIndents(level);
232      printf("EventHandler {\n");      printf("EventHandler {\n");
# Line 217  Statement* Statements::statement(uint i) Line 250  Statement* Statements::statement(uint i)
250      return &*args.at(i);      return &*args.at(i);
251  }  }
252    
253    bool Statements::isPolyphonic() const {
254        for (int i = 0; i < args.size(); ++i)
255            if (args[i]->isPolyphonic())
256                return true;
257        return false;
258    }
259    
260    DynamicVariableCall::DynamicVariableCall(const String& name, ParserContext* ctx, VMDynVar* v)
261        : Variable(ctx, 0, false), dynVar(v), varName(name)
262    {
263    }
264    
265    int DynamicVariableCall::evalInt() {
266        VMIntExpr* expr = dynamic_cast<VMIntExpr*>(dynVar);
267        if (!expr) return 0;
268        return expr->evalInt();
269    }
270    
271    String DynamicVariableCall::evalStr() {
272        VMStringExpr* expr = dynamic_cast<VMStringExpr*>(dynVar);
273        if (!expr) return "";
274        return expr->evalStr();
275    }
276    
277    String DynamicVariableCall::evalCastToStr() {
278        if (dynVar->exprType() == STRING_EXPR) {
279            return evalStr();
280        } else {
281            VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(dynVar);
282            return intExpr ? ToString(intExpr->evalInt()) : "";
283        }
284    }
285    
286    void DynamicVariableCall::dump(int level) {
287        printIndents(level);
288        printf("Dynamic Variable '%s'\n", varName.c_str());
289    }
290    
291  void FunctionCall::dump(int level) {  void FunctionCall::dump(int level) {
292      printIndents(level);      printIndents(level);
293      printf("FunctionCall '%s' args={\n", functionName.c_str());      printf("FunctionCall '%s' args={\n", functionName.c_str());
# Line 252  int FunctionCall::evalInt() { Line 323  int FunctionCall::evalInt() {
323      return intExpr->evalInt();      return intExpr->evalInt();
324  }  }
325    
326    VMIntArrayExpr* FunctionCall::asIntArray() const {
327        VMFnResult* result = const_cast<FunctionCall*>(this)->execVMFn();
328        if (!result) return 0;
329        VMIntArrayExpr* intArrExpr = dynamic_cast<VMIntArrayExpr*>(result->resultValue());
330        return intArrExpr;
331    }
332    
333  String FunctionCall::evalStr() {  String FunctionCall::evalStr() {
334      VMFnResult* result = execVMFn();      VMFnResult* result = execVMFn();
335      if (!result) return "";      if (!result) return "";
# Line 298  IntVariable::IntVariable(ParserContext* Line 376  IntVariable::IntVariable(ParserContext*
376    
377  void IntVariable::assign(Expression* expr) {  void IntVariable::assign(Expression* expr) {
378      IntExpr* intExpr = dynamic_cast<IntExpr*>(expr);      IntExpr* intExpr = dynamic_cast<IntExpr*>(expr);
379      if (intExpr)      if (intExpr) {
380          if (polyphonic)          if (polyphonic)
381              context->execContext->polyphonicIntMemory[memPos] = intExpr->evalInt();              context->execContext->polyphonicIntMemory[memPos] = intExpr->evalInt();
382          else          else
383              (*context->globalIntMemory)[memPos] = intExpr->evalInt();              (*context->globalIntMemory)[memPos] = intExpr->evalInt();
384        }
385  }  }
386    
387  int IntVariable::evalInt() {  int IntVariable::evalInt() {
# Line 316  int IntVariable::evalInt() { Line 395  int IntVariable::evalInt() {
395    
396  void IntVariable::dump(int level) {  void IntVariable::dump(int level) {
397      printIndents(level);      printIndents(level);
398        printf("IntVariable\n");
399      //printf("IntVariable memPos=%d\n", memPos);      //printf("IntVariable memPos=%d\n", memPos);
400  }  }
401    
# Line 345  void ConstIntVariable::dump(int level) { Line 425  void ConstIntVariable::dump(int level) {
425      printf("ConstIntVariable val=%d\n", value);      printf("ConstIntVariable val=%d\n", value);
426  }  }
427    
428    BuiltInIntVariable::BuiltInIntVariable(const String& name, VMIntRelPtr* ptr)
429        : IntVariable(NULL,false,false), name(name), ptr(ptr)
430    {
431    }
432    
433    void BuiltInIntVariable::assign(Expression* expr) {
434        IntExpr* valueExpr = dynamic_cast<IntExpr*>(expr);
435        if (!valueExpr) return;
436        ptr->assign(valueExpr->evalInt());
437    }
438    
439    int BuiltInIntVariable::evalInt() {
440        return ptr->evalInt();
441    }
442    
443    void BuiltInIntVariable::dump(int level) {
444        printIndents(level);
445        printf("Built-in IntVar '%s'\n", name.c_str());
446    }
447    
448  PolyphonicIntVariable::PolyphonicIntVariable(ParserContext* ctx)  PolyphonicIntVariable::PolyphonicIntVariable(ParserContext* ctx)
449      : IntVariable(ctx,true,false)      : IntVariable(ctx,true,false)
450  {  {
# Line 362  IntArrayVariable::IntArrayVariable(Parse Line 462  IntArrayVariable::IntArrayVariable(Parse
462      memset(&values[0], 0, size * sizeof(int));      memset(&values[0], 0, size * sizeof(int));
463  }  }
464    
465  IntArrayVariable::IntArrayVariable(ParserContext* ctx, int size, ArgsRef values)  IntArrayVariable::IntArrayVariable(ParserContext* ctx, int size, ArgsRef values, bool _bConst)
466      : Variable(ctx, 0, false)      : Variable(ctx, 0, _bConst)
467  {  {
468      this->values.resize(size);      this->values.resize(size);
469      for (int i = 0; i < values->argsCount(); ++i) {      for (int i = 0; i < values->argsCount(); ++i) {
# Line 372  IntArrayVariable::IntArrayVariable(Parse Line 472  IntArrayVariable::IntArrayVariable(Parse
472      }      }
473  }  }
474    
475    IntArrayVariable::IntArrayVariable(ParserContext* ctx, bool bConst)
476        : Variable(ctx, 0, bConst)
477    {
478    }
479    
480  int IntArrayVariable::evalIntElement(uint i) {  int IntArrayVariable::evalIntElement(uint i) {
481      if (i >= values.size()) return 0;      if (i >= values.size()) return 0;
482      return values[i];      return values[i];
# Line 396  void IntArrayVariable::dump(int level) { Line 501  void IntArrayVariable::dump(int level) {
501      printf(")\n");      printf(")\n");
502  }  }
503    
504  IntArrayElement::IntArrayElement(IntArrayVariableRef array, IntExprRef arrayIndex)  BuiltInIntArrayVariable::BuiltInIntArrayVariable(const String& name, VMInt8Array* array)
505        : IntArrayVariable(NULL, false), name(name), array(array)
506    {
507    }
508    
509    int BuiltInIntArrayVariable::evalIntElement(uint i) {
510        return i >= array->size ? 0 : array->data[i];
511    }
512    
513    void BuiltInIntArrayVariable::assignIntElement(uint i, int value) {
514        if (i >= array->size) return;
515        array->data[i] = value;
516    }
517    
518    void BuiltInIntArrayVariable::dump(int level) {
519        printIndents(level);
520        printf("Built-In Int Array Variable '%s'\n", name.c_str());
521    }
522    
523    IntArrayElement::IntArrayElement(IntArrayExprRef array, IntExprRef arrayIndex)
524      : IntVariable(NULL, false, false, 0), array(array), index(arrayIndex)      : IntVariable(NULL, false, false, 0), array(array), index(arrayIndex)
525  {      {    
526  }  }
# Line 493  Statements* If::branch(uint i) const { Line 617  Statements* If::branch(uint i) const {
617      return NULL;      return NULL;
618  }  }
619    
620    bool If::isPolyphonic() const {
621        if (condition->isPolyphonic() || ifStatements->isPolyphonic())
622            return true;
623        return elseStatements ? elseStatements->isPolyphonic() : false;
624    }
625    
626  void SelectCase::dump(int level) {  void SelectCase::dump(int level) {
627      printIndents(level);      printIndents(level);
628      if (select)      if (select)
# Line 543  Statements* SelectCase::branch(uint i) c Line 673  Statements* SelectCase::branch(uint i) c
673      return NULL;      return NULL;
674  }  }
675    
676    bool SelectCase::isPolyphonic() const {
677        if (select->isPolyphonic()) return true;
678        for (int i = 0; i < branches.size(); ++i)
679            if (branches[i].statements->isPolyphonic())
680                return true;
681        return false;
682    }
683    
684  // void Case::addBranch(IntExprRef condition, StatementsRef statements) {  // void Case::addBranch(IntExprRef condition, StatementsRef statements) {
685  //     CaseBranchRef b = new CaseBranchRef;  //     CaseBranchRef b = new CaseBranchRef;
686  //     b->from = condition;  //     b->from = condition;
# Line 585  bool While::evalLoopStartCondition() { Line 723  bool While::evalLoopStartCondition() {
723      return m_condition->evalInt();      return m_condition->evalInt();
724  }  }
725    
726    void SyncBlock::dump(int level) {
727        printIndents(level);
728        printf("sync {\n");
729        m_statements->dump(level+1);
730        printIndents(level);
731        printf("}\n");
732    }
733    
734    Statements* SyncBlock::statements() const {
735        return (m_statements) ? const_cast<Statements*>( &*m_statements ) : NULL;
736    }
737    
738  void Neg::dump(int level) {  void Neg::dump(int level) {
739      printIndents(level);      printIndents(level);
740      printf("Negative Expr\n");      printf("Negative Expr\n");
741  }  }
742    
743  String ConcatString::evalStr() {  String ConcatString::evalStr() {
744      return lhs->evalCastToStr() + rhs->evalCastToStr();      // temporaries required here to enforce the associative left (to right) order
745        // ( required for GCC and Visual Studio, see:
746        //   http://stackoverflow.com/questions/25842902/why-stdstring-concatenation-operator-works-like-right-associative-one
747        //   Personally I am not convinced that this is "not a bug" of the
748        //   compiler/STL implementation and the allegedly underlying "function call"
749        //   nature causing this is IMO no profound reason that the C++ language's
750        //   "+" operator's left associativity is ignored. -- Christian, 2016-07-14 )
751        String l = lhs->evalCastToStr();
752        String r = rhs->evalCastToStr();
753        return l + r;
754  }  }
755    
756  void ConcatString::dump(int level) {  void ConcatString::dump(int level) {
# Line 669  bool Relation::isConstExpr() const { Line 828  bool Relation::isConstExpr() const {
828    
829  int Or::evalInt() {  int Or::evalInt() {
830      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
831        if (pLHS->evalInt()) return 1;
832      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;
833      return pLHS->evalInt() || pRHS->evalInt();      return (pRHS->evalInt()) ? 1 : 0;
834  }  }
835    
836  void Or::dump(int level) {  void Or::dump(int level) {
# Line 684  void Or::dump(int level) { Line 844  void Or::dump(int level) {
844      printf(")\n");      printf(")\n");
845  }  }
846    
847    int BitwiseOr::evalInt() {
848        IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
849        IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
850        return pLHS->evalInt() | pRHS->evalInt();
851    }
852    
853    void BitwiseOr::dump(int level) {
854        printIndents(level);
855        printf("BitwiseOr(\n");
856        lhs->dump(level+1);
857        printIndents(level);
858        printf(",\n");
859        rhs->dump(level+1);
860        printIndents(level);
861        printf(")\n");
862    }
863    
864  int And::evalInt() {  int And::evalInt() {
865      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
866      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      if (!pLHS->evalInt()) return 0;
867      return pLHS->evalInt() && pRHS->evalInt();      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
868        return (pRHS->evalInt()) ? 1 : 0;
869  }  }
870    
871  void And::dump(int level) {  void And::dump(int level) {
# Line 701  void And::dump(int level) { Line 879  void And::dump(int level) {
879      printf(")\n");      printf(")\n");
880  }  }
881    
882    int BitwiseAnd::evalInt() {
883        IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
884        IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
885        return pLHS->evalInt() & pRHS->evalInt();
886    }
887    
888    void BitwiseAnd::dump(int level) {
889        printIndents(level);
890        printf("BitwiseAnd(\n");
891        lhs->dump(level+1);
892        printIndents(level);
893        printf(",\n");
894        rhs->dump(level+1);
895        printIndents(level);
896        printf(")\n");
897    }
898    
899  void Not::dump(int level) {  void Not::dump(int level) {
900      printIndents(level);      printIndents(level);
901      printf("Not(\n");      printf("Not(\n");
# Line 709  void Not::dump(int level) { Line 904  void Not::dump(int level) {
904      printf(")\n");      printf(")\n");
905  }  }
906    
907    void BitwiseNot::dump(int level) {
908        printIndents(level);
909        printf("BitwiseNot(\n");
910        expr->dump(level+1);
911        printIndents(level);
912        printf(")\n");
913    }
914    
915    StatementsRef ParserContext::userFunctionByName(const String& name) {
916        if (!userFnTable.count(name)) {
917            return StatementsRef();
918        }
919        return userFnTable.find(name)->second;
920    }
921    
922  VariableRef ParserContext::variableByName(const String& name) {  VariableRef ParserContext::variableByName(const String& name) {
923      if (!vartable.count(name)) {      if (!vartable.count(name)) {
924          return VariableRef();          return VariableRef();
# Line 742  ParserContext::~ParserContext() { Line 952  ParserContext::~ParserContext() {
952      }      }
953  }  }
954    
955  void ParserContext::addErr(int line, const char* txt) {  void ParserContext::addErr(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt) {
956      ParserIssue e;      ParserIssue e;
957      e.type = PARSER_ERROR;      e.type = PARSER_ERROR;
958      e.txt = txt;      e.txt = txt;
959      e.line = line;      e.firstLine = firstLine;
960        e.lastLine = lastLine;
961        e.firstColumn = firstColumn;
962        e.lastColumn = lastColumn;
963      vErrors.push_back(e);      vErrors.push_back(e);
964      vIssues.push_back(e);      vIssues.push_back(e);
965  }  }
966    
967  void ParserContext::addWrn(int line, const char* txt) {  void ParserContext::addWrn(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt) {
968      ParserIssue w;      ParserIssue w;
969      w.type = PARSER_WARNING;      w.type = PARSER_WARNING;
970      w.txt = txt;      w.txt = txt;
971      w.line = line;      w.firstLine = firstLine;
972        w.lastLine = lastLine;
973        w.firstColumn = firstColumn;
974        w.lastColumn = lastColumn;
975      vWarnings.push_back(w);      vWarnings.push_back(w);
976      vIssues.push_back(w);      vIssues.push_back(w);
977  }  }
978    
979    void ParserContext::addPreprocessorComment(int firstLine, int lastLine, int firstColumn, int lastColumn) {
980        CodeBlock block;
981        block.firstLine = firstLine;
982        block.lastLine = lastLine;
983        block.firstColumn = firstColumn;
984        block.lastColumn = lastColumn;
985        vPreprocessorComments.push_back(block);
986    }
987    
988  bool ParserContext::setPreprocessorCondition(const char* name) {  bool ParserContext::setPreprocessorCondition(const char* name) {
989      if (builtinPreprocessorConditions.count(name)) return false;      if (builtinPreprocessorConditions.count(name)) return false;
990      if (userPreprocessorConditions.count(name)) return false;      if (userPreprocessorConditions.count(name)) return false;
# Line 791  std::vector<ParserIssue> ParserContext:: Line 1016  std::vector<ParserIssue> ParserContext::
1016      return vWarnings;      return vWarnings;
1017  }  }
1018    
1019    std::vector<CodeBlock> ParserContext::preprocessorComments() const {
1020        return vPreprocessorComments;
1021    }
1022    
1023  VMEventHandler* ParserContext::eventHandler(uint index) {  VMEventHandler* ParserContext::eventHandler(uint index) {
1024      if (!handlers) return NULL;      if (!handlers) return NULL;
1025      return handlers->eventHandler(index);      return handlers->eventHandler(index);
# Line 801  VMEventHandler* ParserContext::eventHand Line 1030  VMEventHandler* ParserContext::eventHand
1030      return handlers->eventHandlerByName(name);      return handlers->eventHandlerByName(name);
1031  }  }
1032    
1033    void ParserContext::registerBuiltInConstIntVariables(const std::map<String,int>& vars) {
1034        for (std::map<String,int>::const_iterator it = vars.begin();
1035             it != vars.end(); ++it)
1036        {
1037            ConstIntVariableRef ref = new ConstIntVariable(it->second);
1038            vartable[it->first] = ref;
1039        }
1040    }
1041    
1042    void ParserContext::registerBuiltInIntVariables(const std::map<String,VMIntRelPtr*>& vars) {
1043        for (std::map<String,VMIntRelPtr*>::const_iterator it = vars.begin();
1044             it != vars.end(); ++it)
1045        {
1046            BuiltInIntVariableRef ref = new BuiltInIntVariable(it->first, it->second);
1047            vartable[it->first] = ref;
1048        }
1049    }
1050    
1051    void ParserContext::registerBuiltInIntArrayVariables(const std::map<String,VMInt8Array*>& vars) {
1052        for (std::map<String,VMInt8Array*>::const_iterator it = vars.begin();
1053             it != vars.end(); ++it)
1054        {
1055            BuiltInIntArrayVariableRef ref = new BuiltInIntArrayVariable(it->first, it->second);
1056            vartable[it->first] = ref;
1057        }
1058    }
1059    
1060    void ParserContext::registerBuiltInDynVariables(const std::map<String,VMDynVar*>& vars) {
1061        for (std::map<String,VMDynVar*>::const_iterator it = vars.begin();
1062             it != vars.end(); ++it)
1063        {
1064            DynamicVariableCallRef ref = new DynamicVariableCall(it->first, this, it->second);
1065            vartable[it->first] = ref;
1066        }
1067    }
1068    
1069    ExecContext::ExecContext() :
1070        status(VM_EXEC_NOT_RUNNING), flags(STMT_SUCCESS), stackFrame(-1),
1071        suspendMicroseconds(0), instructionsCount(0)
1072    {
1073        exitRes.value = NULL;
1074    }
1075    
1076    void ExecContext::forkTo(VMExecContext* ectx) const {
1077        ExecContext* child = dynamic_cast<ExecContext*>(ectx);
1078    
1079        child->polyphonicIntMemory.copyFlatFrom(polyphonicIntMemory);
1080        child->status = VM_EXEC_SUSPENDED;
1081        child->flags = STMT_SUCCESS;
1082        child->stack.copyFlatFrom(stack);
1083        child->stackFrame = stackFrame;
1084        child->suspendMicroseconds = 0;
1085        child->instructionsCount = 0;
1086    }
1087    
1088  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.2588  
changed lines
  Added in v.3551

  ViewVC Help
Powered by ViewVC