/[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 3576 by schoenebeck, Wed Aug 28 12:56:38 2019 UTC revision 3707 by schoenebeck, Wed Jan 8 21:21:58 2020 UTC
# Line 11  Line 11 
11  #include <string.h>  #include <string.h>
12  #include "tree.h"  #include "tree.h"
13  #include "../common/global_private.h"  #include "../common/global_private.h"
14    #include "../common/RTMath.h"
15  #include <assert.h>  #include <assert.h>
16    
17  namespace LinuxSampler {  namespace LinuxSampler {
# Line 18  namespace LinuxSampler { Line 19  namespace LinuxSampler {
19  bool isNoOperation(StatementRef statement) {  bool isNoOperation(StatementRef statement) {
20      return statement->statementType() == STMT_NOOP;      return statement->statementType() == STMT_NOOP;
21  }  }
22    
23    String acceptedArgTypesStr(VMFunction* fn, vmint iArg) {
24        static const ExprType_t allTypes[] = {
25            INT_EXPR,
26            INT_ARR_EXPR,
27            REAL_EXPR,
28            REAL_ARR_EXPR,
29            STRING_EXPR,
30            STRING_ARR_EXPR,
31        };
32        const size_t nTypes = sizeof(allTypes) / sizeof(ExprType_t);
33    
34        std::vector<ExprType_t> supportedTypes;
35        for (int iType = 0; iType < nTypes; ++iType) {
36            const ExprType_t& type = allTypes[iType];
37            if (fn->acceptsArgType(iArg, type))
38                supportedTypes.push_back(type);
39        }
40        assert(!supportedTypes.empty());
41    
42        if (supportedTypes.size() == 1) {
43            return typeStr(*supportedTypes.begin());
44        } else {
45            String s = "either ";
46            for (size_t i = 0; i < supportedTypes.size(); ++i) {
47                const ExprType_t& type = supportedTypes[i];
48                if (i == 0) {
49                    s += typeStr(type);
50                } else if (i == supportedTypes.size() - 1) {
51                    s += " or " + typeStr(type);
52                } else {
53                    s += ", " + typeStr(type);
54                }
55            }
56            return s;
57        }
58    }
59            
60  Node::Node() {  Node::Node() {
61  }  }
# Line 30  void Node::printIndents(int n) { Line 68  void Node::printIndents(int n) {
68      fflush(stdout);      fflush(stdout);
69  }  }
70    
71    vmint Unit::convIntToUnitFactor(vmint iValue, VMUnit* srcUnit, VMUnit* dstUnit) {
72        vmfloat f = (vmfloat) iValue;
73        vmfloat factor = srcUnit->unitFactor() / dstUnit->unitFactor();
74        if (sizeof(vmfloat) == sizeof(float))
75            return llroundf(f * factor);
76        else
77            return llround(f * factor);
78    }
79    
80    vmint Unit::convIntToUnitFactor(vmint iValue, vmfloat srcFactor, vmfloat dstFactor) {
81        vmfloat f = (vmfloat) iValue;
82        vmfloat factor = srcFactor / dstFactor;
83        if (sizeof(vmfloat) == sizeof(float))
84            return llroundf(f * factor);
85        else
86            return llround(f * factor);
87    }
88    
89    vmfloat Unit::convRealToUnitFactor(vmfloat fValue, VMUnit* srcUnit, VMUnit* dstUnit) {
90        vmfloat factor = srcUnit->unitFactor() / dstUnit->unitFactor();
91        return fValue * factor;
92    }
93    
94    vmfloat Unit::convRealToUnitFactor(vmfloat fValue, vmfloat srcFactor, vmfloat dstFactor) {
95        vmfloat factor = srcFactor / dstFactor;
96        return fValue * factor;
97    }
98    
99    vmint IntExpr::evalIntToUnitFactor(vmfloat unitFactor) {
100        vmfloat f = (vmfloat) evalInt();
101        vmfloat factor = this->unitFactor() / unitFactor;
102        if (sizeof(vmfloat) == sizeof(float))
103            return llroundf(f * factor);
104        else
105            return llround(f * factor);
106    }
107    
108    static String _unitFactorToShortStr(vmfloat unitFactor) {
109        const long int tens = lround( log10(unitFactor) );
110        switch (tens) {
111            case  3: return "k";  // kilo  = 10^3
112            case  2: return "h";  // hecto = 10^2
113            case  1: return "da"; // deca  = 10
114            case  0: return "" ;  //  --   = 1
115            case -1: return "d";  // deci  = 10^-1
116            case -2: return "c";  // centi = 10^-2 (this is also used for tuning "cents")
117            case -3: return "m";  // milli = 10^-3
118            case -4: return "md"; // milli deci = 10^-4
119            case -5: return "mc"; // milli centi = 10^-5 (this is also used for tuning "cents")
120            case -6: return "u";  // micro = 10^-6
121            default: return "*10^" + ToString(tens);
122        }
123    }
124    
125    static String _unitToStr(Unit* unit) {
126        const StdUnit_t type = unit->unitType();
127        String sType;
128        switch (type) {
129            case VM_NO_UNIT: break;
130            case VM_SECOND: sType = "s"; break;
131            case VM_HERTZ: sType = "Hz"; break;
132            case VM_BEL: sType = "B"; break;
133        }
134    
135        String prefix = _unitFactorToShortStr( unit->unitFactor() );
136    
137        return prefix + sType;
138    }
139    
140  String IntExpr::evalCastToStr() {  String IntExpr::evalCastToStr() {
141      return ToString(evalInt());      return ToString(evalInt()) + _unitToStr(this);
142    }
143    
144    vmfloat RealExpr::evalRealToUnitFactor(vmfloat unitFactor) {
145        vmfloat f = evalReal();
146        vmfloat factor = this->unitFactor() / unitFactor;
147        return f * factor;
148  }  }
149    
150  String RealExpr::evalCastToStr() {  String RealExpr::evalCastToStr() {
151      return ToString(evalReal());      return ToString(evalReal()) + _unitToStr(this);
152  }  }
153    
154  String IntArrayExpr::evalCastToStr() {  String IntArrayExpr::evalCastToStr() {
155      String s = "{";      String s = "{";
156      for (vmint i = 0; i < arraySize(); ++i) {      for (vmint i = 0; i < arraySize(); ++i) {
157          vmint val = evalIntElement(i);          vmint val = evalIntElement(i);
158            vmfloat factor = unitFactorOfElement(i);
159          if (i) s += ",";          if (i) s += ",";
160          s += ToString(val);          s += ToString(val) + _unitFactorToShortStr(factor);
161      }      }
162      s += "}";      s += "}";
163      return s;      return s;
# Line 53  String RealArrayExpr::evalCastToStr() { Line 167  String RealArrayExpr::evalCastToStr() {
167      String s = "{";      String s = "{";
168      for (vmint i = 0; i < arraySize(); ++i) {      for (vmint i = 0; i < arraySize(); ++i) {
169          vmfloat val = evalRealElement(i);          vmfloat val = evalRealElement(i);
170            vmfloat factor = unitFactorOfElement(i);
171          if (i) s += ",";          if (i) s += ",";
172          s += ToString(val);          s += ToString(val) + _unitFactorToShortStr(factor);
173      }      }
174      s += "}";      s += "}";
175      return s;      return s;
176  }  }
177    
178  MetricPrefix_t Unit::unitPrefix(vmuint i) const {  IntLiteral::IntLiteral(const IntLitDef& def) :
179      if (i >= prefix.size()) return VM_NO_PREFIX;      IntExpr(), Unit(def.unitType),
180      return prefix[i];      value(def.value), unitPrefixFactor(def.unitFactor),
181  }      finalVal(def.isFinal)
182    {
 void Unit::setUnit(const std::vector<MetricPrefix_t>& prefix, StdUnit_t type) {  
     this->prefix.resize( prefix.size() );  
     for (vmuint i = 0; i < prefix.size(); ++i)  
         this->prefix[i] = prefix[i];  
   
     unit = type;  
 }  
   
 void Unit::setUnit(const MetricPrefix_t* prefixes, StdUnit_t type) {  
     unit = type;  
     prefix.clear();  
     for (int i = 0; i < 2 && prefixes[i]; ++i)  
         prefix.add(prefixes[i]);  
 }  
   
 void Unit::copyUnitFrom(const UnitRef& src) {  
     unit = src->unitType();  
     prefix.clear();  
     for (int i = 0; true; ++i) {  
         MetricPrefix_t p = src->unitPrefix(i);  
         if (!p) return;  
         prefix.add(p);  
     }  
183  }  }
184    
185  vmint IntLiteral::evalInt() {  vmint IntLiteral::evalInt() {
# Line 96  vmint IntLiteral::evalInt() { Line 188  vmint IntLiteral::evalInt() {
188    
189  void IntLiteral::dump(int level) {  void IntLiteral::dump(int level) {
190      printIndents(level);      printIndents(level);
191      printf("IntLiteral %lld\n", value);      printf("IntLiteral %" PRId64 "\n", (int64_t)value);
192    }
193    
194    RealLiteral::RealLiteral(const RealLitDef& def) :
195        RealExpr(), Unit(def.unitType),
196        value(def.value), unitPrefixFactor(def.unitFactor),
197        finalVal(def.isFinal)
198    {
199  }  }
200    
201  vmfloat RealLiteral::evalReal() {  vmfloat RealLiteral::evalReal() {
# Line 113  void StringLiteral::dump(int level) { Line 212  void StringLiteral::dump(int level) {
212      printf("StringLiteral: '%s'\n", value.c_str());      printf("StringLiteral: '%s'\n", value.c_str());
213  }  }
214    
215    Add::Add(NumberExprRef lhs, NumberExprRef rhs) :
216        VaritypeScalarBinaryOp(lhs, rhs),
217        Unit(
218            // lhs and rhs are forced to be same unit type at parse time, so either one is fine here
219            (lhs) ? lhs->unitType() : VM_NO_UNIT
220        )
221    {
222    }
223    
224  vmint Add::evalInt() {  vmint Add::evalInt() {
225      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
226      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
227      return (pLHS && pRHS) ? pLHS->evalInt() + pRHS->evalInt() : 0;      if (!pLHS || !pRHS) return 0;
228        // eval*() call is required before calling unitFactor(), since the latter does not evaluate expressions!
229        vmint lvalue = pLHS->evalInt();
230        vmint rvalue = pRHS->evalInt();
231        if (pLHS->unitFactor() == pRHS->unitFactor())
232            return lvalue + rvalue;
233        if (pLHS->unitFactor() < pRHS->unitFactor())
234            return lvalue + Unit::convIntToUnitFactor(rvalue, pRHS, pLHS);
235        else
236            return Unit::convIntToUnitFactor(lvalue, pLHS, pRHS) + rvalue;
237  }  }
238    
239  vmfloat Add::evalReal() {  vmfloat Add::evalReal() {
240      RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);      RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
241      RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);;      RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);
242      return (pLHS && pRHS) ? pLHS->evalReal() + pRHS->evalReal() : 0;      if (!pLHS || !pRHS) return 0;
243        // eval*() call is required before calling unitFactor(), since the latter does not evaluate expressions!
244        vmfloat lvalue = pLHS->evalReal();
245        vmfloat rvalue = pRHS->evalReal();
246        if (pLHS->unitFactor() == pRHS->unitFactor())
247            return lvalue + rvalue;
248        if (pLHS->unitFactor() < pRHS->unitFactor())
249            return lvalue + Unit::convRealToUnitFactor(rvalue, pRHS, pLHS);
250        else
251            return Unit::convRealToUnitFactor(lvalue, pLHS, pRHS) + rvalue;
252    }
253    
254    vmfloat Add::unitFactor() const {
255        const NumberExpr* pLHS = dynamic_cast<const NumberExpr*>(&*lhs);
256        const NumberExpr* pRHS = dynamic_cast<const NumberExpr*>(&*rhs);
257        return (pLHS->unitFactor() < pRHS->unitFactor()) ? pLHS->unitFactor() : pRHS->unitFactor();
258  }  }
259    
260  void Add::dump(int level) {  void Add::dump(int level) {
# Line 136  void Add::dump(int level) { Line 268  void Add::dump(int level) {
268      printf(")\n");      printf(")\n");
269  }  }
270    
271    Sub::Sub(NumberExprRef lhs, NumberExprRef rhs) :
272        VaritypeScalarBinaryOp(lhs, rhs),
273        Unit(
274            // lhs and rhs are forced to be same unit type at parse time, so either one is fine here
275            (lhs) ? lhs->unitType() : VM_NO_UNIT
276        )
277    {
278    }
279    
280  vmint Sub::evalInt() {  vmint Sub::evalInt() {
281      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
282      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
283      return (pLHS && pRHS) ? pLHS->evalInt() - pRHS->evalInt() : 0;      if (!pLHS || !pRHS) return 0;
284        // eval*() call is required before calling unitFactor(), since the latter does not evaluate expressions!
285        vmint lvalue = pLHS->evalInt();
286        vmint rvalue = pRHS->evalInt();
287        if (pLHS->unitFactor() == pRHS->unitFactor())
288            return lvalue - rvalue;
289        if (pLHS->unitFactor() < pRHS->unitFactor())
290            return lvalue - Unit::convIntToUnitFactor(rvalue, pRHS, pLHS);
291        else
292            return Unit::convIntToUnitFactor(lvalue, pLHS, pRHS) - rvalue;
293  }  }
294    
295  vmfloat Sub::evalReal() {  vmfloat Sub::evalReal() {
296      RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);      RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
297      RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);;      RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);
298      return (pLHS && pRHS) ? pLHS->evalReal() - pRHS->evalReal() : 0;      if (!pLHS || !pRHS) return 0;
299        // eval*() call is required before calling unitFactor(), since the latter does not evaluate expressions!
300        vmfloat lvalue = pLHS->evalReal();
301        vmfloat rvalue = pRHS->evalReal();
302        if (pLHS->unitFactor() == pRHS->unitFactor())
303            return lvalue - rvalue;
304        if (pLHS->unitFactor() < pRHS->unitFactor())
305            return lvalue - Unit::convRealToUnitFactor(rvalue, pRHS, pLHS);
306        else
307            return Unit::convRealToUnitFactor(lvalue, pLHS, pRHS) - rvalue;
308    }
309    
310    vmfloat Sub::unitFactor() const {
311        const NumberExpr* pLHS = dynamic_cast<const NumberExpr*>(&*lhs);
312        const NumberExpr* pRHS = dynamic_cast<const NumberExpr*>(&*rhs);
313        return (pLHS->unitFactor() < pRHS->unitFactor()) ? pLHS->unitFactor() : pRHS->unitFactor();
314  }  }
315    
316  void Sub::dump(int level) {  void Sub::dump(int level) {
# Line 159  void Sub::dump(int level) { Line 324  void Sub::dump(int level) {
324      printf(")\n");      printf(")\n");
325  }  }
326    
327    Mul::Mul(NumberExprRef lhs, NumberExprRef rhs) :
328        VaritypeScalarBinaryOp(lhs, rhs),
329        Unit(
330            // currently the NKSP parser only allows a unit type on either side on multiplications
331            (lhs->unitType()) ? lhs->unitType() : rhs->unitType()
332        )
333    {
334    }
335    
336  vmint Mul::evalInt() {  vmint Mul::evalInt() {
337      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
338      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;
# Line 182  void Mul::dump(int level) { Line 356  void Mul::dump(int level) {
356      printf(")\n");      printf(")\n");
357  }  }
358    
359  MetricPrefix_t Mul::unitPrefix(vmuint i) const {  vmfloat Mul::unitFactor() const {
360      const ScalarNumberExpr* pLHS = dynamic_cast<const ScalarNumberExpr*>(&*lhs);      const NumberExpr* pLHS = dynamic_cast<const NumberExpr*>(&*lhs);
361      const ScalarNumberExpr* pRHS = dynamic_cast<const ScalarNumberExpr*>(&*rhs);      const NumberExpr* pRHS = dynamic_cast<const NumberExpr*>(&*rhs);
362      // currently the NKSP parser only allows a unit prefix on either side      return pLHS->unitFactor() * pRHS->unitFactor();
     return (pLHS->unitPrefix(0)) ? pLHS->unitPrefix(i) : pRHS->unitPrefix(i);  
363  }  }
364    
365  StdUnit_t Mul::unitType() const {  Div::Div(NumberExprRef lhs, NumberExprRef rhs) :
366      const ScalarNumberExpr* pLHS = dynamic_cast<const ScalarNumberExpr*>(&*lhs);      VaritypeScalarBinaryOp(lhs, rhs),
367      const ScalarNumberExpr* pRHS = dynamic_cast<const ScalarNumberExpr*>(&*rhs);      Unit(
368      // currently the NKSP parser only allows a unit type on either side          // the NKSP parser only allows either A) a unit type on left side and none
369      return (pLHS->unitType()) ? pLHS->unitType() : pRHS->unitType();          // on right side or B) an identical unit type on both sides
370            (lhs->unitType() && rhs->unitType()) ? VM_NO_UNIT : lhs->unitType()
371        )
372    {
373  }  }
374    
375  vmint Div::evalInt() {  vmint Div::evalInt() {
# Line 208  vmint Div::evalInt() { Line 384  vmint Div::evalInt() {
384    
385  vmfloat Div::evalReal() {  vmfloat Div::evalReal() {
386      RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);      RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
387      RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);;      RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);
388      if (!pLHS || !pRHS) return 0;      if (!pLHS || !pRHS) return 0;
389      vmfloat l = pLHS->evalReal();      vmfloat l = pLHS->evalReal();
390      vmfloat r = pRHS->evalReal();      vmfloat r = pRHS->evalReal();
# Line 227  void Div::dump(int level) { Line 403  void Div::dump(int level) {
403      printf(")\n");      printf(")\n");
404  }  }
405    
406  MetricPrefix_t Div::unitPrefix(vmuint i) const {  vmfloat Div::unitFactor() const {
407      const ScalarNumberExpr* pLHS = dynamic_cast<const ScalarNumberExpr*>(&*lhs);      const NumberExpr* pLHS = dynamic_cast<const NumberExpr*>(&*lhs);
408      const ScalarNumberExpr* pRHS = dynamic_cast<const ScalarNumberExpr*>(&*rhs);      const NumberExpr* pRHS = dynamic_cast<const NumberExpr*>(&*rhs);
409      // currently the NKSP parser only allows either A) a unit prefix on left      return pLHS->unitFactor() / pRHS->unitFactor();
     // side and none on right side or B) an identical unit prefix on both sides  
     return (pLHS->unitPrefix(0) && pRHS->unitPrefix(0)) ? VM_NO_PREFIX : pLHS->unitPrefix(i);  
 }  
   
 StdUnit_t Div::unitType() const {  
     const ScalarNumberExpr* pLHS = dynamic_cast<const ScalarNumberExpr*>(&*lhs);  
     const ScalarNumberExpr* pRHS = dynamic_cast<const ScalarNumberExpr*>(&*rhs);  
     // the NKSP parser only allows either A) a unit type on left side and none  
     // on right side or B) an identical unit type on both sides  
     return (pLHS->unitType() && pRHS->unitType()) ? VM_NO_UNIT : pLHS->unitType();  
410  }  }
411    
412  vmint Mod::evalInt() {  vmint Mod::evalInt() {
413      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
414      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
415      return (pLHS && pRHS) ? pLHS->evalInt() % pRHS->evalInt() : 0;      return (pLHS && pRHS) ? pLHS->evalInt() % pRHS->evalInt() : 0;
416  }  }
417    
# Line 369  bool Statements::isPolyphonic() const { Line 535  bool Statements::isPolyphonic() const {
535      return false;      return false;
536  }  }
537    
538  DynamicVariableCall::DynamicVariableCall(const String& name, ParserContext* ctx, VMDynVar* v)  DynamicVariableCall::DynamicVariableCall(const String& name, ParserContext* ctx, VMDynVar* v) :
539      : Variable(ctx, 0, false), dynVar(v), varName(name)      Variable({
540            .ctx = ctx,
541            .elements = 0
542        }),
543        Unit(VM_NO_UNIT),
544        dynVar(v), varName(name)
545  {  {
546  }  }
547    
# Line 400  void DynamicVariableCall::dump(int level Line 571  void DynamicVariableCall::dump(int level
571      printf("Dynamic Variable '%s'\n", varName.c_str());      printf("Dynamic Variable '%s'\n", varName.c_str());
572  }  }
573    
574    FunctionCall::FunctionCall(const char* function, ArgsRef args, VMFunction* fn) :
575        Unit(
576            (fn) ? fn->returnUnitType(dynamic_cast<VMFnArgs*>(&*args)) : VM_NO_UNIT
577        ),
578        functionName(function), args(args), fn(fn), result(NULL)
579    {
580    }
581    
582  void FunctionCall::dump(int level) {  void FunctionCall::dump(int level) {
583      printIndents(level);      printIndents(level);
584      printf("FunctionCall '%s' args={\n", functionName.c_str());      printf("FunctionCall '%s' args={\n", functionName.c_str());
# Line 410  void FunctionCall::dump(int level) { Line 589  void FunctionCall::dump(int level) {
589    
590  ExprType_t FunctionCall::exprType() const {  ExprType_t FunctionCall::exprType() const {
591      if (!fn) return EMPTY_EXPR;      if (!fn) return EMPTY_EXPR;
592      return fn->returnType();      FunctionCall* self = const_cast<FunctionCall*>(this);
593        return fn->returnType(dynamic_cast<VMFnArgs*>(&*self->args));
594    }
595    
596    vmfloat FunctionCall::unitFactor() const {
597        if (!fn || !result) return VM_NO_FACTOR;
598        VMExpr* expr = result->resultValue();
599        if (!expr) return VM_NO_FACTOR;
600        VMNumberExpr* scalar = expr->asNumber();
601        if (!scalar) return VM_NO_FACTOR;
602        return scalar->unitFactor();
603    }
604    
605    bool FunctionCall::isFinal() const {
606        if (!fn) return false;
607        FunctionCall* self = const_cast<FunctionCall*>(this);
608        return fn->returnsFinal(dynamic_cast<VMFnArgs*>(&*self->args));
609  }  }
610    
611  VMFnResult* FunctionCall::execVMFn() {  VMFnResult* FunctionCall::execVMFn() {
# Line 421  VMFnResult* FunctionCall::execVMFn() { Line 616  VMFnResult* FunctionCall::execVMFn() {
616  }  }
617    
618  StmtFlags_t FunctionCall::exec() {  StmtFlags_t FunctionCall::exec() {
619      VMFnResult* result = execVMFn();      result = execVMFn();
620      if (!result)      if (!result)
621          return StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);          return StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
622      return result->resultFlags();      return result->resultFlags();
623  }  }
624    
625  vmint FunctionCall::evalInt() {  vmint FunctionCall::evalInt() {
626      VMFnResult* result = execVMFn();      result = execVMFn();
627      if (!result) return 0;      if (!result) return 0;
628      VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());      VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());
629      if (!intExpr) return 0;      if (!intExpr) return 0;
# Line 436  vmint FunctionCall::evalInt() { Line 631  vmint FunctionCall::evalInt() {
631  }  }
632    
633  vmfloat FunctionCall::evalReal() {  vmfloat FunctionCall::evalReal() {
634      VMFnResult* result = execVMFn();      result = execVMFn();
635      if (!result) return 0;      if (!result) return 0;
636      VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());      VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());
637      if (!realExpr) return 0;      if (!realExpr) return 0;
# Line 444  vmfloat FunctionCall::evalReal() { Line 639  vmfloat FunctionCall::evalReal() {
639  }  }
640    
641  VMIntArrayExpr* FunctionCall::asIntArray() const {  VMIntArrayExpr* FunctionCall::asIntArray() const {
     VMFnResult* result = const_cast<FunctionCall*>(this)->execVMFn();  
642      if (!result) return 0;      if (!result) return 0;
643      VMIntArrayExpr* intArrExpr = dynamic_cast<VMIntArrayExpr*>(result->resultValue());      VMIntArrayExpr* intArrExpr = dynamic_cast<VMIntArrayExpr*>(result->resultValue());
644      return intArrExpr;      return intArrExpr;
645  }  }
646    
647  VMRealArrayExpr* FunctionCall::asRealArray() const {  VMRealArrayExpr* FunctionCall::asRealArray() const {
     VMFnResult* result = const_cast<FunctionCall*>(this)->execVMFn();  
648      if (!result) return 0;      if (!result) return 0;
649      VMRealArrayExpr* realArrExpr = dynamic_cast<VMRealArrayExpr*>(result->resultValue());      VMRealArrayExpr* realArrExpr = dynamic_cast<VMRealArrayExpr*>(result->resultValue());
650      return realArrExpr;      return realArrExpr;
651  }  }
652    
653  String FunctionCall::evalStr() {  String FunctionCall::evalStr() {
654      VMFnResult* result = execVMFn();      result = execVMFn();
655      if (!result) return "";      if (!result) return "";
656      VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());      VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());
657      if (!strExpr) return "";      if (!strExpr) return "";
# Line 466  String FunctionCall::evalStr() { Line 659  String FunctionCall::evalStr() {
659  }  }
660    
661  String FunctionCall::evalCastToStr() {  String FunctionCall::evalCastToStr() {
662      VMFnResult* result = execVMFn();      result = execVMFn();
663      if (!result) return "";      if (!result) return "";
664      const ExprType_t resultType = result->resultValue()->exprType();      const ExprType_t resultType = result->resultValue()->exprType();
665      if (resultType == STRING_EXPR) {      if (resultType == STRING_EXPR) {
# Line 481  String FunctionCall::evalCastToStr() { Line 674  String FunctionCall::evalCastToStr() {
674      }      }
675  }  }
676    
677  ScalarNumberVariable::ScalarNumberVariable(ParserContext* ctx, vmint _memPos,  Variable::Variable(const VariableDecl& decl) :
678                                             bool _bConst, bool _bPolyphonic,      context(decl.ctx), memPos(decl.memPos), bConst(decl.isConst)
                                            bool _bFinal)  
     : Variable(ctx, _memPos, _bConst),  
       Unit(),  
       polyphonic(_bPolyphonic), finalVal(_bFinal)  
