/[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 3577 by schoenebeck, Wed Aug 28 15:23:23 2019 UTC revision 3581 by schoenebeck, Fri Aug 30 11:40:25 2019 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 30  void Node::printIndents(int n) { Line 31  void Node::printIndents(int n) {
31      fflush(stdout);      fflush(stdout);
32  }  }
33    
34    vmint Unit::convIntToUnitFactor(vmint iValue, VMUnit* srcUnit, VMUnit* dstUnit) {
35        vmfloat f = (vmfloat) iValue;
36        vmfloat factor = srcUnit->unitFactor() / dstUnit->unitFactor();
37        if (sizeof(vmfloat) == sizeof(float))
38            return llroundf(f * factor);
39        else
40            return llround(f * factor);
41    }
42    
43    vmint Unit::convIntToUnitFactor(vmint iValue, vmfloat srcFactor, vmfloat dstFactor) {
44        vmfloat f = (vmfloat) iValue;
45        vmfloat factor = srcFactor / dstFactor;
46        if (sizeof(vmfloat) == sizeof(float))
47            return llroundf(f * factor);
48        else
49            return llround(f * factor);
50    }
51    
52    vmfloat Unit::convRealToUnitFactor(vmfloat fValue, VMUnit* srcUnit, VMUnit* dstUnit) {
53        vmfloat factor = srcUnit->unitFactor() / dstUnit->unitFactor();
54        return fValue * factor;
55    }
56    
57    vmfloat Unit::convRealToUnitFactor(vmfloat fValue, vmfloat srcFactor, vmfloat dstFactor) {
58        vmfloat factor = srcFactor / dstFactor;
59        return fValue * factor;
60    }
61    
62    vmint IntExpr::evalIntToUnitFactor(vmfloat unitFactor) {
63        vmfloat f = (vmfloat) evalInt();
64        vmfloat factor = this->unitFactor() / unitFactor;
65        if (sizeof(vmfloat) == sizeof(float))
66            return llroundf(f * factor);
67        else
68            return llround(f * factor);
69    }
70    
71    static String _unitFactorToShortStr(vmfloat unitFactor) {
72        const long int tens = lround( log10(unitFactor) );
73        switch (tens) {
74            case  3: return "k";  // kilo  = 10^3
75            case  2: return "h";  // hecto = 10^2
76            case  1: return "da"; // deca  = 10
77            case  0: return "" ;  //  --   = 1
78            case -1: return "d";  // deci  = 10^-1
79            case -2: return "c";  // centi = 10^-2 (this is also used for tuning "cents")
80            case -3: return "m";  // milli = 10^-3
81            case -4: return "md"; // milli deci = 10^-4
82            case -5: return "mc"; // milli centi = 10^-5 (this is also used for tuning "cents")
83            case -6: return "u";  // micro = 10^-6
84            default: return "*10^" + ToString(tens);
85        }
86    }
87    
88    static String _unitToStr(Unit* unit) {
89        const StdUnit_t type = unit->unitType();
90        String sType;
91        switch (type) {
92            case VM_NO_UNIT: break;
93            case VM_SECOND: sType = "s"; break;
94            case VM_HERTZ: sType = "Hz"; break;
95            case VM_BEL: sType = "B"; break;
96        }
97    
98        String prefix = _unitFactorToShortStr( unit->unitFactor() );
99    
100        return prefix + sType;
101    }
102    
103  String IntExpr::evalCastToStr() {  String IntExpr::evalCastToStr() {
104      return ToString(evalInt());      return ToString(evalInt()) + _unitToStr(this);
105    }
106    
107    vmfloat RealExpr::evalRealToUnitFactor(vmfloat unitFactor) {
108        vmfloat f = evalReal();
109        vmfloat factor = this->unitFactor() / unitFactor;
110        return f * factor;
111  }  }
112    
113  String RealExpr::evalCastToStr() {  String RealExpr::evalCastToStr() {
114      return ToString(evalReal());      return ToString(evalReal()) + _unitToStr(this);
115  }  }
116    
117  String IntArrayExpr::evalCastToStr() {  String IntArrayExpr::evalCastToStr() {
118      String s = "{";      String s = "{";
119      for (vmint i = 0; i < arraySize(); ++i) {      for (vmint i = 0; i < arraySize(); ++i) {
120          vmint val = evalIntElement(i);          vmint val = evalIntElement(i);
121            vmfloat factor = unitFactorOfElement(i);
122          if (i) s += ",";          if (i) s += ",";
123          s += ToString(val);          s += ToString(val) + _unitFactorToShortStr(factor);
124      }      }
125      s += "}";      s += "}";
126      return s;      return s;
# Line 53  String RealArrayExpr::evalCastToStr() { Line 130  String RealArrayExpr::evalCastToStr() {
130      String s = "{";      String s = "{";
131      for (vmint i = 0; i < arraySize(); ++i) {      for (vmint i = 0; i < arraySize(); ++i) {
132          vmfloat val = evalRealElement(i);          vmfloat val = evalRealElement(i);
133            vmfloat factor = unitFactorOfElement(i);
134          if (i) s += ",";          if (i) s += ",";
135          s += ToString(val);          s += ToString(val) + _unitFactorToShortStr(factor);
136      }      }
137      s += "}";      s += "}";
138      return s;      return s;
139  }  }
140    
141  MetricPrefix_t Unit::unitPrefix(vmuint i) const {  IntLiteral::IntLiteral(const IntLitDef& def) :
142      if (i >= prefix.size()) return VM_NO_PREFIX;      IntExpr(), Unit(def.unitType),
143      return prefix[i];      value(def.value), unitPrefixFactor(def.unitFactor),
144  }      finalVal(def.isFinal)
145    {
 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);  
     }  
