/[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 3747 by schoenebeck, Sun Feb 16 11:31:46 2020 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 575  FunctionCall::FunctionCall(const char* f Line 576  FunctionCall::FunctionCall(const char* f
576      Unit(      Unit(
577          (fn) ? fn->returnUnitType(dynamic_cast<VMFnArgs*>(&*args)) : VM_NO_UNIT          (fn) ? fn->returnUnitType(dynamic_cast<VMFnArgs*>(&*args)) : VM_NO_UNIT
578      ),      ),
579      functionName(function), args(args), fn(fn), result(NULL)      functionName(function), args(args), fn(fn),
580        result( (fn) ? fn->allocResult(dynamic_cast<VMFnArgs*>(&*args)) : NULL )
581  {  {
582  }  }
583    
584    FunctionCall::~FunctionCall() {
585        if (result) {
586            delete result;
587            result = NULL;
588        }
589    }
590    
591  void FunctionCall::dump(int level) {  void FunctionCall::dump(int level) {
592      printIndents(level);      printIndents(level);
593      printf("FunctionCall '%s' args={\n", functionName.c_str());      printf("FunctionCall '%s' args={\n", functionName.c_str());
# Line 610  bool FunctionCall::isFinal() const { Line 619  bool FunctionCall::isFinal() const {
619    
620  VMFnResult* FunctionCall::execVMFn() {  VMFnResult* FunctionCall::execVMFn() {
621      if (!fn) return NULL;      if (!fn) return NULL;
622    
623        // tell function where it shall dump its return value to
624        VMFnResult* oldRes = fn->boundResult();
625        fn->bindResult(result);
626    
627      // assuming here that all argument checks (amount and types) have been made      // assuming here that all argument checks (amount and types) have been made
628      // at parse time, to avoid time intensive checks on each function call      // at parse time, to avoid time intensive checks on each function call
629      return fn->exec(dynamic_cast<VMFnArgs*>(&*args));      VMFnResult* res = fn->exec(dynamic_cast<VMFnArgs*>(&*args));
630    
631        // restore previous result binding of some potential toplevel or concurrent
632        // caller, i.e. if exactly same function is called more than one time,
633        // concurrently in a term by other FunctionCall objects, e.g.:
634        // ~c := ceil( ceil(~a) + ~b)
635        fn->bindResult(oldRes);
636    
637        if (!res) return res;
638    
639        VMExpr* expr = res->resultValue();
640        if (!expr) return res;
641    
642        // For performance reasons we always only let 'FunctionCall' assign the unit
643        // type to the function's result expression, never by the function
644        // implementation itself, nor by other classes, because a FunctionCall
645        // object solely knows the unit type in O(1).
646        ExprType_t type = expr->exprType();
647        if (type == INT_EXPR) {
648            VMIntResult* intRes = dynamic_cast<VMIntResult*>(res);
649            intRes->unitBaseType = unitType();
650        } else if (type == REAL_EXPR) {
651            VMRealResult* realRes = dynamic_cast<VMRealResult*>(res);
652            realRes->unitBaseType = unitType();
653        }
654    
655        return res;
656  }  }
657    
658  StmtFlags_t FunctionCall::exec() {  StmtFlags_t FunctionCall::exec() {
659      result = execVMFn();      VMFnResult* result = execVMFn();
660      if (!result)      if (!result)
661          return StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);          return StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
662      return result->resultFlags();      return result->resultFlags();
663  }  }
664    
665  vmint FunctionCall::evalInt() {  vmint FunctionCall::evalInt() {
666      result = execVMFn();      VMFnResult* result = execVMFn();
667      if (!result) return 0;      if (!result) return 0;
668      VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());      VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());
669      if (!intExpr) return 0;      if (!intExpr) return 0;
# Line 631  vmint FunctionCall::evalInt() { Line 671  vmint FunctionCall::evalInt() {
671  }  }
672    
673  vmfloat FunctionCall::evalReal() {  vmfloat FunctionCall::evalReal() {
674      result = execVMFn();      VMFnResult* result = execVMFn();
675      if (!result) return 0;      if (!result) return 0;
676      VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());      VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());
677      if (!realExpr) return 0;      if (!realExpr) return 0;
# Line 639  vmfloat FunctionCall::evalReal() { Line 679  vmfloat FunctionCall::evalReal() {
679  }  }
680    
681  VMIntArrayExpr* FunctionCall::asIntArray() const {  VMIntArrayExpr* FunctionCall::asIntArray() const {
682        //FIXME: asIntArray() not intended for evaluation semantics (for both
683        // performance reasons with arrays, but also to prevent undesired value
684        // mutation by implied (hidden) evaluation, as actually done here. We must
685        // force function evaluation here though, because we need it for function
686        // calls to be evaluated at all. This issue should be addressed cleanly by
687        // adjusting the API appropriately.
688        FunctionCall* rwSelf = const_cast<FunctionCall*>(this);
689        VMFnResult* result = rwSelf->execVMFn();
690    
691      if (!result) return 0;      if (!result) return 0;
692      VMIntArrayExpr* intArrExpr = dynamic_cast<VMIntArrayExpr*>(result->resultValue());      VMIntArrayExpr* intArrExpr = dynamic_cast<VMIntArrayExpr*>(result->resultValue());
693      return intArrExpr;      return intArrExpr;
694  }  }
695    
696  VMRealArrayExpr* FunctionCall::asRealArray() const {  VMRealArrayExpr* FunctionCall::asRealArray() const {
697        //FIXME: asRealArray() not intended for evaluation semantics (for both
698        // performance reasons with arrays, but also to prevent undesired value
699        // mutation by implied (hidden) evaluation, as actually done here. We must
700        // force function evaluation here though, because we need it for function
701        // calls to be evaluated at all. This issue should be addressed cleanly by
702        // adjusting the API appropriately.
703        FunctionCall* rwSelf = const_cast<FunctionCall*>(this);
704        VMFnResult* result = rwSelf->execVMFn();
705    
706      if (!result) return 0;      if (!result) return 0;
707      VMRealArrayExpr* realArrExpr = dynamic_cast<VMRealArrayExpr*>(result->resultValue());      VMRealArrayExpr* realArrExpr = dynamic_cast<VMRealArrayExpr*>(result->resultValue());
708      return realArrExpr;      return realArrExpr;
709  }  }
710    
711  String FunctionCall::evalStr() {  String FunctionCall::evalStr() {
712      result = execVMFn();      VMFnResult* result = execVMFn();
713      if (!result) return "";      if (!result) return "";
714      VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());      VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());
715      if (!strExpr) return "";      if (!strExpr) return "";
# Line 659  String FunctionCall::evalStr() { Line 717  String FunctionCall::evalStr() {
717  }  }
718    
719  String FunctionCall::evalCastToStr() {  String FunctionCall::evalCastToStr() {
720      result = execVMFn();      VMFnResult* result = execVMFn();
721      if (!result) return "";      if (!result) return "";
722      const ExprType_t resultType = result->resultValue()->exprType();      const ExprType_t resultType = result->resultValue()->exprType();
723      if (resultType == STRING_EXPR) {      if (resultType == STRING_EXPR) {
# Line 667  String FunctionCall::evalCastToStr() { Line 725  String FunctionCall::evalCastToStr() {
725          return strExpr ? strExpr->evalStr() : "";          return strExpr ? strExpr->evalStr() : "";
726      } else if (resultType == REAL_EXPR) {      } else if (resultType == REAL_EXPR) {
727          VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());          VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());
728          return realExpr ? ToString(realExpr->evalReal()) : "";          return realExpr ? ToString(realExpr->evalReal()) + _unitToStr(realExpr) : "";
729      } else {      } else {
730          VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());          VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());
731          return intExpr ? ToString(intExpr->evalInt()) : "";          return intExpr ? ToString(intExpr->evalInt()) + _unitToStr(intExpr) : "";
732      }      }
733  }  }
734    
# Line 1794  ParserContext::~ParserContext() { Line 1852  ParserContext::~ParserContext() {
1852      }      }
1853  }  }
1854    
1855  void ParserContext::addErr(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt) {  void ParserContext::addErr(int firstLine, int lastLine, int firstColumn,
1856                               int lastColumn, int firstByte, int lengthBytes,
1857                               const char* txt)
1858    {
1859      ParserIssue e;      ParserIssue e;
1860      e.type = PARSER_ERROR;      e.type = PARSER_ERROR;
1861      e.txt = txt;      e.txt = txt;
# Line 1802  void ParserContext::addErr(int firstLine Line 1863  void ParserContext::addErr(int firstLine
1863      e.lastLine = lastLine;      e.lastLine = lastLine;
1864      e.firstColumn = firstColumn;      e.firstColumn = firstColumn;
1865      e.lastColumn = lastColumn;      e.lastColumn = lastColumn;
1866        e.firstByte = firstByte;
1867        e.lengthBytes = lengthBytes;
1868      vErrors.push_back(e);      vErrors.push_back(e);
1869      vIssues.push_back(e);      vIssues.push_back(e);
1870  }  }
1871    
1872  void ParserContext::addWrn(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt) {  void ParserContext::addWrn(int firstLine, int lastLine, int firstColumn,
1873                               int lastColumn, int firstByte, int lengthBytes,
1874                               const char* txt)
1875    {
1876      ParserIssue w;      ParserIssue w;
1877      w.type = PARSER_WARNING;      w.type = PARSER_WARNING;
1878      w.txt = txt;      w.txt = txt;
# Line 1814  void ParserContext::addWrn(int firstLine Line 1880  void ParserContext::addWrn(int firstLine
1880      w.lastLine = lastLine;      w.lastLine = lastLine;
1881      w.firstColumn = firstColumn;      w.firstColumn = firstColumn;
1882      w.lastColumn = lastColumn;      w.lastColumn = lastColumn;
1883        w.firstByte = firstByte;
1884        w.lengthBytes = lengthBytes;
1885      vWarnings.push_back(w);      vWarnings.push_back(w);
1886      vIssues.push_back(w);      vIssues.push_back(w);
1887  }  }
1888    
1889  void ParserContext::addPreprocessorComment(int firstLine, int lastLine, int firstColumn, int lastColumn) {  void ParserContext::addPreprocessorComment(int firstLine, int lastLine,
1890                                               int firstColumn, int lastColumn,
1891                                               int firstByte, int lengthBytes)
1892    {
1893      CodeBlock block;      CodeBlock block;
1894      block.firstLine = firstLine;      block.firstLine = firstLine;
1895      block.lastLine = lastLine;      block.lastLine = lastLine;
1896      block.firstColumn = firstColumn;      block.firstColumn = firstColumn;
1897      block.lastColumn = lastColumn;      block.lastColumn = lastColumn;
1898        block.firstByte = firstByte;
1899        block.lengthBytes = lengthBytes;
1900      vPreprocessorComments.push_back(block);      vPreprocessorComments.push_back(block);
1901  }  }
1902    

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

  ViewVC Help
Powered by ViewVC