679  {  {
680  }  }
681    
682  IntVariable::IntVariable(ParserContext* ctx)  NumberVariable::NumberVariable(const VariableDecl& decl) :
683      : ScalarNumberVariable(ctx, ctx ? ctx->globalIntVarCount++ : 0)      Variable(decl),
684        Unit(decl.unitType),
685        unitFactorMemPos(decl.unitFactorMemPos), polyphonic(decl.isPolyphonic),
686        finalVal(decl.isFinal)
687  {  {
688      //printf("globalIntVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);  }
689      assert(ctx);  
690    vmfloat NumberVariable::unitFactor() const {
691        if (isPolyphonic()) {
692            return context->execContext->polyphonicUnitFactorMemory[unitFactorMemPos];
693        }
694        return (*context->globalUnitFactorMemory)[unitFactorMemPos];
695  }  }
696    
697  inline static vmint postfixInc(vmint& object, vmint incBy) {  inline static vmint postfixInc(vmint& object, vmint incBy) {
# Line 503  inline static vmint postfixInc(vmint& ob Line 700  inline static vmint postfixInc(vmint& ob
700      return i;      return i;
701  }  }
702    
703  IntVariable::IntVariable(ParserContext* ctx, bool bPolyphonic, bool bConst, vmint size)  IntVariable::IntVariable(const VariableDecl& decl) :
704      : ScalarNumberVariable(      NumberVariable({
705            ctx,          .ctx = decl.ctx,
706            !ctx ? 0 : bPolyphonic ? postfixInc(ctx->polyphonicIntVarCount, size) :          .isPolyphonic = decl.isPolyphonic,
707                                     postfixInc(ctx->globalIntVarCount, size),          .isConst = decl.isConst,
708            bConst, bPolyphonic          .elements = decl.elements,
709        )          .memPos = (
710  {              (!decl.ctx) ? 0 :
711      //printf("IntVar size=%d parserCtx=0x%lx\n", size, (uint64_t)ctx);                  (decl.isPolyphonic) ?
712      if (bPolyphonic) {                      postfixInc(decl.ctx->polyphonicIntVarCount, decl.elements) :
713          //printf("polyIntVar memPOS=%d\n", memPos);                      postfixInc(decl.ctx->globalIntVarCount, decl.elements)
714          assert(ctx);          ),
715      }          .unitFactorMemPos = (
716                (!decl.ctx) ? 0 :
717                    (decl.isPolyphonic) ?
718                        postfixInc(decl.ctx->polyphonicUnitFactorCount, decl.elements) :
719                        postfixInc(decl.ctx->globalUnitFactorCount, decl.elements)
720            ),
721            .unitType = decl.unitType,
722            .isFinal = decl.isFinal,
723        }),
724        Unit(decl.unitType)
725    {
726        //printf("IntVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);
727        assert(!decl.isPolyphonic || decl.ctx);
728  }  }
729    
730  void IntVariable::assign(Expression* expr) {  void IntVariable::assign(Expression* expr) {
731      IntExpr* intExpr = dynamic_cast<IntExpr*>(expr);      IntExpr* intExpr = dynamic_cast<IntExpr*>(expr);
732      if (intExpr) {      if (intExpr) {
733          if (isPolyphonic())          //NOTE: sequence matters! evalInt() must be called before getting unitFactor() !
734            if (isPolyphonic()) {
735              context->execContext->polyphonicIntMemory[memPos] = intExpr->evalInt();              context->execContext->polyphonicIntMemory[memPos] = intExpr->evalInt();
736          else              context->execContext->polyphonicUnitFactorMemory[unitFactorMemPos] = intExpr->unitFactor();
737            } else {
738              (*context->globalIntMemory)[memPos] = intExpr->evalInt();              (*context->globalIntMemory)[memPos] = intExpr->evalInt();
739                (*context->globalUnitFactorMemory)[unitFactorMemPos] = intExpr->unitFactor();
740            }
741      }      }
742  }  }
743    
# Line 543  void IntVariable::dump(int level) { Line 756  void IntVariable::dump(int level) {
756      //printf("IntVariable memPos=%d\n", memPos);      //printf("IntVariable memPos=%d\n", memPos);
757  }  }
758    
759  RealVariable::RealVariable(ParserContext* ctx)  RealVariable::RealVariable(const VariableDecl& decl) :
760      : ScalarNumberVariable(ctx, ctx ? ctx->globalRealVarCount++ : 0)      NumberVariable({
761            .ctx = decl.ctx,
762            .isPolyphonic = decl.isPolyphonic,
763            .isConst = decl.isConst,
764            .elements = decl.elements,
765            .memPos = (
766                (!decl.ctx) ? 0 :
767                    (decl.isPolyphonic) ?
768                        postfixInc(decl.ctx->polyphonicRealVarCount, decl.elements) :
769                        postfixInc(decl.ctx->globalRealVarCount, decl.elements)
770            ),
771            .unitFactorMemPos = (
772                (!decl.ctx) ? 0 :
773                    (decl.isPolyphonic) ?
774                        postfixInc(decl.ctx->polyphonicUnitFactorCount, decl.elements) :
775                        postfixInc(decl.ctx->globalUnitFactorCount, decl.elements)
776            ),
777            .unitType = decl.unitType,
778            .isFinal = decl.isFinal,
779        }),
780        Unit(decl.unitType)
781  {  {
782      //printf("globalRealVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);      //printf("RealVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);
783      assert(ctx);      assert(!decl.isPolyphonic || decl.ctx);
 }  
   
 RealVariable::RealVariable(ParserContext* ctx, bool bPolyphonic, bool bConst, vmint size)  
     : ScalarNumberVariable(  
           ctx,  
           !ctx ? 0 : bPolyphonic ? postfixInc(ctx->polyphonicRealVarCount, size) :  
                                    postfixInc(ctx->globalRealVarCount, size),  
           bConst, bPolyphonic  
       )  
 {  
     //printf("RealVar size=%d parserCtx=0x%lx\n", size, (uint64_t)ctx);  
     if (bPolyphonic) {  
         //printf("polyRealVar memPOS=%d\n", memPos);  
         assert(ctx);  
     }  
784  }  }
785    
786  void RealVariable::assign(Expression* expr) {  void RealVariable::assign(Expression* expr) {
787      RealExpr* realExpr = dynamic_cast<RealExpr*>(expr);      RealExpr* realExpr = dynamic_cast<RealExpr*>(expr);
788      if (realExpr) {      if (realExpr) {
789          if (isPolyphonic())          //NOTE: sequence matters! evalReal() must be called before getting unitFactor() !
790            if (isPolyphonic()) {
791              context->execContext->polyphonicRealMemory[memPos] = realExpr->evalReal();              context->execContext->polyphonicRealMemory[memPos] = realExpr->evalReal();
792          else              context->execContext->polyphonicUnitFactorMemory[unitFactorMemPos] = realExpr->unitFactor();
793            } else {
794              (*context->globalRealMemory)[memPos] = realExpr->evalReal();              (*context->globalRealMemory)[memPos] = realExpr->evalReal();
795                (*context->globalUnitFactorMemory)[unitFactorMemPos] = realExpr->unitFactor();
796            }
797      }      }
798  }  }
799    
# Line 590  void RealVariable::dump(int level) { Line 812  void RealVariable::dump(int level) {
812      //printf("RealVariable memPos=%d\n", memPos);      //printf("RealVariable memPos=%d\n", memPos);
813  }  }
814    
815  ConstIntVariable::ConstIntVariable(vmint value)  ConstIntVariable::ConstIntVariable(const IntVarDef& def) :
816      : IntVariable(NULL,false,true), value(value)      IntVariable({
817            .ctx = def.ctx,
818            .isPolyphonic = false,
819            .isConst = true,
820            .elements = 1,
821            .memPos = def.memPos,
822            .unitFactorMemPos = def.unitFactorMemPos,
823            .unitType = def.unitType,
824            .isFinal = def.isFinal,
825        }),
826        Unit(def.unitType),
827        value(def.value), unitPrefixFactor(def.unitFactor)
828  {  {
829  }  }
830    
# Line 612  vmint ConstIntVariable::evalInt() { Line 845  vmint ConstIntVariable::evalInt() {
845    
846  void ConstIntVariable::dump(int level) {  void ConstIntVariable::dump(int level) {
847      printIndents(level);      printIndents(level);
848      printf("ConstIntVariable val=%lld\n", value);      printf("ConstIntVariable val=%" PRId64 "\n", (int64_t)value);
849  }  }
850    
851  ConstRealVariable::ConstRealVariable(vmfloat value)  ConstRealVariable::ConstRealVariable(const RealVarDef& def) :
852      : RealVariable(NULL,false,true), value(value)      RealVariable({
853            .ctx = def.ctx,
854            .isPolyphonic = false,
855            .isConst = true,
856            .elements = 1,
857            .memPos = def.memPos,
858            .unitFactorMemPos = def.unitFactorMemPos,
859            .unitType = def.unitType,
860            .isFinal = def.isFinal,
861        }),
862        Unit(def.unitType),
863        value(def.value), unitPrefixFactor(def.unitFactor)
864  {  {
865  }  }
866    
# Line 633  void ConstRealVariable::dump(int level) Line 877  void ConstRealVariable::dump(int level)
877      printf("ConstRealVariable val=%f\n", value);      printf("ConstRealVariable val=%f\n", value);
878  }  }
879    
880  BuiltInIntVariable::BuiltInIntVariable(const String& name, VMIntPtr* ptr)  BuiltInIntVariable::BuiltInIntVariable(const String& name, VMIntPtr* ptr) :
881      : IntVariable(NULL,false,false), name(name), ptr(ptr)      IntVariable({
882            .ctx = NULL,
883            .isPolyphonic = false,
884            .isConst = false, // may or may not be modifyable though!
885            .elements = 0,
886            .memPos = 0,
887            .unitFactorMemPos = 0,
888            .unitType = VM_NO_UNIT,
889            .isFinal = false,
890        }),
891        Unit(VM_NO_UNIT),
892        name(name), ptr(ptr)
893  {  {
894  }  }
895    
# Line 653  void BuiltInIntVariable::dump(int level) Line 908  void BuiltInIntVariable::dump(int level)
908      printf("Built-in IntVar '%s'\n", name.c_str());      printf("Built-in IntVar '%s'\n", name.c_str());
909  }  }
910    
911  PolyphonicIntVariable::PolyphonicIntVariable(ParserContext* ctx)  PolyphonicIntVariable::PolyphonicIntVariable(const VariableDecl& decl) :
912      : IntVariable(ctx,true,false)      IntVariable({
913            .ctx = decl.ctx,
914            .isPolyphonic = true,
915            .isConst = decl.isConst,
916            .elements = 1,
917            .memPos = 0,
918            .unitFactorMemPos = 0,
919            .unitType = decl.unitType,
920            .isFinal = decl.isFinal,
921        }),
922        Unit(decl.unitType)
923  {  {
924  }  }
925    
# Line 663  void PolyphonicIntVariable::dump(int lev Line 928  void PolyphonicIntVariable::dump(int lev
928      printf("PolyphonicIntVariable\n");      printf("PolyphonicIntVariable\n");
929  }  }
930    
931  PolyphonicRealVariable::PolyphonicRealVariable(ParserContext* ctx)  PolyphonicRealVariable::PolyphonicRealVariable(const VariableDecl& decl) :
932      : RealVariable(ctx,true,false)      RealVariable({
933            .ctx = decl.ctx,
934            .isPolyphonic = true,
935            .isConst = decl.isConst,
936            .elements = 1,
937            .memPos = 0,
938            .unitFactorMemPos = 0,
939            .unitType = decl.unitType,
940            .isFinal = decl.isFinal,
941        }),
942        Unit(decl.unitType)
943  {  {
944  }  }
945    
# Line 673  void PolyphonicRealVariable::dump(int le Line 948  void PolyphonicRealVariable::dump(int le
948      printf("PolyphonicRealVariable\n");      printf("PolyphonicRealVariable\n");
949  }  }
950    
951  IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size)  IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size) :
952      : Variable(ctx, 0, false)      Variable({
953            .ctx = ctx,
954            .isPolyphonic = false,
955            .isConst = false,
956            .elements = 0,
957            .memPos = 0,
958            .unitFactorMemPos = 0,
959            .unitType = VM_NO_UNIT,
960            .isFinal = false,
961        })
962  {  {
963      values.resize(size);      values.resize(size);
964      memset(&values[0], 0, size * sizeof(vmint));      memset(&values[0], 0, size * sizeof(vmint));
 }  
965    
966  IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size, ArgsRef values, bool _bConst)      unitFactors.resize(size);
967      : Variable(ctx, 0, _bConst)      for (size_t i = 0; i < size; ++i)
968            unitFactors[i] = VM_NO_FACTOR;
969    }
970    
971    IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size,
972                                       ArgsRef values, bool _bConst) :
973        Variable({
974            .ctx = ctx,
975            .isPolyphonic = false,
976            .isConst = _bConst,
977            .elements = 0,
978            .memPos = 0,
979            .unitFactorMemPos = 0,
980            .unitType = VM_NO_UNIT,
981            .isFinal = false,
982        })
983  {  {
984      this->values.resize(size);      this->values.resize(size);
985        this->unitFactors.resize(size);
986      for (vmint i = 0; i < values->argsCount(); ++i) {      for (vmint i = 0; i < values->argsCount(); ++i) {
987          VMIntExpr* expr = dynamic_cast<VMIntExpr*>(values->arg(i));          VMIntExpr* expr = dynamic_cast<VMIntExpr*>(values->arg(i));
988          if (expr) this->values[i] = expr->evalInt();          if (expr) {
989                this->values[i] = expr->evalInt();
990                this->unitFactors[i] = expr->unitFactor();
991            }
992      }      }
993  }  }
994    
995  IntArrayVariable::IntArrayVariable(ParserContext* ctx, bool bConst)  IntArrayVariable::IntArrayVariable(ParserContext* ctx, bool bConst) :
996      : Variable(ctx, 0, bConst)      Variable({
997            .ctx = ctx,
998            .isPolyphonic = false,
999            .isConst = bConst,
1000            .elements = 0,
1001            .memPos = 0,
1002            .unitFactorMemPos = 0,
1003            .unitType = VM_NO_UNIT,
1004            .isFinal = false,
1005        })
1006  {  {
1007  }  }
1008    
# Line 705  void IntArrayVariable::assignIntElement( Line 1016  void IntArrayVariable::assignIntElement(
1016      values[i] = value;      values[i] = value;
1017  }  }
1018    
1019    vmfloat IntArrayVariable::unitFactorOfElement(vmuint i) const {
1020        if (i >= unitFactors.size()) return VM_NO_FACTOR;
1021        return unitFactors[i];
1022    }
1023    
1024    void IntArrayVariable::assignElementUnitFactor(vmuint i, vmfloat factor) {
1025        if (i >= unitFactors.size()) return;
1026        unitFactors[i] = factor;
1027    }
1028    
1029  void IntArrayVariable::dump(int level) {  void IntArrayVariable::dump(int level) {
1030      printIndents(level);      printIndents(level);
1031      printf("IntArray(");      printf("IntArray(");
# Line 713  void IntArrayVariable::dump(int level) { Line 1034  void IntArrayVariable::dump(int level) {
1034              printf("\n");              printf("\n");
1035              printIndents(level+1);              printIndents(level+1);
1036          }          }
1037          printf("%lld, ", values[i]);          printf("%" PRId64 ", ", (int64_t)values[i]);
1038      }      }
1039      printIndents(level);      printIndents(level);
1040      printf(")\n");      printf(")\n");
1041  }  }
1042    
1043  RealArrayVariable::RealArrayVariable(ParserContext* ctx, vmint size)  RealArrayVariable::RealArrayVariable(ParserContext* ctx, vmint size) :
1044      : Variable(ctx, 0, false)      Variable({
1045            .ctx = ctx,
1046            .isPolyphonic = false,
1047            .isConst = false,
1048            .elements = 0,
1049            .memPos = 0,
1050            .unitFactorMemPos = 0,
1051            .unitType = VM_NO_UNIT,
1052            .isFinal = false,
1053        })
1054  {  {
1055      values.resize(size);      values.resize(size);
1056      memset(&values[0], 0, size * sizeof(vmfloat));      memset(&values[0], 0, size * sizeof(vmfloat));
 }  
1057    
1058  RealArrayVariable::RealArrayVariable(ParserContext* ctx, vmint size, ArgsRef values, bool _bConst)      unitFactors.resize(size);
1059      : Variable(ctx, 0, _bConst)      for (size_t i = 0; i < size; ++i)
1060            unitFactors[i] = VM_NO_FACTOR;
1061    }
1062    
1063    RealArrayVariable::RealArrayVariable(ParserContext* ctx, vmint size,
1064                                         ArgsRef values, bool _bConst) :
1065        Variable({
1066            .ctx = ctx,
1067            .isPolyphonic = false,
1068            .isConst = _bConst,
1069            .elements = 0,
1070            .memPos = 0,
1071            .unitFactorMemPos = 0,
1072            .unitType = VM_NO_UNIT,
1073            .isFinal = false,
1074        })
1075  {  {
1076      this->values.resize(size);      this->values.resize(size);
1077        this->unitFactors.resize(size);
1078      for (vmint i = 0; i < values->argsCount(); ++i) {      for (vmint i = 0; i < values->argsCount(); ++i) {
1079          VMRealExpr* expr = dynamic_cast<VMRealExpr*>(values->arg(i));          VMRealExpr* expr = dynamic_cast<VMRealExpr*>(values->arg(i));
1080          if (expr) this->values[i] = expr->evalReal();          if (expr) {
1081                this->values[i] = expr->evalReal();
1082                this->unitFactors[i] = expr->unitFactor();
1083            }
1084      }      }
1085  }  }
1086    
1087  RealArrayVariable::RealArrayVariable(ParserContext* ctx, bool bConst)  RealArrayVariable::RealArrayVariable(ParserContext* ctx, bool bConst) :
1088      : Variable(ctx, 0, bConst)      Variable({
1089            .ctx = ctx,
1090            .isPolyphonic = false,
1091            .isConst = bConst,
1092            .elements = 0,
1093            .memPos = 0,
1094            .unitFactorMemPos = 0,
1095            .unitType = VM_NO_UNIT,
1096            .isFinal = false,
1097        })
1098  {  {
1099  }  }
1100    
# Line 751  void RealArrayVariable::assignRealElemen Line 1108  void RealArrayVariable::assignRealElemen
1108      values[i] = value;      values[i] = value;
1109  }  }
1110    
1111    vmfloat RealArrayVariable::unitFactorOfElement(vmuint i) const {
1112        if (i >= unitFactors.size()) return VM_NO_FACTOR;
1113        return unitFactors[i];
1114    }
1115    
1116    void RealArrayVariable::assignElementUnitFactor(vmuint i, vmfloat factor) {
1117        if (i >= unitFactors.size()) return;
1118        unitFactors[i] = factor;
1119    }
1120    
1121  void RealArrayVariable::dump(int level) {  void RealArrayVariable::dump(int level) {
1122      printIndents(level);      printIndents(level);
1123      printf("RealArray(");      printf("RealArray(");
# Line 765  void RealArrayVariable::dump(int level) Line 1132  void RealArrayVariable::dump(int level)
1132      printf(")\n");      printf(")\n");
1133  }  }
1134    
1135  BuiltInIntArrayVariable::BuiltInIntArrayVariable(const String& name, VMInt8Array* array)  BuiltInIntArrayVariable::BuiltInIntArrayVariable(const String& name,
1136      : IntArrayVariable(NULL, false), name(name), array(array)                                                   VMInt8Array* array) :
1137        IntArrayVariable(NULL, false),
1138        name(name), array(array)
1139  {  {
1140  }  }
1141    
# Line 784  void BuiltInIntArrayVariable::dump(int l Line 1153  void BuiltInIntArrayVariable::dump(int l
1153      printf("Built-In Int Array Variable '%s'\n", name.c_str());      printf("Built-In Int Array Variable '%s'\n", name.c_str());
1154  }  }
1155    
1156  IntArrayElement::IntArrayElement(IntArrayExprRef array, IntExprRef arrayIndex)  IntArrayElement::IntArrayElement(IntArrayExprRef array, IntExprRef arrayIndex) :
1157      : IntVariable(NULL, false, false, 0), array(array), index(arrayIndex)      IntVariable({
1158  {              .ctx = NULL,
1159            .isPolyphonic = (array) ? array->isPolyphonic() : false,
1160            .isConst = (array) ? array->isConstExpr() : false,
1161            .elements = 0,
1162            .memPos = 0,
1163            .unitFactorMemPos = 0,
1164            .unitType = VM_NO_UNIT,
1165            .isFinal = false,
1166        }),
1167        Unit(VM_NO_UNIT),
1168        array(array), index(arrayIndex), currentIndex(-1)
1169    {
1170  }  }
1171    
1172  void IntArrayElement::assign(Expression* expr) {  void IntArrayElement::assign(Expression* expr) {
1173      IntExpr* valueExpr = dynamic_cast<IntExpr*>(expr);      IntExpr* valueExpr = dynamic_cast<IntExpr*>(expr);
1174      if (!valueExpr) return;      if (!valueExpr) return;
1175      vmint value = valueExpr->evalInt();      vmint value = valueExpr->evalInt();
1176        vmfloat unitFactor = valueExpr->unitFactor();
1177    
1178      if (!index) return;      if (!index) return;
1179      vmint idx = index->evalInt();      vmint idx = currentIndex = index->evalInt();
1180      if (idx < 0 || idx >= array->arraySize()) return;      if (idx < 0 || idx >= array->arraySize()) return;
1181    
1182      array->assignIntElement(idx, value);      array->assignIntElement(idx, value);
1183        array->assignElementUnitFactor(idx, unitFactor);
1184  }  }
1185    
1186  vmint IntArrayElement::evalInt() {  vmint IntArrayElement::evalInt() {
1187      if (!index) return 0;      if (!index) return 0;
1188      vmint idx = index->evalInt();      vmint idx = currentIndex = index->evalInt();
1189      if (idx < 0 || idx >= array->arraySize()) return 0;      if (idx < 0 || idx >= array->arraySize()) return 0;
1190    
1191      return array->evalIntElement(idx);      return array->evalIntElement(idx);
1192  }  }
1193    
1194    vmfloat IntArrayElement::unitFactor() const {
1195        if (!index) return VM_NO_FACTOR;
1196        vmint idx = currentIndex;
1197        if (idx < 0 || idx >= array->arraySize()) return 0;
1198    
1199        return array->unitFactorOfElement(idx);
1200    }
1201    
1202  void IntArrayElement::dump(int level) {  void IntArrayElement::dump(int level) {
1203      printIndents(level);      printIndents(level);
1204      printf("IntArrayElement\n");      printf("IntArrayElement\n");
1205  }  }
1206    
1207  RealArrayElement::RealArrayElement(RealArrayExprRef array, IntExprRef arrayIndex)  RealArrayElement::RealArrayElement(RealArrayExprRef array, IntExprRef arrayIndex) :
1208      : RealVariable(NULL, false, false, 0), array(array), index(arrayIndex)      RealVariable({
1209            .ctx = NULL,
1210            .isPolyphonic = (array) ? array->isPolyphonic() : false,
1211            .isConst = (array) ? array->isConstExpr() : false,
1212            .elements = 0,
1213            .memPos = 0,
1214            .unitFactorMemPos = 0,
1215            .unitType = VM_NO_UNIT,
1216            .isFinal = false,
1217        }),
1218        Unit(VM_NO_UNIT),
1219        array(array), index(arrayIndex), currentIndex(-1)
1220  {  {
1221  }  }
1222    
# Line 823  void RealArrayElement::assign(Expression Line 1224  void RealArrayElement::assign(Expression
1224      RealExpr* valueExpr = dynamic_cast<RealExpr*>(expr);      RealExpr* valueExpr = dynamic_cast<RealExpr*>(expr);
1225      if (!valueExpr) return;      if (!valueExpr) return;
1226      vmfloat value = valueExpr->evalReal();      vmfloat value = valueExpr->evalReal();
1227        vmfloat unitFactor = valueExpr->unitFactor();
1228    
1229      if (!index) return;      if (!index) return;
1230      vmint idx = index->evalInt();      vmint idx = currentIndex = index->evalInt();
1231      if (idx < 0 || idx >= array->arraySize()) return;      if (idx < 0 || idx >= array->arraySize()) return;
1232    
1233      array->assignRealElement(idx, value);      array->assignRealElement(idx, value);
1234        array->assignElementUnitFactor(idx, unitFactor);
1235  }  }
1236    
1237  vmfloat RealArrayElement::evalReal() {  vmfloat RealArrayElement::evalReal() {
1238      if (!index) return 0;      if (!index) return 0;
1239      vmint idx = index->evalInt();      vmint idx = currentIndex = index->evalInt();
1240      if (idx < 0 || idx >= array->arraySize()) return 0;      if (idx < 0 || idx >= array->arraySize()) return 0;
1241    
1242      return array->evalRealElement(idx);      return array->evalRealElement(idx);
1243  }  }
1244    
1245    vmfloat RealArrayElement::unitFactor() const {
1246        if (!index) return VM_NO_FACTOR;
1247        vmint idx = currentIndex;
1248        if (idx < 0 || idx >= array->arraySize()) return 0;
1249    
1250        return array->unitFactorOfElement(idx);
1251    }
1252    
1253  void RealArrayElement::dump(int level) {  void RealArrayElement::dump(int level) {
1254      printIndents(level);      printIndents(level);
1255      printf("RealArrayElement\n");      printf("RealArrayElement\n");
1256  }  }
1257    
1258  StringVariable::StringVariable(ParserContext* ctx)  StringVariable::StringVariable(ParserContext* ctx) :
1259      : Variable(ctx,ctx->globalStrVarCount++,false)      Variable({
1260            .ctx = ctx,
1261            .elements = 1,
1262            .memPos = ctx->globalStrVarCount++
1263        })
1264  {  {
1265  }  }
1266    
1267  StringVariable::StringVariable(ParserContext* ctx, bool bConst)  StringVariable::StringVariable(ParserContext* ctx, bool bConst) :
1268      : Variable(ctx,0,bConst)      Variable({
1269            .ctx = ctx,
1270            .isConst = bConst,
1271            .memPos = 0,
1272        })
1273  {  {
1274  }  }
1275    
# Line 866  String StringVariable::evalStr() { Line 1285  String StringVariable::evalStr() {
1285    
1286  void StringVariable::dump(int level) {  void StringVariable::dump(int level) {
1287      printIndents(level);      printIndents(level);
1288      printf("StringVariable memPos=%lld\n", memPos);      printf("StringVariable memPos=%" PRId64 "\n", (int64_t)memPos);
1289  }  }
1290    
1291  ConstStringVariable::ConstStringVariable(ParserContext* ctx, String _value)  ConstStringVariable::ConstStringVariable(ParserContext* ctx, String _value)
# Line 889  void ConstStringVariable::dump(int level Line 1308  void ConstStringVariable::dump(int level
1308      printf("ConstStringVariable val='%s'\n", value.c_str());      printf("ConstStringVariable val='%s'\n", value.c_str());
1309  }  }
1310    
1311  MetricPrefix_t ScalarNumberBinaryOp::unitPrefix(vmuint i) const {  bool NumberBinaryOp::isFinal() const {
1312      ScalarNumberExprRef l = (ScalarNumberExprRef) lhs;      NumberExprRef l = (NumberExprRef) lhs;
1313      ScalarNumberExprRef r = (ScalarNumberExprRef) rhs;      NumberExprRef r = (NumberExprRef) rhs;
     return (r->unitFactor() < l->unitFactor()) ? r->unitPrefix(i) : l->unitPrefix(i);  
 }  
   
 StdUnit_t ScalarNumberBinaryOp::unitType() const {  
     ScalarNumberExprRef l = (ScalarNumberExprRef) lhs;  
     ScalarNumberExprRef r = (ScalarNumberExprRef) rhs;  
     return (l->unitType()) ? l->unitType() : r->unitType();  
 }  
   
 bool ScalarNumberBinaryOp::isFinal() const {  
     ScalarNumberExprRef l = (ScalarNumberExprRef) lhs;  
     ScalarNumberExprRef r = (ScalarNumberExprRef) rhs;  
1314      return l->isFinal() || r->isFinal();      return l->isFinal() || r->isFinal();
1315  }  }
1316    
# Line 948  void SelectCase::dump(int level) { Line 1355  void SelectCase::dump(int level) {
1355      printIndents(level);      printIndents(level);
1356      if (select)      if (select)
1357          if (select->isConstExpr())          if (select->isConstExpr())
1358              printf("Case select %lld\n", select->evalInt());              printf("Case select %" PRId64 "\n", (int64_t)select->evalInt());
1359          else          else
1360              printf("Case select [runtime expr]\n");              printf("Case select [runtime expr]\n");
1361      else      else
# Line 958  void SelectCase::dump(int level) { Line 1365  void SelectCase::dump(int level) {
1365          CaseBranch& branch = branches[i];          CaseBranch& branch = branches[i];
1366          if (branch.from && branch.to)          if (branch.from && branch.to)
1367              if (branch.from->isConstExpr() && branch.to->isConstExpr())              if (branch.from->isConstExpr() && branch.to->isConstExpr())
1368                  printf("case %lld to %lld\n", branch.from->evalInt(), branch.to->evalInt());                  printf("case %" PRId64 " to %" PRId64 "\n", (int64_t)branch.from->evalInt(), (int64_t)branch.to->evalInt());
1369              else if (branch.from->isConstExpr() && !branch.to->isConstExpr())              else if (branch.from->isConstExpr() && !branch.to->isConstExpr())
1370                  printf("case %lld to [runtime expr]\n", branch.from->evalInt());                  printf("case %" PRId64 " to [runtime expr]\n", (int64_t)branch.from->evalInt());
1371              else if (!branch.from->isConstExpr() && branch.to->isConstExpr())              else if (!branch.from->isConstExpr() && branch.to->isConstExpr())
1372                  printf("case [runtime expr] to %lld\n", branch.to->evalInt());                  printf("case [runtime expr] to %" PRId64 "\n", (int64_t)branch.to->evalInt());
1373              else              else
1374                  printf("case [runtime expr] to [runtime expr]\n");                  printf("case [runtime expr] to [runtime expr]\n");
1375          else if (branch.from)          else if (branch.from)
1376              if (branch.from->isConstExpr())              if (branch.from->isConstExpr())
1377                  printf("case %lld\n", branch.from->evalInt());                  printf("case %" PRId64 "\n", (int64_t)branch.from->evalInt());
1378              else              else
1379                  printf("case [runtime expr]\n");                  printf("case [runtime expr]\n");
1380          else          else
# Line 1002  bool SelectCase::isPolyphonic() const { Line 1409  bool SelectCase::isPolyphonic() const {
1409      return false;      return false;
1410  }  }
1411    
 // void Case::addBranch(IntExprRef condition, StatementsRef statements) {  
 //     CaseBranchRef b = new CaseBranchRef;  
 //     b->from = condition;  
 //     b->statements = statements;  
 //     branches.push_back(b);  
 // }  
 //  
 // void Case::addBranch(IntExprRef from, IntExprRef to, StatementsRef statements) {  
 //     CaseBranchRef b = new CaseBranchRef;  
 //     b->from = from;  
 //     b->to   = to;  
 //     b->statements = statements;  
 //     branches.push_back(b);  
 // }  
 //  
 // void Case::addBranch(CaseBranchRef branch) {  
 //     branches.push_back(branch);  
 // }  
   