146  }  }
147    
148  vmint IntLiteral::evalInt() {  vmint IntLiteral::evalInt() {
# Line 99  void IntLiteral::dump(int level) { Line 154  void IntLiteral::dump(int level) {
154      printf("IntLiteral %lld\n", value);      printf("IntLiteral %lld\n", value);
155  }  }
156    
157    RealLiteral::RealLiteral(const RealLitDef& def) :
158        RealExpr(), Unit(def.unitType),
159        value(def.value), unitPrefixFactor(def.unitFactor),
160        finalVal(def.isFinal)
161    {
162    }
163    
164  vmfloat RealLiteral::evalReal() {  vmfloat RealLiteral::evalReal() {
165      return value;      return value;
166  }  }
# Line 113  void StringLiteral::dump(int level) { Line 175  void StringLiteral::dump(int level) {
175      printf("StringLiteral: '%s'\n", value.c_str());      printf("StringLiteral: '%s'\n", value.c_str());
176  }  }
177    
178    Add::Add(ScalarNumberExprRef lhs, ScalarNumberExprRef rhs) :
179        VaritypeScalarBinaryOp(lhs, rhs),
180        Unit(
181            // lhs and rhs are forced to be same unit type at parse time, so either one is fine here
182            (lhs) ? lhs->unitType() : VM_NO_UNIT
183        )
184    {
185    }
186    
187  vmint Add::evalInt() {  vmint Add::evalInt() {
188      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
189      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
190      return (pLHS && pRHS) ? pLHS->evalInt() + pRHS->evalInt() : 0;      if (!pLHS || !pRHS) return 0;
191        // eval*() call is required before calling unitFactor(), since the latter does not evaluate expressions!
192        vmint lvalue = pLHS->evalInt();
193        vmint rvalue = pRHS->evalInt();
194        if (pLHS->unitFactor() == pRHS->unitFactor())
195            return lvalue + rvalue;
196        if (pLHS->unitFactor() < pRHS->unitFactor())
197            return lvalue + Unit::convIntToUnitFactor(rvalue, pRHS, pLHS);
198        else
199            return Unit::convIntToUnitFactor(lvalue, pLHS, pRHS) + rvalue;
200  }  }
201    
202  vmfloat Add::evalReal() {  vmfloat Add::evalReal() {
203      RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);      RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
204      RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);;      RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);
205      return (pLHS && pRHS) ? pLHS->evalReal() + pRHS->evalReal() : 0;      if (!pLHS || !pRHS) return 0;
206        // eval*() call is required before calling unitFactor(), since the latter does not evaluate expressions!
207        vmfloat lvalue = pLHS->evalReal();
208        vmfloat rvalue = pRHS->evalReal();
209        if (pLHS->unitFactor() == pRHS->unitFactor())
210            return lvalue + rvalue;
211        if (pLHS->unitFactor() < pRHS->unitFactor())
212            return lvalue + Unit::convRealToUnitFactor(rvalue, pRHS, pLHS);
213        else
214            return Unit::convRealToUnitFactor(lvalue, pLHS, pRHS) + rvalue;
215    }
216    
217    vmfloat Add::unitFactor() const {
218        const ScalarNumberExpr* pLHS = dynamic_cast<const ScalarNumberExpr*>(&*lhs);
219        const ScalarNumberExpr* pRHS = dynamic_cast<const ScalarNumberExpr*>(&*rhs);
220        return (pLHS->unitFactor() < pRHS->unitFactor()) ? pLHS->unitFactor() : pRHS->unitFactor();
221  }  }
222    
223  void Add::dump(int level) {  void Add::dump(int level) {
# Line 136  void Add::dump(int level) { Line 231  void Add::dump(int level) {
231      printf(")\n");      printf(")\n");
232  }  }
233    
234    Sub::Sub(ScalarNumberExprRef lhs, ScalarNumberExprRef rhs) :
235        VaritypeScalarBinaryOp(lhs, rhs),
236        Unit(
237            // lhs and rhs are forced to be same unit type at parse time, so either one is fine here
238            (lhs) ? lhs->unitType() : VM_NO_UNIT
239        )
240    {
241    }
242    
243  vmint Sub::evalInt() {  vmint Sub::evalInt() {
244      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
245      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
246      return (pLHS && pRHS) ? pLHS->evalInt() - pRHS->evalInt() : 0;      if (!pLHS || !pRHS) return 0;
247        // eval*() call is required before calling unitFactor(), since the latter does not evaluate expressions!
248        vmint lvalue = pLHS->evalInt();
249        vmint rvalue = pRHS->evalInt();
250        if (pLHS->unitFactor() == pRHS->unitFactor())
251            return lvalue - rvalue;
252        if (pLHS->unitFactor() < pRHS->unitFactor())
253            return lvalue - Unit::convIntToUnitFactor(rvalue, pRHS, pLHS);
254        else
255            return Unit::convIntToUnitFactor(lvalue, pLHS, pRHS) - rvalue;
256  }  }
257    
258  vmfloat Sub::evalReal() {  vmfloat Sub::evalReal() {
259      RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);      RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
260      RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);;      RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);
261      return (pLHS && pRHS) ? pLHS->evalReal() - pRHS->evalReal() : 0;      if (!pLHS || !pRHS) return 0;
262        // eval*() call is required before calling unitFactor(), since the latter does not evaluate expressions!
263        vmfloat lvalue = pLHS->evalReal();
264        vmfloat rvalue = pRHS->evalReal();
265        if (pLHS->unitFactor() == pRHS->unitFactor())
266            return lvalue - rvalue;
267        if (pLHS->unitFactor() < pRHS->unitFactor())
268            return lvalue - Unit::convRealToUnitFactor(rvalue, pRHS, pLHS);
269        else
270            return Unit::convRealToUnitFactor(lvalue, pLHS, pRHS) - rvalue;
271    }
272    
273    vmfloat Sub::unitFactor() const {
274        const ScalarNumberExpr* pLHS = dynamic_cast<const ScalarNumberExpr*>(&*lhs);
275        const ScalarNumberExpr* pRHS = dynamic_cast<const ScalarNumberExpr*>(&*rhs);
276        return (pLHS->unitFactor() < pRHS->unitFactor()) ? pLHS->unitFactor() : pRHS->unitFactor();
277  }  }
278    
279  void Sub::dump(int level) {  void Sub::dump(int level) {
# Line 159  void Sub::dump(int level) { Line 287  void Sub::dump(int level) {
287      printf(")\n");      printf(")\n");
288  }  }
289    
290    Mul::Mul(ScalarNumberExprRef lhs, ScalarNumberExprRef rhs) :
291        VaritypeScalarBinaryOp(lhs, rhs),
292        Unit(
293            // currently the NKSP parser only allows a unit type on either side on multiplications
294            (lhs->unitType()) ? lhs->unitType() : rhs->unitType()
295        )
296    {
297    }
298    
299  vmint Mul::evalInt() {  vmint Mul::evalInt() {
300      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
301      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;
# Line 182  void Mul::dump(int level) { Line 319  void Mul::dump(int level) {
319      printf(")\n");      printf(")\n");
320  }  }
321    
322  MetricPrefix_t Mul::unitPrefix(vmuint i) const {  vmfloat Mul::unitFactor() const {
323      const ScalarNumberExpr* pLHS = dynamic_cast<const ScalarNumberExpr*>(&*lhs);      const ScalarNumberExpr* pLHS = dynamic_cast<const ScalarNumberExpr*>(&*lhs);
324      const ScalarNumberExpr* pRHS = dynamic_cast<const ScalarNumberExpr*>(&*rhs);      const ScalarNumberExpr* pRHS = dynamic_cast<const ScalarNumberExpr*>(&*rhs);
325      // 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);  
326  }  }
327    
328  StdUnit_t Mul::unitType() const {  Div::Div(ScalarNumberExprRef lhs, ScalarNumberExprRef rhs) :
329      const ScalarNumberExpr* pLHS = dynamic_cast<const ScalarNumberExpr*>(&*lhs);      VaritypeScalarBinaryOp(lhs, rhs),
330      const ScalarNumberExpr* pRHS = dynamic_cast<const ScalarNumberExpr*>(&*rhs);      Unit(
331      // 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
332      return (pLHS->unitType()) ? pLHS->unitType() : pRHS->unitType();          // on right side or B) an identical unit type on both sides
333            (lhs->unitType() && rhs->unitType()) ? VM_NO_UNIT : lhs->unitType()
334        )
335    {
336  }  }
337    
338  vmint Div::evalInt() {  vmint Div::evalInt() {
# Line 208  vmint Div::evalInt() { Line 347  vmint Div::evalInt() {
347    
348  vmfloat Div::evalReal() {  vmfloat Div::evalReal() {
349      RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);      RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
350      RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);;      RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);
351      if (!pLHS || !pRHS) return 0;      if (!pLHS || !pRHS) return 0;
352      vmfloat l = pLHS->evalReal();      vmfloat l = pLHS->evalReal();
353      vmfloat r = pRHS->evalReal();      vmfloat r = pRHS->evalReal();
# Line 227  void Div::dump(int level) { Line 366  void Div::dump(int level) {
366      printf(")\n");      printf(")\n");
367  }  }
368    
369  MetricPrefix_t Div::unitPrefix(vmuint i) const {  vmfloat Div::unitFactor() const {
     const ScalarNumberExpr* pLHS = dynamic_cast<const ScalarNumberExpr*>(&*lhs);  
     const ScalarNumberExpr* pRHS = dynamic_cast<const ScalarNumberExpr*>(&*rhs);  
     // currently the NKSP parser only allows either A) a unit prefix on left  
     // 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 {  
370      const ScalarNumberExpr* pLHS = dynamic_cast<const ScalarNumberExpr*>(&*lhs);      const ScalarNumberExpr* pLHS = dynamic_cast<const ScalarNumberExpr*>(&*lhs);
371      const ScalarNumberExpr* pRHS = dynamic_cast<const ScalarNumberExpr*>(&*rhs);      const ScalarNumberExpr* pRHS = dynamic_cast<const ScalarNumberExpr*>(&*rhs);
372      // the NKSP parser only allows either A) a unit type on left side and none      return pLHS->unitFactor() / pRHS->unitFactor();
     // on right side or B) an identical unit type on both sides  
     return (pLHS->unitType() && pRHS->unitType()) ? VM_NO_UNIT : pLHS->unitType();  
373  }  }
374    
375  vmint Mod::evalInt() {  vmint Mod::evalInt() {
376      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
377      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
378      return (pLHS && pRHS) ? pLHS->evalInt() % pRHS->evalInt() : 0;      return (pLHS && pRHS) ? pLHS->evalInt() % pRHS->evalInt() : 0;
379  }  }
380    
# Line 369  bool Statements::isPolyphonic() const { Line 498  bool Statements::isPolyphonic() const {
498      return false;      return false;
499  }  }
500    
501  DynamicVariableCall::DynamicVariableCall(const String& name, ParserContext* ctx, VMDynVar* v)  DynamicVariableCall::DynamicVariableCall(const String& name, ParserContext* ctx, VMDynVar* v) :
502      : Variable(ctx, 0, false), dynVar(v), varName(name)      Variable({
503            .ctx = ctx,
504            .elements = 0
505        }),
506        Unit(VM_NO_UNIT),
507        dynVar(v), varName(name)
508  {  {
509  }  }
510    
# Line 400  void DynamicVariableCall::dump(int level Line 534  void DynamicVariableCall::dump(int level
534      printf("Dynamic Variable '%s'\n", varName.c_str());      printf("Dynamic Variable '%s'\n", varName.c_str());
535  }  }
536    
537    FunctionCall::FunctionCall(const char* function, ArgsRef args, VMFunction* fn) :
538        Unit(
539            (fn) ? fn->returnUnitType(dynamic_cast<VMFnArgs*>(&*args)) : VM_NO_UNIT
540        ),
541        functionName(function), args(args), fn(fn), result(NULL)
542    {
543    }
544    
545  void FunctionCall::dump(int level) {  void FunctionCall::dump(int level) {
546      printIndents(level);      printIndents(level);
547      printf("FunctionCall '%s' args={\n", functionName.c_str());      printf("FunctionCall '%s' args={\n", functionName.c_str());
# Line 414  ExprType_t FunctionCall::exprType() cons Line 556  ExprType_t FunctionCall::exprType() cons
556      return fn->returnType(dynamic_cast<VMFnArgs*>(&*self->args));      return fn->returnType(dynamic_cast<VMFnArgs*>(&*self->args));
557  }  }
558    
559    vmfloat FunctionCall::unitFactor() const {
560        if (!fn || !result) return VM_NO_FACTOR;
561        VMExpr* expr = result->resultValue();
562        if (!expr) return VM_NO_FACTOR;
563        VMScalarNumberExpr* scalar = expr->asScalarNumberExpr();
564        if (!scalar) return VM_NO_FACTOR;
565        return scalar->unitFactor();
566    }
567    
568    bool FunctionCall::isFinal() const {
569        if (!fn) return false;
570        FunctionCall* self = const_cast<FunctionCall*>(this);
571        return fn->returnsFinal(dynamic_cast<VMFnArgs*>(&*self->args));
572    }
573    
574  VMFnResult* FunctionCall::execVMFn() {  VMFnResult* FunctionCall::execVMFn() {
575      if (!fn) return NULL;      if (!fn) return NULL;
576      // assuming here that all argument checks (amount and types) have been made      // assuming here that all argument checks (amount and types) have been made
# Line 422  VMFnResult* FunctionCall::execVMFn() { Line 579  VMFnResult* FunctionCall::execVMFn() {
579  }  }
580    
581  StmtFlags_t FunctionCall::exec() {  StmtFlags_t FunctionCall::exec() {
582      VMFnResult* result = execVMFn();      result = execVMFn();
583      if (!result)      if (!result)
584          return StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);          return StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
585      return result->resultFlags();      return result->resultFlags();
586  }  }
587    
588  vmint FunctionCall::evalInt() {  vmint FunctionCall::evalInt() {
589      VMFnResult* result = execVMFn();      result = execVMFn();
590      if (!result) return 0;      if (!result) return 0;
591      VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());      VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());
592      if (!intExpr) return 0;      if (!intExpr) return 0;
# Line 437  vmint FunctionCall::evalInt() { Line 594  vmint FunctionCall::evalInt() {
594  }  }
595    
596  vmfloat FunctionCall::evalReal() {  vmfloat FunctionCall::evalReal() {
597      VMFnResult* result = execVMFn();      result = execVMFn();
598      if (!result) return 0;      if (!result) return 0;
599      VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());      VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());
600      if (!realExpr) return 0;      if (!realExpr) return 0;
# Line 445  vmfloat FunctionCall::evalReal() { Line 602  vmfloat FunctionCall::evalReal() {
602  }  }
603    
604  VMIntArrayExpr* FunctionCall::asIntArray() const {  VMIntArrayExpr* FunctionCall::asIntArray() const {
     VMFnResult* result = const_cast<FunctionCall*>(this)->execVMFn();  
605      if (!result) return 0;      if (!result) return 0;
606      VMIntArrayExpr* intArrExpr = dynamic_cast<VMIntArrayExpr*>(result->resultValue());      VMIntArrayExpr* intArrExpr = dynamic_cast<VMIntArrayExpr*>(result->resultValue());
607      return intArrExpr;      return intArrExpr;
608  }  }
609    
610  VMRealArrayExpr* FunctionCall::asRealArray() const {  VMRealArrayExpr* FunctionCall::asRealArray() const {
     VMFnResult* result = const_cast<FunctionCall*>(this)->execVMFn();  
611      if (!result) return 0;      if (!result) return 0;
612      VMRealArrayExpr* realArrExpr = dynamic_cast<VMRealArrayExpr*>(result->resultValue());      VMRealArrayExpr* realArrExpr = dynamic_cast<VMRealArrayExpr*>(result->resultValue());
613      return realArrExpr;      return realArrExpr;
614  }  }
615    
616  String FunctionCall::evalStr() {  String FunctionCall::evalStr() {
617      VMFnResult* result = execVMFn();      result = execVMFn();
618      if (!result) return "";      if (!result) return "";
619      VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());      VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());
620      if (!strExpr) return "";      if (!strExpr) return "";
# Line 467  String FunctionCall::evalStr() { Line 622  String FunctionCall::evalStr() {
622  }  }
623    
624  String FunctionCall::evalCastToStr() {  String FunctionCall::evalCastToStr() {
625      VMFnResult* result = execVMFn();      result = execVMFn();
626      if (!result) return "";      if (!result) return "";
627      const ExprType_t resultType = result->resultValue()->exprType();      const ExprType_t resultType = result->resultValue()->exprType();
628      if (resultType == STRING_EXPR) {      if (resultType == STRING_EXPR) {
# Line 482  String FunctionCall::evalCastToStr() { Line 637  String FunctionCall::evalCastToStr() {
637      }      }
638  }  }
639    
640  ScalarNumberVariable::ScalarNumberVariable(ParserContext* ctx, vmint _memPos,  Variable::Variable(const VariableDecl& decl) :
641                                             bool _bConst, bool _bPolyphonic,      context(decl.ctx), memPos(decl.memPos), bConst(decl.isConst)
                                            bool _bFinal)  
     : Variable(ctx, _memPos, _bConst),  
       Unit(),  
       polyphonic(_bPolyphonic), finalVal(_bFinal)  
