/[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 3707 by schoenebeck, Wed Jan 8 21:21:58 2020 UTC revision 3845 by schoenebeck, Tue Jan 5 20:42:32 2021 UTC
# Line 13  Line 13 
13  #include "../common/global_private.h"  #include "../common/global_private.h"
14  #include "../common/RTMath.h"  #include "../common/RTMath.h"
15  #include <assert.h>  #include <assert.h>
16    #include "CoreVMFunctions.h" // for VMIntResult, VMRealResult
17    
18  namespace LinuxSampler {  namespace LinuxSampler {
19            
# Line 122  static String _unitFactorToShortStr(vmfl Line 123  static String _unitFactorToShortStr(vmfl
123      }      }
124  }  }
125    
126  static String _unitToStr(Unit* unit) {  static String _unitToStr(VMUnit* unit) {
127      const StdUnit_t type = unit->unitType();      const StdUnit_t type = unit->unitType();
128      String sType;      String sType;
129      switch (type) {      switch (type) {
# Line 500  StmtFlags_t Assignment::exec() { Line 501  StmtFlags_t Assignment::exec() {
501      return STMT_SUCCESS;      return STMT_SUCCESS;
502  }  }
503    
504  EventHandler::EventHandler(StatementsRef statements) {  Subroutine::Subroutine(StatementsRef statements) {
505      this->statements = statements;      this->statements = statements;
506    }
507    
508    void Subroutine::dump(int level) {
509        printIndents(level);
510        printf("Subroutine {\n");
511        statements->dump(level+1);
512        printIndents(level);
513        printf("}\n");
514    }
515    
516    UserFunction::UserFunction(StatementsRef statements)
517        : Subroutine(statements)
518    {
519    }
520    
521    EventHandler::EventHandler(StatementsRef statements)
522        : Subroutine(statements)
523    {
524      usingPolyphonics = statements->isPolyphonic();      usingPolyphonics = statements->isPolyphonic();
525  }  }
526    
527  void EventHandler::dump(int level) {  void EventHandler::dump(int level) {
528      printIndents(level);      printIndents(level);
529      printf("EventHandler {\n");      printf("EventHandler {\n");
530      statements->dump(level+1);      Subroutine::dump(level+1);
531      printIndents(level);      printIndents(level);
532      printf("}\n");      printf("}\n");
533  }  }
# Line 575  FunctionCall::FunctionCall(const char* f Line 594  FunctionCall::FunctionCall(const char* f
594      Unit(      Unit(
595          (fn) ? fn->returnUnitType(dynamic_cast<VMFnArgs*>(&*args)) : VM_NO_UNIT          (fn) ? fn->returnUnitType(dynamic_cast<VMFnArgs*>(&*args)) : VM_NO_UNIT
596      ),      ),
597      functionName(function), args(args), fn(fn), result(NULL)      functionName(function), args(args), fn(fn),
598        result( (fn) ? fn->allocResult(dynamic_cast<VMFnArgs*>(&*args)) : NULL )
599  {  {
600  }  }
601    
602    FunctionCall::~FunctionCall() {
603        if (result) {
604            delete result;
605            result = NULL;
606        }
607    }
608    
609  void FunctionCall::dump(int level) {  void FunctionCall::dump(int level) {
610      printIndents(level);      printIndents(level);
611      printf("FunctionCall '%s' args={\n", functionName.c_str());      printf("FunctionCall '%s' args={\n", functionName.c_str());
# Line 610  bool FunctionCall::isFinal() const { Line 637  bool FunctionCall::isFinal() const {
637    
638  VMFnResult* FunctionCall::execVMFn() {  VMFnResult* FunctionCall::execVMFn() {
639      if (!fn) return NULL;      if (!fn) return NULL;
640    
641        // tell function where it shall dump its return value to
642        VMFnResult* oldRes = fn->boundResult();
643        fn->bindResult(result);
644    
645      // assuming here that all argument checks (amount and types) have been made      // assuming here that all argument checks (amount and types) have been made
646      // at parse time, to avoid time intensive checks on each function call      // at parse time, to avoid time intensive checks on each function call
647      return fn->exec(dynamic_cast<VMFnArgs*>(&*args));      VMFnResult* res = fn->exec(dynamic_cast<VMFnArgs*>(&*args));
648    
649        // restore previous result binding of some potential toplevel or concurrent
650        // caller, i.e. if exactly same function is called more than one time,
651        // concurrently in a term by other FunctionCall objects, e.g.:
652        // ~c := ceil( ceil(~a) + ~b)
653        fn->bindResult(oldRes);
654    
655        if (!res) return res;
656    
657        VMExpr* expr = res->resultValue();
658        if (!expr) return res;
659    
660        // For performance reasons we always only let 'FunctionCall' assign the unit
661        // type to the function's result expression, never by the function
662        // implementation itself, nor by other classes, because a FunctionCall
663        // object solely knows the unit type in O(1).
664        ExprType_t type = expr->exprType();
665        if (type == INT_EXPR) {
666            VMIntResult* intRes = dynamic_cast<VMIntResult*>(res);
667            intRes->unitBaseType = unitType();
668        } else if (type == REAL_EXPR) {
669            VMRealResult* realRes = dynamic_cast<VMRealResult*>(res);
670            realRes->unitBaseType = unitType();
671        }
672    
673        return res;
674  }  }
675    
676  StmtFlags_t FunctionCall::exec() {  StmtFlags_t FunctionCall::exec() {
677      result = execVMFn();      VMFnResult* result = execVMFn();
678      if (!result)      if (!result)
679          return StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);          return StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
680      return result->resultFlags();      return result->resultFlags();
681  }  }
682    
683  vmint FunctionCall::evalInt() {  vmint FunctionCall::evalInt() {
684      result = execVMFn();      VMFnResult* result = execVMFn();
685      if (!result) return 0;      if (!result) return 0;
686      VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());      VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());
687      if (!intExpr) return 0;      if (!intExpr) return 0;
# Line 631  vmint FunctionCall::evalInt() { Line 689  vmint FunctionCall::evalInt() {
689  }  }
690    
691  vmfloat FunctionCall::evalReal() {  vmfloat FunctionCall::evalReal() {
692      result = execVMFn();      VMFnResult* result = execVMFn();
693      if (!result) return 0;      if (!result) return 0;
694      VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());      VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());
695      if (!realExpr) return 0;      if (!realExpr) return 0;
# Line 639  vmfloat FunctionCall::evalReal() { Line 697  vmfloat FunctionCall::evalReal() {
697  }  }
698    
699  VMIntArrayExpr* FunctionCall::asIntArray() const {  VMIntArrayExpr* FunctionCall::asIntArray() const {
700        //FIXME: asIntArray() not intended for evaluation semantics (for both
701        // performance reasons with arrays, but also to prevent undesired value
702        // mutation by implied (hidden) evaluation, as actually done here. We must
703        // force function evaluation here though, because we need it for function
704        // calls to be evaluated at all. This issue should be addressed cleanly by
705        // adjusting the API appropriately.
706        FunctionCall* rwSelf = const_cast<FunctionCall*>(this);
707        VMFnResult* result = rwSelf->execVMFn();
708    
709      if (!result) return 0;      if (!result) return 0;
710      VMIntArrayExpr* intArrExpr = dynamic_cast<VMIntArrayExpr*>(result->resultValue());      VMIntArrayExpr* intArrExpr = dynamic_cast<VMIntArrayExpr*>(result->resultValue());
711      return intArrExpr;      return intArrExpr;
712  }  }
713    
714  VMRealArrayExpr* FunctionCall::asRealArray() const {  VMRealArrayExpr* FunctionCall::asRealArray() const {
715        //FIXME: asRealArray() not intended for evaluation semantics (for both
716        // performance reasons with arrays, but also to prevent undesired value
717        // mutation by implied (hidden) evaluation, as actually done here. We must
718        // force function evaluation here though, because we need it for function
719        // calls to be evaluated at all. This issue should be addressed cleanly by
720        // adjusting the API appropriately.
721        FunctionCall* rwSelf = const_cast<FunctionCall*>(this);
722        VMFnResult* result = rwSelf->execVMFn();
723    
724      if (!result) return 0;      if (!result) return 0;
725      VMRealArrayExpr* realArrExpr = dynamic_cast<VMRealArrayExpr*>(result->resultValue());      VMRealArrayExpr* realArrExpr = dynamic_cast<VMRealArrayExpr*>(result->resultValue());
726      return realArrExpr;      return realArrExpr;
727  }  }
728    
729  String FunctionCall::evalStr() {  String FunctionCall::evalStr() {
730      result = execVMFn();      VMFnResult* result = execVMFn();
731      if (!result) return "";      if (!result) return "";
732      VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());      VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());
733      if (!strExpr) return "";      if (!strExpr) return "";
# Line 659  String FunctionCall::evalStr() { Line 735  String FunctionCall::evalStr() {
735  }  }
736    
737  String FunctionCall::evalCastToStr() {  String FunctionCall::evalCastToStr() {
738      result = execVMFn();      VMFnResult* result = execVMFn();
739      if (!result) return "";      if (!result) return "";
740      const ExprType_t resultType = result->resultValue()->exprType();      const ExprType_t resultType = result->resultValue()->exprType();
741      if (resultType == STRING_EXPR) {      if (resultType == STRING_EXPR) {
# Line 667  String FunctionCall::evalCastToStr() { Line 743  String FunctionCall::evalCastToStr() {
743          return strExpr ? strExpr->evalStr() : "";          return strExpr ? strExpr->evalStr() : "";
744      } else if (resultType == REAL_EXPR) {      } else if (resultType == REAL_EXPR) {
745          VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());          VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());
746          return realExpr ? ToString(realExpr->evalReal()) : "";          return realExpr ? ToString(realExpr->evalReal()) + _unitToStr(realExpr) : "";
747      } else {      } else {
748          VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());          VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());
749          return intExpr ? ToString(intExpr->evalInt()) : "";          return intExpr ? ToString(intExpr->evalInt()) + _unitToStr(intExpr) : "";
750      }      }
751  }  }
752    
# Line 988  IntArrayVariable::IntArrayVariable(Parse Line 1064  IntArrayVariable::IntArrayVariable(Parse
1064          if (expr) {          if (expr) {
1065              this->values[i] = expr->evalInt();              this->values[i] = expr->evalInt();
1066              this->unitFactors[i] = expr->unitFactor();              this->unitFactors[i] = expr->unitFactor();
1067            } else {
1068                this->values[i] = 0;
1069                this->unitFactors[i] = VM_NO_FACTOR;
1070          }          }
1071      }      }
1072        for (vmint i = values->argsCount(); i < size; ++i) {
1073            this->values[i] = 0;
1074            this->unitFactors[i] = VM_NO_FACTOR;
1075        }
1076  }  }
1077    
1078  IntArrayVariable::IntArrayVariable(ParserContext* ctx, bool bConst) :  IntArrayVariable::IntArrayVariable(ParserContext* ctx, bool bConst) :
# Line 1080  RealArrayVariable::RealArrayVariable(Par Line 1163  RealArrayVariable::RealArrayVariable(Par
1163          if (expr) {          if (expr) {
1164              this->values[i] = expr->evalReal();              this->values[i] = expr->evalReal();
1165              this->unitFactors[i] = expr->unitFactor();              this->unitFactors[i] = expr->unitFactor();
1166            } else {
1167                this->values[i] = (vmfloat) 0;
1168                this->unitFactors[i] = VM_NO_FACTOR;
1169          }          }
1170      }      }
1171        for (vmint i = values->argsCount(); i < size; ++i) {
1172            this->values[i] = (vmfloat) 0;
1173            this->unitFactors[i] = VM_NO_FACTOR;
1174        }
1175  }  }
1176    
1177  RealArrayVariable::RealArrayVariable(ParserContext* ctx, bool bConst) :  RealArrayVariable::RealArrayVariable(ParserContext* ctx, bool bConst) :
# Line 1746  void Final::dump(int level) { Line 1836  void Final::dump(int level) {
1836      printf(")\n");      printf(")\n");
1837  }  }
1838    
1839  StatementsRef ParserContext::userFunctionByName(const String& name) {  UserFunctionRef ParserContext::userFunctionByName(const String& name) {
1840      if (!userFnTable.count(name)) {      if (!userFnTable.count(name)) {
1841          return StatementsRef();          return UserFunctionRef();
1842      }      }
1843      return userFnTable.find(name)->second;      return userFnTable.find(name)->second;
1844  }  }
# Line 1792  ParserContext::~ParserContext() { Line 1882  ParserContext::~ParserContext() {
1882          delete globalRealMemory;          delete globalRealMemory;
1883          globalRealMemory = NULL;          globalRealMemory = NULL;
1884      }      }
1885        for (void* data : vAutoFreeAfterParse)
1886            free(data);
1887        vAutoFreeAfterParse.clear();
1888  }  }
1889    
1890  void ParserContext::addErr(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt) {  void ParserContext::addErr(int firstLine, int lastLine, int firstColumn,
1891                               int lastColumn, int firstByte, int lengthBytes,
1892                               const char* txt)
1893    {
1894      ParserIssue e;      ParserIssue e;
1895      e.type = PARSER_ERROR;      e.type = PARSER_ERROR;
1896      e.txt = txt;      e.txt = txt;
# Line 1802  void ParserContext::addErr(int firstLine Line 1898  void ParserContext::addErr(int firstLine
1898      e.lastLine = lastLine;      e.lastLine = lastLine;
1899      e.firstColumn = firstColumn;      e.firstColumn = firstColumn;
1900      e.lastColumn = lastColumn;      e.lastColumn = lastColumn;
1901        e.firstByte = firstByte;
1902        e.lengthBytes = lengthBytes;
1903      vErrors.push_back(e);      vErrors.push_back(e);
1904      vIssues.push_back(e);      vIssues.push_back(e);
1905  }  }
1906    
1907  void ParserContext::addWrn(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt) {  void ParserContext::addWrn(int firstLine, int lastLine, int firstColumn,
1908                               int lastColumn, int firstByte, int lengthBytes,
1909                               const char* txt)
1910    {
1911      ParserIssue w;      ParserIssue w;
1912      w.type = PARSER_WARNING;      w.type = PARSER_WARNING;
1913      w.txt = txt;      w.txt = txt;
# Line 1814  void ParserContext::addWrn(int firstLine Line 1915  void ParserContext::addWrn(int firstLine
1915      w.lastLine = lastLine;      w.lastLine = lastLine;
1916      w.firstColumn = firstColumn;      w.firstColumn = firstColumn;
1917      w.lastColumn = lastColumn;      w.lastColumn = lastColumn;
1918        w.firstByte = firstByte;
1919        w.lengthBytes = lengthBytes;
1920      vWarnings.push_back(w);      vWarnings.push_back(w);
1921      vIssues.push_back(w);      vIssues.push_back(w);
1922  }  }
1923    
1924  void ParserContext::addPreprocessorComment(int firstLine, int lastLine, int firstColumn, int lastColumn) {  void ParserContext::addPreprocessorComment(int firstLine, int lastLine,
1925                                               int firstColumn, int lastColumn,
1926                                               int firstByte, int lengthBytes)
1927    {
1928      CodeBlock block;      CodeBlock block;
1929      block.firstLine = firstLine;      block.firstLine = firstLine;
1930      block.lastLine = lastLine;      block.lastLine = lastLine;
1931      block.firstColumn = firstColumn;      block.firstColumn = firstColumn;
1932      block.lastColumn = lastColumn;      block.lastColumn = lastColumn;
1933        block.firstByte = firstByte;
1934        block.lengthBytes = lengthBytes;
1935      vPreprocessorComments.push_back(block);      vPreprocessorComments.push_back(block);
1936  }  }
1937    
# Line 1846  bool ParserContext::isPreprocessorCondit Line 1954  bool ParserContext::isPreprocessorCondit
1954      return userPreprocessorConditions.count(name);      return userPreprocessorConditions.count(name);
1955  }  }
1956    
1957    void ParserContext::autoFreeAfterParse(void* data) {
1958        vAutoFreeAfterParse.push_back(data);
1959    }
1960    
1961  std::vector<ParserIssue> ParserContext::issues() const {  std::vector<ParserIssue> ParserContext::issues() const {
1962      return vIssues;      return vIssues;
1963  }  }
# Line 1928  ExecContext::ExecContext() : Line 2040  ExecContext::ExecContext() :
2040      exitRes.value = NULL;      exitRes.value = NULL;
2041  }  }
2042    
2043    void ExecContext::copyPolyphonicDataFrom(VMExecContext* ectx) {
2044        ExecContext* src = dynamic_cast<ExecContext*>(ectx);
2045    
2046        polyphonicIntMemory.copyFlatFrom(src->polyphonicIntMemory);
2047        polyphonicRealMemory.copyFlatFrom(src->polyphonicRealMemory);
2048    }
2049    
2050  void ExecContext::forkTo(VMExecContext* ectx) const {  void ExecContext::forkTo(VMExecContext* ectx) const {
2051      ExecContext* child = dynamic_cast<ExecContext*>(ectx);      ExecContext* child = dynamic_cast<ExecContext*>(ectx);
2052    

Legend:
Removed from v.3707  
changed lines
  Added in v.3845

  ViewVC Help
Powered by ViewVC