1412  void While::dump(int level) {  void While::dump(int level) {
1413      printIndents(level);      printIndents(level);
1414      if (m_condition)      if (m_condition)
1415          if (m_condition->isConstExpr())          if (m_condition->isConstExpr())
1416              printf("while (%lld) {\n", m_condition->evalInt());              printf("while (%" PRId64 ") {\n", (int64_t)m_condition->evalInt());
1417          else          else
1418              printf("while ([runtime expr]) {\n");              printf("while ([runtime expr]) {\n");
1419      else      else
# Line 1093  bool ConcatString::isConstExpr() const { Line 1481  bool ConcatString::isConstExpr() const {
1481      return lhs->isConstExpr() && rhs->isConstExpr();      return lhs->isConstExpr() && rhs->isConstExpr();
1482  }  }
1483    
1484    Relation::Relation(ExpressionRef lhs, Type type, ExpressionRef rhs) :
1485        Unit(VM_NO_UNIT),
1486        lhs(lhs), rhs(rhs), type(type)
1487    {
1488    }
1489    
1490    // Equal / unequal comparison of real numbers in NKSP scripts:
1491    //
1492    // Unlike system level languages like C/C++ we are less conservative about
1493    // comparing floating point numbers for 'equalness' or 'unequalness' in NKSP
1494    // scripts. Due to the musical context of the NKSP language we automatically
1495    // take the (to be) expected floating point tolerances into account when
1496    // comparing two floating point numbers with each other, however only for '='
1497    // and '#' operators. The '<=' and '>=' still use conservative low level
1498    // floating point comparison for not breaking their transitivity feature.
1499    
1500    template<typename T_LHS, typename T_RHS>
1501    struct RelComparer {
1502        static inline bool isEqual(T_LHS a, T_RHS b) { // for int comparison ('3 = 3')
1503            return a == b;
1504        }
1505        static inline bool isUnequal(T_LHS a, T_RHS b) { // for int comparison ('3 # 3')
1506            return a != b;
1507        }
1508    };
1509    
1510    template<>
1511    struct RelComparer<float,float> {
1512        static inline bool isEqual(float a, float b) { // for real number comparison ('3.1 = 3.1')
1513            return RTMath::fEqual32(a, b);
1514        }
1515        static inline bool isUnequal(float a, float b) { // for real number comparison ('3.1 # 3.1')
1516            return !RTMath::fEqual32(a, b);
1517        }
1518    };
1519    
1520    template<>
1521    struct RelComparer<double,double> {
1522        static inline bool isEqual(double a, double b) { // for future purpose
1523            return RTMath::fEqual64(a, b);
1524        }
1525        static inline bool isUnqqual(double a, double b) { // for future purpose
1526            return !RTMath::fEqual64(a, b);
1527        }
1528    };
1529    
1530  template<class T_LHS, class T_RHS>  template<class T_LHS, class T_RHS>
1531  static inline vmint _evalRelation(Relation::Type type, T_LHS lhs, T_RHS rhs) {  inline vmint _evalRelation(Relation::Type type, T_LHS lhs, T_RHS rhs) {
1532      switch (type) {      switch (type) {
1533          case Relation::LESS_THAN:          case Relation::LESS_THAN:
1534              return lhs < rhs;              return lhs < rhs;
# Line 1105  static inline vmint _evalRelation(Relati Line 1539  static inline vmint _evalRelation(Relati
1539          case Relation::GREATER_OR_EQUAL:          case Relation::GREATER_OR_EQUAL:
1540              return lhs >= rhs;              return lhs >= rhs;
1541          case Relation::EQUAL:          case Relation::EQUAL:
1542              return lhs == rhs;              return RelComparer<typeof(lhs),typeof(rhs)>::isEqual(lhs, rhs);
1543          case Relation::NOT_EQUAL:          case Relation::NOT_EQUAL:
1544              return lhs != rhs;              return RelComparer<typeof(lhs),typeof(rhs)>::isUnequal(lhs, rhs);
1545      }      }
1546      return 0;      return 0;
1547  }  }
1548    
1549    template<class T_LVALUE, class T_RVALUE, class T_LEXPR, class T_REXPR>
1550    inline vmint _evalRealRelation(Relation::Type type,
1551                                   T_LVALUE lvalue, T_RVALUE rvalue,
1552                                   T_LEXPR* pLHS, T_REXPR* pRHS)
1553    {
1554        if (pLHS->unitFactor() == pRHS->unitFactor())
1555            return _evalRelation(type, lvalue, rvalue);
1556        if (pLHS->unitFactor() < pRHS->unitFactor())
1557            return _evalRelation(type, lvalue, Unit::convRealToUnitFactor(rvalue, pRHS, pLHS));
1558        else
1559            return _evalRelation(type, Unit::convRealToUnitFactor(lvalue, pLHS, pRHS), rvalue);
1560    }
1561    
1562    template<class T_LEXPR, class T_REXPR>
1563    inline vmint _evalIntRelation(Relation::Type type,
1564                                  vmint lvalue, vmint rvalue,
1565                                  T_LEXPR* pLHS, T_REXPR* pRHS)
1566    {
1567        if (pLHS->unitFactor() == pRHS->unitFactor())
1568            return _evalRelation(type, lvalue, rvalue);
1569        if (pLHS->unitFactor() < pRHS->unitFactor())
1570            return _evalRelation(type, lvalue, Unit::convIntToUnitFactor(rvalue, pRHS, pLHS));
1571        else
1572            return _evalRelation(type, Unit::convIntToUnitFactor(lvalue, pLHS, pRHS), rvalue);
1573    }
1574    
1575  vmint Relation::evalInt() {  vmint Relation::evalInt() {
1576      const ExprType_t lType = lhs->exprType();      const ExprType_t lType = lhs->exprType();
1577      const ExprType_t rType = rhs->exprType();      const ExprType_t rType = rhs->exprType();
# Line 1125  vmint Relation::evalInt() { Line 1585  vmint Relation::evalInt() {
1585                  return 0;                  return 0;
1586          }          }
1587      } else if (lType == REAL_EXPR && rType == REAL_EXPR) {      } else if (lType == REAL_EXPR && rType == REAL_EXPR) {
1588          return _evalRelation(          vmfloat lvalue = lhs->asReal()->evalReal();
1589              type, lhs->asReal()->evalReal(), rhs->asReal()->evalReal()          vmfloat rvalue = rhs->asReal()->evalReal();
1590            return _evalRealRelation(
1591                type, lvalue, rvalue, lhs->asReal(), rhs->asReal()
1592          );          );
1593      } else if (lType == REAL_EXPR && rType == INT_EXPR) {      } else if (lType == REAL_EXPR && rType == INT_EXPR) {
1594          return _evalRelation(          vmfloat lvalue = lhs->asReal()->evalReal();
1595              type, lhs->asReal()->evalReal(), rhs->asInt()->evalInt()          vmint rvalue = rhs->asInt()->evalInt();
1596            return _evalRealRelation(
1597                type, lvalue, rvalue, lhs->asReal(), rhs->asInt()
1598          );          );
1599      } else if (lType == INT_EXPR && rType == REAL_EXPR) {      } else if (lType == INT_EXPR && rType == REAL_EXPR) {
1600          return _evalRelation(          vmint lvalue = lhs->asInt()->evalInt();
1601              type, lhs->asInt()->evalInt(), rhs->asReal()->evalReal()          vmfloat rvalue = rhs->asReal()->evalReal();
1602            return _evalRealRelation(
1603                type, lvalue, rvalue, lhs->asInt(), rhs->asReal()
1604          );          );
1605      } else {      } else {
1606          return _evalRelation(          vmint lvalue = lhs->asInt()->evalInt();
1607              type, lhs->asInt()->evalInt(), rhs->asInt()->evalInt()          vmint rvalue = rhs->asInt()->evalInt();
1608            return _evalIntRelation(
1609                type, lvalue, rvalue, lhs->asInt(), rhs->asInt()
1610          );          );
1611      }      }
1612  }  }
# Line 1180  bool Relation::isConstExpr() const { Line 1648  bool Relation::isConstExpr() const {
1648  vmint Or::evalInt() {  vmint Or::evalInt() {
1649      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1650      if (pLHS->evalInt()) return 1;      if (pLHS->evalInt()) return 1;
1651      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
1652      return (pRHS->evalInt()) ? 1 : 0;      return (pRHS->evalInt()) ? 1 : 0;
1653  }  }
1654    
# Line 1408  void ParserContext::registerBuiltInConst Line 1876  void ParserContext::registerBuiltInConst
1876      for (std::map<String,vmint>::const_iterator it = vars.begin();      for (std::map<String,vmint>::const_iterator it = vars.begin();
1877           it != vars.end(); ++it)           it != vars.end(); ++it)
1878      {      {
1879          ConstIntVariableRef ref = new ConstIntVariable(it->second);          ConstIntVariableRef ref = new ConstIntVariable({
1880                .value = it->second
1881            });
1882            vartable[it->first] = ref;
1883        }
1884    }
1885    
1886    void ParserContext::registerBuiltInConstRealVariables(const std::map<String,vmfloat>& vars) {
1887        for (std::map<String,vmfloat>::const_iterator it = vars.begin();
1888             it != vars.end(); ++it)
1889        {
1890            ConstRealVariableRef ref = new ConstRealVariable({
1891                .value = it->second
1892            });
1893          vartable[it->first] = ref;          vartable[it->first] = ref;
1894      }      }
1895  }  }

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

  ViewVC Help
Powered by ViewVC