642  {  {
643  }  }
644    
645  IntVariable::IntVariable(ParserContext* ctx)  ScalarNumberVariable::ScalarNumberVariable(const VariableDecl& decl) :
646      : ScalarNumberVariable(ctx, ctx ? ctx->globalIntVarCount++ : 0)      Variable(decl),
647        Unit(decl.unitType),
648        unitFactorMemPos(decl.unitFactorMemPos), polyphonic(decl.isPolyphonic),
649        finalVal(decl.isFinal)
650  {  {
651      //printf("globalIntVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);  }
652      assert(ctx);  
653    vmfloat ScalarNumberVariable::unitFactor() const {
654        if (isPolyphonic()) {
655            return context->execContext->polyphonicUnitFactorMemory[unitFactorMemPos];
656        }
657        return (*context->globalUnitFactorMemory)[unitFactorMemPos];
658  }  }
659    
660  inline static vmint postfixInc(vmint& object, vmint incBy) {  inline static vmint postfixInc(vmint& object, vmint incBy) {
# Line 504  inline static vmint postfixInc(vmint& ob Line 663  inline static vmint postfixInc(vmint& ob
663      return i;      return i;
664  }  }
665    
666  IntVariable::IntVariable(ParserContext* ctx, bool bPolyphonic, bool bConst, vmint size)  IntVariable::IntVariable(const VariableDecl& decl) :
667      : ScalarNumberVariable(      ScalarNumberVariable({
668            ctx,          .ctx = decl.ctx,
669            !ctx ? 0 : bPolyphonic ? postfixInc(ctx->polyphonicIntVarCount, size) :          .isPolyphonic = decl.isPolyphonic,
670                                     postfixInc(ctx->globalIntVarCount, size),          .isConst = decl.isConst,
671            bConst, bPolyphonic          .isFinal = decl.isFinal,
672        )          .elements = decl.elements,
673  {          .memPos = (
674      //printf("IntVar size=%d parserCtx=0x%lx\n", size, (uint64_t)ctx);              (!decl.ctx) ? 0 :
675      if (bPolyphonic) {                  (decl.isPolyphonic) ?
676          //printf("polyIntVar memPOS=%d\n", memPos);                      postfixInc(decl.ctx->polyphonicIntVarCount, decl.elements) :
677          assert(ctx);                      postfixInc(decl.ctx->globalIntVarCount, decl.elements)
678      }          ),
679            .unitFactorMemPos = (
680                (!decl.ctx) ? 0 :
681                    (decl.isPolyphonic) ?
682                        postfixInc(decl.ctx->polyphonicUnitFactorCount, decl.elements) :
683                        postfixInc(decl.ctx->globalUnitFactorCount, decl.elements)
684            ),
685            .unitType = decl.unitType
686        }),
687        Unit(decl.unitType)
688    {
689        //printf("IntVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);
690        assert(!decl.isPolyphonic || decl.ctx);
691  }  }
692    
693  void IntVariable::assign(Expression* expr) {  void IntVariable::assign(Expression* expr) {
694      IntExpr* intExpr = dynamic_cast<IntExpr*>(expr);      IntExpr* intExpr = dynamic_cast<IntExpr*>(expr);
695      if (intExpr) {      if (intExpr) {
696          if (isPolyphonic())          //NOTE: sequence matters! evalInt() must be called before getting unitFactor() !
697            if (isPolyphonic()) {
698              context->execContext->polyphonicIntMemory[memPos] = intExpr->evalInt();              context->execContext->polyphonicIntMemory[memPos] = intExpr->evalInt();
699          else              context->execContext->polyphonicUnitFactorMemory[unitFactorMemPos] = intExpr->unitFactor();
700            } else {
701              (*context->globalIntMemory)[memPos] = intExpr->evalInt();              (*context->globalIntMemory)[memPos] = intExpr->evalInt();
702                (*context->globalUnitFactorMemory)[unitFactorMemPos] = intExpr->unitFactor();
703            }
704      }      }
705  }  }
706    
# Line 544  void IntVariable::dump(int level) { Line 719  void IntVariable::dump(int level) {
719      //printf("IntVariable memPos=%d\n", memPos);      //printf("IntVariable memPos=%d\n", memPos);
720  }  }
721    
722  RealVariable::RealVariable(ParserContext* ctx)  RealVariable::RealVariable(const VariableDecl& decl) :
723      : ScalarNumberVariable(ctx, ctx ? ctx->globalRealVarCount++ : 0)      ScalarNumberVariable({
724            .ctx = decl.ctx,
725            .isPolyphonic = decl.isPolyphonic,
726            .isConst = decl.isConst,
727            .isFinal = decl.isFinal,
728            .elements = decl.elements,
729            .memPos = (
730                (!decl.ctx) ? 0 :
731                    (decl.isPolyphonic) ?
732                        postfixInc(decl.ctx->polyphonicRealVarCount, decl.elements) :
733                        postfixInc(decl.ctx->globalRealVarCount, decl.elements)
734            ),
735            .unitFactorMemPos = (
736                (!decl.ctx) ? 0 :
737                    (decl.isPolyphonic) ?
738                        postfixInc(decl.ctx->polyphonicUnitFactorCount, decl.elements) :
739                        postfixInc(decl.ctx->globalUnitFactorCount, decl.elements)
740            ),
741            .unitType = decl.unitType
742        }),
743        Unit(decl.unitType)
744  {  {
745      //printf("globalRealVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);      //printf("RealVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);
746      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);  
     }  
747  }  }
748    
749  void RealVariable::assign(Expression* expr) {  void RealVariable::assign(Expression* expr) {
750      RealExpr* realExpr = dynamic_cast<RealExpr*>(expr);      RealExpr* realExpr = dynamic_cast<RealExpr*>(expr);
751      if (realExpr) {      if (realExpr) {
752          if (isPolyphonic())          //NOTE: sequence matters! evalReal() must be called before getting unitFactor() !
753            if (isPolyphonic()) {
754              context->execContext->polyphonicRealMemory[memPos] = realExpr->evalReal();              context->execContext->polyphonicRealMemory[memPos] = realExpr->evalReal();
755          else              context->execContext->polyphonicUnitFactorMemory[unitFactorMemPos] = realExpr->unitFactor();
756            } else {
757              (*context->globalRealMemory)[memPos] = realExpr->evalReal();              (*context->globalRealMemory)[memPos] = realExpr->evalReal();
758                (*context->globalUnitFactorMemory)[unitFactorMemPos] = realExpr->unitFactor();
759            }
760      }      }
761  }  }
762    
# Line 591  void RealVariable::dump(int level) { Line 775  void RealVariable::dump(int level) {
775      //printf("RealVariable memPos=%d\n", memPos);      //printf("RealVariable memPos=%d\n", memPos);
776  }  }
777    
778  ConstIntVariable::ConstIntVariable(vmint value)  ConstIntVariable::ConstIntVariable(const IntVarDef& def) :
779      : IntVariable(NULL,false,true), value(value)      IntVariable({
780            .ctx = def.ctx,
781            .isPolyphonic = false,
782            .isConst = true,
783            .isFinal = def.isFinal,
784            .elements = 1,
785            .memPos = def.memPos,
786            .unitFactorMemPos = def.unitFactorMemPos,
787            .unitType = def.unitType
788        }),
789        Unit(def.unitType),
790        value(def.value), unitPrefixFactor(def.unitFactor)
791  {  {
792  }  }
793    
# Line 616  void ConstIntVariable::dump(int level) { Line 811  void ConstIntVariable::dump(int level) {
811      printf("ConstIntVariable val=%lld\n", value);      printf("ConstIntVariable val=%lld\n", value);
812  }  }
813    
814  ConstRealVariable::ConstRealVariable(vmfloat value)  ConstRealVariable::ConstRealVariable(const RealVarDef& def) :
815      : RealVariable(NULL,false,true), value(value)      RealVariable({
816            .ctx = def.ctx,
817            .isPolyphonic = false,
818            .isConst = true,
819            .isFinal = def.isFinal,
820            .elements = 1,
821            .memPos = def.memPos,
822            .unitFactorMemPos = def.unitFactorMemPos,
823            .unitType = def.unitType
824        }),
825        Unit(def.unitType),
826        value(def.value), unitPrefixFactor(def.unitFactor)
827  {  {
828  }  }
829    
# Line 634  void ConstRealVariable::dump(int level) Line 840  void ConstRealVariable::dump(int level)
840      printf("ConstRealVariable val=%f\n", value);      printf("ConstRealVariable val=%f\n", value);
841  }  }
842    
843  BuiltInIntVariable::BuiltInIntVariable(const String& name, VMIntPtr* ptr)  BuiltInIntVariable::BuiltInIntVariable(const String& name, VMIntPtr* ptr) :
844      : IntVariable(NULL,false,false), name(name), ptr(ptr)      IntVariable({
845            .ctx = NULL,
846            .isPolyphonic = false,
847            .isConst = false, // may or may not be modifyable though!
848            .isFinal = false,
849            .elements = 0,
850            .memPos = 0,
851            .unitFactorMemPos = 0,
852            .unitType = VM_NO_UNIT
853        }),
854        Unit(VM_NO_UNIT),
855        name(name), ptr(ptr)
856  {  {
857  }  }
858    
# Line 654  void BuiltInIntVariable::dump(int level) Line 871  void BuiltInIntVariable::dump(int level)
871      printf("Built-in IntVar '%s'\n", name.c_str());      printf("Built-in IntVar '%s'\n", name.c_str());
872  }  }
873    
874  PolyphonicIntVariable::PolyphonicIntVariable(ParserContext* ctx)  PolyphonicIntVariable::PolyphonicIntVariable(const VariableDecl& decl) :
875      : IntVariable(ctx,true,false)      IntVariable({
876            .ctx = decl.ctx,
877            .isPolyphonic = true,
878            .isConst = decl.isConst,
879            .isFinal = decl.isFinal,
880            .elements = 1,
881            .memPos = 0,
882            .unitFactorMemPos = 0,
883            .unitType = decl.unitType
884        }),
885        Unit(decl.unitType)
886  {  {
887  }  }
888    
# Line 664  void PolyphonicIntVariable::dump(int lev Line 891  void PolyphonicIntVariable::dump(int lev
891      printf("PolyphonicIntVariable\n");      printf("PolyphonicIntVariable\n");
892  }  }
893    
894  PolyphonicRealVariable::PolyphonicRealVariable(ParserContext* ctx)  PolyphonicRealVariable::PolyphonicRealVariable(const VariableDecl& decl) :
895      : RealVariable(ctx,true,false)      RealVariable({
896            .ctx = decl.ctx,
897            .isPolyphonic = true,
898            .isConst = decl.isConst,
899            .isFinal = decl.isFinal,
900            .elements = 1,
901            .memPos = 0,
902            .unitFactorMemPos = 0,
903            .unitType = decl.unitType
904        }),
905        Unit(decl.unitType)
906  {  {
907  }  }
908    
# Line 674  void PolyphonicRealVariable::dump(int le Line 911  void PolyphonicRealVariable::dump(int le
911      printf("PolyphonicRealVariable\n");      printf("PolyphonicRealVariable\n");
912  }  }
913    
914  IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size)  IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size) :
915      : Variable(ctx, 0, false)      Variable({
916            .ctx = ctx,
917            .isPolyphonic = false,
918            .isConst = false,
919            .isFinal = false,
920            .elements = 0,
921            .memPos = 0,
922            .unitFactorMemPos = 0,
923            .unitType = VM_NO_UNIT
924        })
925  {  {
926      values.resize(size);      values.resize(size);
927      memset(&values[0], 0, size * sizeof(vmint));      memset(&values[0], 0, size * sizeof(vmint));
 }  
928    
929  IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size, ArgsRef values, bool _bConst)      unitFactors.resize(size);
930      : Variable(ctx, 0, _bConst)      for (size_t i = 0; i < size; ++i)
931            unitFactors[i] = VM_NO_FACTOR;
932    }
933    
934    IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size,
935                                       ArgsRef values, bool _bConst) :
936        Variable({
937            .ctx = ctx,
938            .isPolyphonic = false,
939            .isConst = _bConst,
940            .isFinal = false,
941            .elements = 0,
942            .memPos = 0,
943            .unitFactorMemPos = 0,
944            .unitType = VM_NO_UNIT
945        })
946  {  {
947      this->values.resize(size);      this->values.resize(size);
948        this->unitFactors.resize(size);
949      for (vmint i = 0; i < values->argsCount(); ++i) {      for (vmint i = 0; i < values->argsCount(); ++i) {
950          VMIntExpr* expr = dynamic_cast<VMIntExpr*>(values->arg(i));          VMIntExpr* expr = dynamic_cast<VMIntExpr*>(values->arg(i));
951          if (expr) this->values[i] = expr->evalInt();          if (expr) {
952                this->values[i] = expr->evalInt();
953                this->unitFactors[i] = expr->unitFactor();
954            }
955      }      }
956  }  }
957    
958  IntArrayVariable::IntArrayVariable(ParserContext* ctx, bool bConst)  IntArrayVariable::IntArrayVariable(ParserContext* ctx, bool bConst) :
959      : Variable(ctx, 0, bConst)      Variable({
960            .ctx = ctx,
961            .isPolyphonic = false,
962            .isConst = bConst,
963            .isFinal = false,
964            .elements = 0,
965            .memPos = 0,
966            .unitFactorMemPos = 0,
967            .unitType = VM_NO_UNIT
968        })
969  {  {
970  }  }
971    
# Line 706  void IntArrayVariable::assignIntElement( Line 979  void IntArrayVariable::assignIntElement(
979      values[i] = value;      values[i] = value;
980  }  }
981    
982    vmfloat IntArrayVariable::unitFactorOfElement(vmuint i) const {
983        if (i >= unitFactors.size()) return VM_NO_FACTOR;
984        return unitFactors[i];
985    }
986    
987    void IntArrayVariable::assignElementUnitFactor(vmuint i, vmfloat factor) {
988        if (i >= unitFactors.size()) return;
989        unitFactors[i] = factor;
990    }
991    
992  void IntArrayVariable::dump(int level) {  void IntArrayVariable::dump(int level) {
993      printIndents(level);      printIndents(level);
994      printf("IntArray(");      printf("IntArray(");
# Line 720  void IntArrayVariable::dump(int level) { Line 1003  void IntArrayVariable::dump(int level) {
1003      printf(")\n");      printf(")\n");
1004  }  }
1005    
1006  RealArrayVariable::RealArrayVariable(ParserContext* ctx, vmint size)  RealArrayVariable::RealArrayVariable(ParserContext* ctx, vmint size) :
1007      : Variable(ctx, 0, false)      Variable({
1008            .ctx = ctx,
1009            .isPolyphonic = false,
1010            .isConst = false,
1011            .isFinal = false,
1012            .elements = 0,
1013            .memPos = 0,
1014            .unitFactorMemPos = 0,
1015            .unitType = VM_NO_UNIT
1016        })
1017  {  {
1018      values.resize(size);      values.resize(size);
1019      memset(&values[0], 0, size * sizeof(vmfloat));      memset(&values[0], 0, size * sizeof(vmfloat));
 }  
1020    
1021  RealArrayVariable::RealArrayVariable(ParserContext* ctx, vmint size, ArgsRef values, bool _bConst)      unitFactors.resize(size);
1022      : Variable(ctx, 0, _bConst)      for (size_t i = 0; i < size; ++i)
1023            unitFactors[i] = VM_NO_FACTOR;
1024    }
1025    
1026    RealArrayVariable::RealArrayVariable(ParserContext* ctx, vmint size,
1027                                         ArgsRef values, bool _bConst) :
1028        Variable({
1029            .ctx = ctx,
1030            .isPolyphonic = false,
1031            .isConst = _bConst,
1032            .isFinal = false,
1033            .elements = 0,
1034            .memPos = 0,
1035            .unitFactorMemPos = 0,
1036            .unitType = VM_NO_UNIT
1037        })
1038  {  {
1039      this->values.resize(size);      this->values.resize(size);
1040        this->unitFactors.resize(size);
1041      for (vmint i = 0; i < values->argsCount(); ++i) {      for (vmint i = 0; i < values->argsCount(); ++i) {
1042          VMRealExpr* expr = dynamic_cast<VMRealExpr*>(values->arg(i));          VMRealExpr* expr = dynamic_cast<VMRealExpr*>(values->arg(i));
1043          if (expr) this->values[i] = expr->evalReal();          if (expr) {
1044                this->values[i] = expr->evalReal();
1045                this->unitFactors[i] = expr->unitFactor();
1046            }
1047      }      }
1048  }  }
1049    
1050  RealArrayVariable::RealArrayVariable(ParserContext* ctx, bool bConst)  RealArrayVariable::RealArrayVariable(ParserContext* ctx, bool bConst) :
1051      : Variable(ctx, 0, bConst)      Variable({
1052            .ctx = ctx,
1053            .isPolyphonic = false,
1054            .isConst = bConst,
1055            .isFinal = false,
1056            .elements = 0,
1057            .memPos = 0,
1058            .unitFactorMemPos = 0,
1059            .unitType = VM_NO_UNIT
1060        })
1061  {  {
1062  }  }
1063    
# Line 752  void RealArrayVariable::assignRealElemen Line 1071  void RealArrayVariable::assignRealElemen
1071      values[i] = value;      values[i] = value;
1072  }  }
1073    
1074    vmfloat RealArrayVariable::unitFactorOfElement(vmuint i) const {
1075        if (i >= unitFactors.size()) return VM_NO_FACTOR;
1076        return unitFactors[i];
1077    }
1078    
1079    void RealArrayVariable::assignElementUnitFactor(vmuint i, vmfloat factor) {
1080        if (i >= unitFactors.size()) return;
1081        unitFactors[i] = factor;
1082    }
1083    
1084  void RealArrayVariable::dump(int level) {  void RealArrayVariable::dump(int level) {
1085      printIndents(level);      printIndents(level);
1086      printf("RealArray(");      printf("RealArray(");
# Line 766  void RealArrayVariable::dump(int level) Line 1095  void RealArrayVariable::dump(int level)
1095      printf(")\n");      printf(")\n");
1096  }  }
1097    
1098  BuiltInIntArrayVariable::BuiltInIntArrayVariable(const String& name, VMInt8Array* array)  BuiltInIntArrayVariable::BuiltInIntArrayVariable(const String& name,
1099      : IntArrayVariable(NULL, false), name(name), array(array)                                                   VMInt8Array* array) :
1100        IntArrayVariable(NULL, false),
1101        name(name), array(array)
1102  {  {
1103  }  }
1104    
# Line 785  void BuiltInIntArrayVariable::dump(int l Line 1116  void BuiltInIntArrayVariable::dump(int l
1116      printf("Built-In Int Array Variable '%s'\n", name.c_str());      printf("Built-In Int Array Variable '%s'\n", name.c_str());
1117  }  }
1118    
1119  IntArrayElement::IntArrayElement(IntArrayExprRef array, IntExprRef arrayIndex)  IntArrayElement::IntArrayElement(IntArrayExprRef array, IntExprRef arrayIndex) :
1120      : IntVariable(NULL, false, false, 0), array(array), index(arrayIndex)      IntVariable({
1121            .ctx = NULL,
1122            .isPolyphonic = (array) ? array->isPolyphonic() : false,
1123            .isConst = (array) ? array->isConstExpr() : false,
1124            .isFinal = false,
1125            .elements = 0,
1126            .memPos = 0,
1127            .unitFactorMemPos = 0,
1128            .unitType = VM_NO_UNIT
1129        }),
1130        Unit(VM_NO_UNIT),
1131        array(array), index(arrayIndex), currentIndex(-1)
1132  {      {    
1133  }  }
1134    
# Line 794  void IntArrayElement::assign(Expression* Line 1136  void IntArrayElement::assign(Expression*
1136      IntExpr* valueExpr = dynamic_cast<IntExpr*>(expr);      IntExpr* valueExpr = dynamic_cast<IntExpr*>(expr);
1137      if (!valueExpr) return;      if (!valueExpr) return;
1138      vmint value = valueExpr->evalInt();      vmint value = valueExpr->evalInt();
1139        vmfloat unitFactor = valueExpr->unitFactor();
1140    
1141      if (!index) return;      if (!index) return;
1142      vmint idx = index->evalInt();      vmint idx = currentIndex = index->evalInt();
1143      if (idx < 0 || idx >= array->arraySize()) return;      if (idx < 0 || idx >= array->arraySize()) return;
1144    
1145      array->assignIntElement(idx, value);      array->assignIntElement(idx, value);
1146        array->assignElementUnitFactor(idx, unitFactor);
1147  }  }
1148    
1149  vmint IntArrayElement::evalInt() {  vmint IntArrayElement::evalInt() {
1150      if (!index) return 0;      if (!index) return 0;
1151      vmint idx = index->evalInt();      vmint idx = currentIndex = index->evalInt();
1152      if (idx < 0 || idx >= array->arraySize()) return 0;      if (idx < 0 || idx >= array->arraySize()) return 0;
1153    
1154      return array->evalIntElement(idx);      return array->evalIntElement(idx);
1155  }  }
1156    
1157    vmfloat IntArrayElement::unitFactor() const {
1158        if (!index) return VM_NO_FACTOR;
1159        vmint idx = currentIndex;
1160        if (idx < 0 || idx >= array->arraySize()) return 0;
1161    
1162        return array->unitFactorOfElement(idx);
1163    }
1164    
1165  void IntArrayElement::dump(int level) {  void IntArrayElement::dump(int level) {
1166      printIndents(level);      printIndents(level);
1167      printf("IntArrayElement\n");      printf("IntArrayElement\n");
1168  }  }
1169    
1170  RealArrayElement::RealArrayElement(RealArrayExprRef array, IntExprRef arrayIndex)  RealArrayElement::RealArrayElement(RealArrayExprRef array, IntExprRef arrayIndex) :
1171      : RealVariable(NULL, false, false, 0), array(array), index(arrayIndex)      RealVariable({
1172            .ctx = NULL,
1173            .isPolyphonic = (array) ? array->isPolyphonic() : false,
1174            .isConst = (array) ? array->isConstExpr() : false,
1175            .isFinal = false,
1176            .elements = 0,
1177            .memPos = 0,
1178            .unitFactorMemPos = 0,
1179            .unitType = VM_NO_UNIT
1180        }),
1181        Unit(VM_NO_UNIT),
1182        array(array), index(arrayIndex), currentIndex(-1)
1183  {  {
1184  }  }
1185    
# Line 824  void RealArrayElement::assign(Expression Line 1187  void RealArrayElement::assign(Expression
1187      RealExpr* valueExpr = dynamic_cast<RealExpr*>(expr);      RealExpr* valueExpr = dynamic_cast<RealExpr*>(expr);
1188      if (!valueExpr) return;      if (!valueExpr) return;
1189      vmfloat value = valueExpr->evalReal();      vmfloat value = valueExpr->evalReal();
1190        vmfloat unitFactor = valueExpr->unitFactor();
1191    
1192      if (!index) return;      if (!index) return;
1193      vmint idx = index->evalInt();      vmint idx = currentIndex = index->evalInt();
1194      if (idx < 0 || idx >= array->arraySize()) return;      if (idx < 0 || idx >= array->arraySize()) return;
1195    
1196      array->assignRealElement(idx, value);      array->assignRealElement(idx, value);
1197        array->assignElementUnitFactor(idx, unitFactor);
1198  }  }
1199    
1200  vmfloat RealArrayElement::evalReal() {  vmfloat RealArrayElement::evalReal() {
1201      if (!index) return 0;      if (!index) return 0;
1202      vmint idx = index->evalInt();      vmint idx = currentIndex = index->evalInt();
1203      if (idx < 0 || idx >= array->arraySize()) return 0;      if (idx < 0 || idx >= array->arraySize()) return 0;
1204    
1205      return array->evalRealElement(idx);      return array->evalRealElement(idx);
1206  }  }
1207    
1208    vmfloat RealArrayElement::unitFactor() const {
1209        if (!index) return VM_NO_FACTOR;
1210        vmint idx = currentIndex;
1211        if (idx < 0 || idx >= array->arraySize()) return 0;
1212    
1213        return array->unitFactorOfElement(idx);
1214    }
1215    
1216  void RealArrayElement::dump(int level) {  void RealArrayElement::dump(int level) {
1217      printIndents(level);      printIndents(level);
1218      printf("RealArrayElement\n");      printf("RealArrayElement\n");
1219  }  }
1220    
1221  StringVariable::StringVariable(ParserContext* ctx)  StringVariable::StringVariable(ParserContext* ctx) :
1222      : Variable(ctx,ctx->globalStrVarCount++,false)      Variable({
1223            .ctx = ctx,
1224            .elements = 1,
1225            .memPos = ctx->globalStrVarCount++
1226        })
1227  {  {
1228  }  }
1229    
1230  StringVariable::StringVariable(ParserContext* ctx, bool bConst)  StringVariable::StringVariable(ParserContext* ctx, bool bConst) :
1231      : Variable(ctx,0,bConst)      Variable({
1232            .ctx = ctx,
1233            .memPos = 0,
1234            .isConst = bConst
1235        })
1236  {  {
1237  }  }
1238    
# Line 890  void ConstStringVariable::dump(int level Line 1271  void ConstStringVariable::dump(int level
1271      printf("ConstStringVariable val='%s'\n", value.c_str());      printf("ConstStringVariable val='%s'\n", value.c_str());
1272  }  }
1273    
 MetricPrefix_t ScalarNumberBinaryOp::unitPrefix(vmuint i) const {  
     ScalarNumberExprRef l = (ScalarNumberExprRef) lhs;  
     ScalarNumberExprRef r = (ScalarNumberExprRef) 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();  
 }  
   
1274  bool ScalarNumberBinaryOp::isFinal() const {  bool ScalarNumberBinaryOp::isFinal() const {
1275      ScalarNumberExprRef l = (ScalarNumberExprRef) lhs;      ScalarNumberExprRef l = (ScalarNumberExprRef) lhs;
1276      ScalarNumberExprRef r = (ScalarNumberExprRef) rhs;      ScalarNumberExprRef r = (ScalarNumberExprRef) rhs;
# Line 1003  bool SelectCase::isPolyphonic() const { Line 1372  bool SelectCase::isPolyphonic() const {
1372      return false;      return false;
1373  }  }
1374    
 // 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);  
 // }  
   
1375  void While::dump(int level) {  void While::dump(int level) {
1376      printIndents(level);      printIndents(level);
1377      if (m_condition)      if (m_condition)
# Line 1094  bool ConcatString::isConstExpr() const { Line 1444  bool ConcatString::isConstExpr() const {
1444      return lhs->isConstExpr() && rhs->isConstExpr();      return lhs->isConstExpr() && rhs->isConstExpr();
1445  }  }
1446    
1447    Relation::Relation(ExpressionRef lhs, Type type, ExpressionRef rhs) :
1448        Unit(VM_NO_UNIT),
1449        lhs(lhs), rhs(rhs), type(type)
1450    {
1451    }
1452    
1453    // Equal / unequal comparison of real numbers in NKSP scripts:
1454    //
1455    // Unlike system level languages like C/C++ we are less conservative about
1456    // comparing floating point numbers for 'equalness' or 'unequalness' in NKSP
1457    // scripts. Due to the musical context of the NKSP language we automatically
1458    // take the (to be) expected floating point tolerances into account when
1459    // comparing two floating point numbers with each other, however only for '='
1460    // and '#' operators. The '<=' and '>=' still use conservative low level
1461    // floating point comparison for not breaking their transitivity feature.
1462    
1463    template<typename T_LHS, typename T_RHS>
1464    struct RelComparer {
1465        static inline bool isEqual(T_LHS a, T_RHS b) { // for int comparison ('3 = 3')
1466            return a == b;
1467        }
1468        static inline bool isUnequal(T_LHS a, T_RHS b) { // for int comparison ('3 # 3')
1469            return a != b;
1470        }
1471    };
1472    
1473    template<>
1474    struct RelComparer<float,float> {
1475        static inline bool isEqual(float a, float b) { // for real number comparison ('3.1 = 3.1')
1476            return RTMath::fEqual32(a, b);
1477        }
1478        static inline bool isUnequal(float a, float b) { // for real number comparison ('3.1 # 3.1')
1479            return !RTMath::fEqual32(a, b);
1480        }
1481    };
1482    
1483    template<>
1484    struct RelComparer<double,double> {
1485        static inline bool isEqual(double a, double b) { // for future purpose
1486            return RTMath::fEqual64(a, b);
1487        }
1488        static inline bool isUnqqual(double a, double b) { // for future purpose
1489            return !RTMath::fEqual64(a, b);
1490        }
1491    };
1492    
1493  template<class T_LHS, class T_RHS>  template<class T_LHS, class T_RHS>
1494  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) {
1495      switch (type) {      switch (type) {
1496          case Relation::LESS_THAN:          case Relation::LESS_THAN:
1497              return lhs < rhs;              return lhs < rhs;
# Line 1106  static inline vmint _evalRelation(Relati Line 1502  static inline vmint _evalRelation(Relati
1502          case Relation::GREATER_OR_EQUAL:          case Relation::GREATER_OR_EQUAL:
1503              return lhs >= rhs;              return lhs >= rhs;
1504          case Relation::EQUAL:          case Relation::EQUAL:
1505              return lhs == rhs;              return RelComparer<typeof(lhs),typeof(rhs)>::isEqual(lhs, rhs);
1506          case Relation::NOT_EQUAL:          case Relation::NOT_EQUAL:
1507              return lhs != rhs;              return RelComparer<typeof(lhs),typeof(rhs)>::isUnequal(lhs, rhs);
1508      }      }
1509      return 0;      return 0;
1510  }  }
1511    
1512    template<class T_LVALUE, class T_RVALUE, class T_LEXPR, class T_REXPR>
1513    inline vmint _evalRealRelation(Relation::Type type,
1514                                   T_LVALUE lvalue, T_RVALUE rvalue,
1515                                   T_LEXPR* pLHS, T_REXPR* pRHS)
1516    {
1517        if (pLHS->unitFactor() == pRHS->unitFactor())
1518            return _evalRelation(type, lvalue, rvalue);
1519        if (pLHS->unitFactor() < pRHS->unitFactor())
1520            return _evalRelation(type, lvalue, Unit::convRealToUnitFactor(rvalue, pRHS, pLHS));
1521        else
1522            return _evalRelation(type, Unit::convRealToUnitFactor(lvalue, pLHS, pRHS), rvalue);
1523    }
1524    
1525    template<class T_LEXPR, class T_REXPR>
1526    inline vmint _evalIntRelation(Relation::Type type,
1527                                  vmint lvalue, vmint rvalue,
1528                                  T_LEXPR* pLHS, T_REXPR* pRHS)
1529    {
1530        if (pLHS->unitFactor() == pRHS->unitFactor())
1531            return _evalRelation(type, lvalue, rvalue);
1532        if (pLHS->unitFactor() < pRHS->unitFactor())
1533            return _evalRelation(type, lvalue, Unit::convIntToUnitFactor(rvalue, pRHS, pLHS));
1534        else
1535            return _evalRelation(type, Unit::convIntToUnitFactor(lvalue, pLHS, pRHS), rvalue);
1536    }
1537    
1538  vmint Relation::evalInt() {  vmint Relation::evalInt() {
1539      const ExprType_t lType = lhs->exprType();      const ExprType_t lType = lhs->exprType();
1540      const ExprType_t rType = rhs->exprType();      const ExprType_t rType = rhs->exprType();
# Line 1126  vmint Relation::evalInt() { Line 1548  vmint Relation::evalInt() {
1548                  return 0;                  return 0;
1549          }          }
1550      } else if (lType == REAL_EXPR && rType == REAL_EXPR) {      } else if (lType == REAL_EXPR && rType == REAL_EXPR) {
1551          return _evalRelation(          vmfloat lvalue = lhs->asReal()->evalReal();
1552              type, lhs->asReal()->evalReal(), rhs->asReal()->evalReal()          vmfloat rvalue = rhs->asReal()->evalReal();
1553            return _evalRealRelation(
1554                type, lvalue, rvalue, lhs->asReal(), rhs->asReal()
1555          );          );
1556      } else if (lType == REAL_EXPR && rType == INT_EXPR) {      } else if (lType == REAL_EXPR && rType == INT_EXPR) {
1557          return _evalRelation(          vmfloat lvalue = lhs->asReal()->evalReal();
1558              type, lhs->asReal()->evalReal(), rhs->asInt()->evalInt()          vmint rvalue = rhs->asInt()->evalInt();
1559            return _evalRealRelation(
1560                type, lvalue, rvalue, lhs->asReal(), rhs->asInt()
1561          );          );
1562      } else if (lType == INT_EXPR && rType == REAL_EXPR) {      } else if (lType == INT_EXPR && rType == REAL_EXPR) {
1563          return _evalRelation(          vmint lvalue = lhs->asInt()->evalInt();
1564              type, lhs->asInt()->evalInt(), rhs->asReal()->evalReal()          vmfloat rvalue = rhs->asReal()->evalReal();
1565            return _evalRealRelation(
1566                type, lvalue, rvalue, lhs->asInt(), rhs->asReal()
1567          );          );
1568      } else {      } else {
1569          return _evalRelation(          vmint lvalue = lhs->asInt()->evalInt();
1570              type, lhs->asInt()->evalInt(), rhs->asInt()->evalInt()          vmint rvalue = rhs->asInt()->evalInt();
1571            return _evalIntRelation(
1572                type, lvalue, rvalue, lhs->asInt(), rhs->asInt()
1573          );          );
1574      }      }
1575  }  }
# Line 1181  bool Relation::isConstExpr() const { Line 1611  bool Relation::isConstExpr() const {
1611  vmint Or::evalInt() {  vmint Or::evalInt() {
1612      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1613      if (pLHS->evalInt()) return 1;      if (pLHS->evalInt()) return 1;
1614      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
1615      return (pRHS->evalInt()) ? 1 : 0;      return (pRHS->evalInt()) ? 1 : 0;
1616  }  }
1617    
# Line 1409  void ParserContext::registerBuiltInConst Line 1839  void ParserContext::registerBuiltInConst
1839      for (std::map<String,vmint>::const_iterator it = vars.begin();      for (std::map<String,vmint>::const_iterator it = vars.begin();
1840           it != vars.end(); ++it)           it != vars.end(); ++it)
1841      {      {
1842          ConstIntVariableRef ref = new ConstIntVariable(it->second);          ConstIntVariableRef ref = new ConstIntVariable({
1843                .value = it->second
1844            });
1845          vartable[it->first] = ref;          vartable[it->first] = ref;
1846      }      }
1847  }  }

Legend:
Removed from v.3577  
changed lines
  Added in v.3581

  ViewVC Help
Powered by ViewVC