/[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 3561 by schoenebeck, Fri Aug 23 11:44:00 2019 UTC revision 3582 by schoenebeck, Fri Aug 30 12:23:40 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() {
114        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;
127  }  }
128    
129  MetricPrefix_t Unit::unitPrefix(vmuint i) const {  String RealArrayExpr::evalCastToStr() {
130      if (i >= prefix.size()) return VM_NO_PREFIX;      String s = "{";
131      return prefix[i];      for (vmint i = 0; i < arraySize(); ++i) {
132            vmfloat val = evalRealElement(i);
133            vmfloat factor = unitFactorOfElement(i);
134            if (i) s += ",";
135            s += ToString(val) + _unitFactorToShortStr(factor);
136        }
137        s += "}";
138        return s;
139  }  }
140    
141  void Unit::setUnit(const std::vector<MetricPrefix_t>& prefix, StdUnit_t type) {  IntLiteral::IntLiteral(const IntLitDef& def) :
142      this->prefix.resize( prefix.size() );      IntExpr(), Unit(def.unitType),
143      for (vmuint i = 0; i < prefix.size(); ++i)      value(def.value), unitPrefixFactor(def.unitFactor),
144          this->prefix[i] = prefix[i];      finalVal(def.isFinal)
145    {
146    }
147    
148      unit = type;  vmint IntLiteral::evalInt() {
149        return value;
150  }  }
151    
152  void Unit::setUnit(const MetricPrefix_t* prefixes, StdUnit_t type) {  void IntLiteral::dump(int level) {
153      unit = type;      printIndents(level);
154      prefix.clear();      printf("IntLiteral %lld\n", value);
     for (int i = 0; i < 2 && prefixes[i]; ++i)  
         prefix.add(prefixes[i]);  
155  }  }
156    
157  void Unit::copyUnitFrom(const IntExprRef& src) {  RealLiteral::RealLiteral(const RealLitDef& def) :
158      unit = src->unitType();      RealExpr(), Unit(def.unitType),
159      prefix.clear();      value(def.value), unitPrefixFactor(def.unitFactor),
160      for (int i = 0; true; ++i) {      finalVal(def.isFinal)
161          MetricPrefix_t p = src->unitPrefix(i);  {
         if (!p) return;  
         prefix.add(p);  
     }  
162  }  }
163    
164  vmint IntLiteral::evalInt() {  vmfloat RealLiteral::evalReal() {
165      return value;      return value;
166  }  }
167    
168  void IntLiteral::dump(int level) {  void RealLiteral::dump(int level) {
169      printIndents(level);      printIndents(level);
170      printf("IntLiteral %lld\n", value);      printf("RealLiteral %f\n", value);
171  }  }
172    
173  void StringLiteral::dump(int level) {  void StringLiteral::dump(int level) {
# Line 89  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(NumberExprRef lhs, NumberExprRef 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() {
203        RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
204        RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);
205        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 NumberExpr* pLHS = dynamic_cast<const NumberExpr*>(&*lhs);
219        const NumberExpr* pRHS = dynamic_cast<const NumberExpr*>(&*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 106  void Add::dump(int level) { Line 231  void Add::dump(int level) {
231      printf(")\n");      printf(")\n");
232  }  }
233    
234    Sub::Sub(NumberExprRef lhs, NumberExprRef 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() {
259        RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
260        RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);
261        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 NumberExpr* pLHS = dynamic_cast<const NumberExpr*>(&*lhs);
275        const NumberExpr* pRHS = dynamic_cast<const NumberExpr*>(&*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 123  void Sub::dump(int level) { Line 287  void Sub::dump(int level) {
287      printf(")\n");      printf(")\n");
288  }  }
289    
290    Mul::Mul(NumberExprRef lhs, NumberExprRef 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);;
302      return (pLHS && pRHS) ? pLHS->evalInt() * pRHS->evalInt() : 0;      return (pLHS && pRHS) ? pLHS->evalInt() * pRHS->evalInt() : 0;
303  }  }
304    
305    vmfloat Mul::evalReal() {
306        RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
307        RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);;
308        return (pLHS && pRHS) ? pLHS->evalReal() * pRHS->evalReal() : 0;
309    }
310    
311  void Mul::dump(int level) {  void Mul::dump(int level) {
312      printIndents(level);      printIndents(level);
313      printf("Mul(\n");      printf("Mul(\n");
# Line 140  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 IntExpr* pLHS = dynamic_cast<const IntExpr*>(&*lhs);      const NumberExpr* pLHS = dynamic_cast<const NumberExpr*>(&*lhs);
324      const IntExpr* pRHS = dynamic_cast<const IntExpr*>(&*rhs);      const NumberExpr* pRHS = dynamic_cast<const NumberExpr*>(&*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(NumberExprRef lhs, NumberExprRef rhs) :
329      const IntExpr* pLHS = dynamic_cast<const IntExpr*>(&*lhs);      VaritypeScalarBinaryOp(lhs, rhs),
330      const IntExpr* pRHS = dynamic_cast<const IntExpr*>(&*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 164  vmint Div::evalInt() { Line 345  vmint Div::evalInt() {
345      return l / r;      return l / r;
346  }  }
347    
348    vmfloat Div::evalReal() {
349        RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
350        RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);
351        if (!pLHS || !pRHS) return 0;
352        vmfloat l = pLHS->evalReal();
353        vmfloat r = pRHS->evalReal();
354        if (r == vmfloat(0)) return 0;
355        return l / r;
356    }
357    
358  void Div::dump(int level) {  void Div::dump(int level) {
359      printIndents(level);      printIndents(level);
360      printf("Div(\n");      printf("Div(\n");
# Line 175  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 {
370      const IntExpr* pLHS = dynamic_cast<const IntExpr*>(&*lhs);      const NumberExpr* pLHS = dynamic_cast<const NumberExpr*>(&*lhs);
371      const IntExpr* pRHS = dynamic_cast<const IntExpr*>(&*rhs);      const NumberExpr* pRHS = dynamic_cast<const NumberExpr*>(&*rhs);
372      // 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 IntExpr* pLHS = dynamic_cast<const IntExpr*>(&*lhs);  
     const IntExpr* pRHS = dynamic_cast<const IntExpr*>(&*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();  
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 317  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 348  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 358  void FunctionCall::dump(int level) { Line 552  void FunctionCall::dump(int level) {
552    
553  ExprType_t FunctionCall::exprType() const {  ExprType_t FunctionCall::exprType() const {
554      if (!fn) return EMPTY_EXPR;      if (!fn) return EMPTY_EXPR;
555      return fn->returnType();      FunctionCall* self = const_cast<FunctionCall*>(this);
556        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        VMNumberExpr* scalar = expr->asNumber();
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() {
# Line 369  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;
593      return intExpr->evalInt();      return intExpr->evalInt();
594  }  }
595    
596    vmfloat FunctionCall::evalReal() {
597        result = execVMFn();
598        if (!result) return 0;
599        VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());
600        if (!realExpr) return 0;
601        return realExpr->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 {
611        if (!result) return 0;
612        VMRealArrayExpr* realArrExpr = dynamic_cast<VMRealArrayExpr*>(result->resultValue());
613        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 399  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      if (result->resultValue()->exprType() == STRING_EXPR) {      const ExprType_t resultType = result->resultValue()->exprType();
628        if (resultType == STRING_EXPR) {
629          VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());          VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());
630          return strExpr ? strExpr->evalStr() : "";          return strExpr ? strExpr->evalStr() : "";
631        } else if (resultType == REAL_EXPR) {
632            VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());
633            return realExpr ? ToString(realExpr->evalReal()) : "";
634      } else {      } else {
635          VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());          VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());
636          return intExpr ? ToString(intExpr->evalInt()) : "";          return intExpr ? ToString(intExpr->evalInt()) : "";
637      }      }
638  }  }
639    
640  IntVariable::IntVariable(ParserContext* ctx)  Variable::Variable(const VariableDecl& decl) :
641      : Variable(ctx, ctx ? ctx->globalIntVarCount++ : 0, false),      context(decl.ctx), memPos(decl.memPos), bConst(decl.isConst)
642        Unit(),  {
643        polyphonic(false), finalVal(false)  }
644    
645    NumberVariable::NumberVariable(const VariableDecl& decl) :
646        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 NumberVariable::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 425  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 polyphonic, bool bConst, vmint size)  IntVariable::IntVariable(const VariableDecl& decl) :
667      : Variable(ctx, !ctx ? 0 : polyphonic ? postfixInc(ctx->polyphonicIntVarCount, size) : postfixInc(ctx->globalIntVarCount, size), bConst),      NumberVariable({
668        Unit(),          .ctx = decl.ctx,
669        polyphonic(polyphonic), finalVal(false)          .isPolyphonic = decl.isPolyphonic,
670  {          .isConst = decl.isConst,
671      //printf("InvVar size=%d parserCtx=0x%lx\n", size, (uint64_t)ctx);          .isFinal = decl.isFinal,
672      if (polyphonic) {          .elements = decl.elements,
673          //printf("polyIntVar memPOS=%d\n", memPos);          .memPos = (
674          assert(ctx);              (!decl.ctx) ? 0 :
675      }                  (decl.isPolyphonic) ?
676                        postfixInc(decl.ctx->polyphonicIntVarCount, decl.elements) :
677                        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 (polyphonic)          //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    
707  vmint IntVariable::evalInt() {  vmint IntVariable::evalInt() {
708      //printf("IntVariable::eval pos=%d\n", memPos);      //printf("IntVariable::eval pos=%d\n", memPos);
709      if (polyphonic) {      if (isPolyphonic()) {
710          //printf("evalInt() poly memPos=%d execCtx=0x%lx\n", memPos, (uint64_t)context->execContext);          //printf("evalInt() poly memPos=%d execCtx=0x%lx\n", memPos, (uint64_t)context->execContext);
711          return context->execContext->polyphonicIntMemory[memPos];          return context->execContext->polyphonicIntMemory[memPos];
712      }      }
# Line 462  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  //ConstIntVariable::ConstIntVariable(ParserContext* ctx, int value)  RealVariable::RealVariable(const VariableDecl& decl) :
723  ConstIntVariable::ConstIntVariable(vmint value)      NumberVariable({
724      : IntVariable(NULL,false,true), value(value)          .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("RealVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);
746        assert(!decl.isPolyphonic || decl.ctx);
747    }
748    
749    void RealVariable::assign(Expression* expr) {
750        RealExpr* realExpr = dynamic_cast<RealExpr*>(expr);
751        if (realExpr) {
752            //NOTE: sequence matters! evalReal() must be called before getting unitFactor() !
753            if (isPolyphonic()) {
754                context->execContext->polyphonicRealMemory[memPos] = realExpr->evalReal();
755                context->execContext->polyphonicUnitFactorMemory[unitFactorMemPos] = realExpr->unitFactor();
756            } else {
757                (*context->globalRealMemory)[memPos] = realExpr->evalReal();
758                (*context->globalUnitFactorMemory)[unitFactorMemPos] = realExpr->unitFactor();
759            }
760        }
761    }
762    
763    vmfloat RealVariable::evalReal() {
764        //printf("RealVariable::eval pos=%d\n", memPos);
765        if (isPolyphonic()) {
766            //printf("evalReal() poly memPos=%d execCtx=0x%lx\n", memPos, (uint64_t)context->execContext);
767            return context->execContext->polyphonicRealMemory[memPos];
768        }
769        return (*context->globalRealMemory)[memPos];
770    }
771    
772    void RealVariable::dump(int level) {
773        printIndents(level);
774        printf("RealVariable\n");
775        //printf("RealVariable memPos=%d\n", memPos);
776    }
777    
778    ConstIntVariable::ConstIntVariable(const IntVarDef& def) :
779        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 488  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  BuiltInIntVariable::BuiltInIntVariable(const String& name, VMIntPtr* ptr)  ConstRealVariable::ConstRealVariable(const RealVarDef& def) :
815      : IntVariable(NULL,false,false), name(name), ptr(ptr)      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    
830    void ConstRealVariable::assign(Expression* expr) {
831        // ignore assignment
832    }
833    
834    vmfloat ConstRealVariable::evalReal() {
835        return value;
836    }
837    
838    void ConstRealVariable::dump(int level) {
839        printIndents(level);
840        printf("ConstRealVariable val=%f\n", value);
841    }
842    
843    BuiltInIntVariable::BuiltInIntVariable(const String& name, VMIntPtr* ptr) :
844        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 508  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 518  void PolyphonicIntVariable::dump(int lev Line 891  void PolyphonicIntVariable::dump(int lev
891      printf("PolyphonicIntVariable\n");      printf("PolyphonicIntVariable\n");
892  }  }
893    
894  IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size)  PolyphonicRealVariable::PolyphonicRealVariable(const VariableDecl& decl) :
895      : Variable(ctx, 0, 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    
909    void PolyphonicRealVariable::dump(int level) {
910        printIndents(level);
911        printf("PolyphonicRealVariable\n");
912    }
913    
914    IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size) :
915        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 550  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 564  void IntArrayVariable::dump(int level) { Line 1003  void IntArrayVariable::dump(int level) {
1003      printf(")\n");      printf(")\n");
1004  }  }
1005    
1006  BuiltInIntArrayVariable::BuiltInIntArrayVariable(const String& name, VMInt8Array* array)  RealArrayVariable::RealArrayVariable(ParserContext* ctx, vmint size) :
1007      : IntArrayVariable(NULL, false), name(name), array(array)      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);
1019        memset(&values[0], 0, size * sizeof(vmfloat));
1020    
1021        unitFactors.resize(size);
1022        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);
1040        this->unitFactors.resize(size);
1041        for (vmint i = 0; i < values->argsCount(); ++i) {
1042            VMRealExpr* expr = dynamic_cast<VMRealExpr*>(values->arg(i));
1043            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) :
1051        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    
1064    vmfloat RealArrayVariable::evalRealElement(vmuint i) {
1065        if (i >= values.size()) return 0;
1066        return values[i];
1067    }
1068    
1069    void RealArrayVariable::assignRealElement(vmuint i, vmfloat value) {
1070        if (i >= values.size()) return;
1071        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) {
1085        printIndents(level);
1086        printf("RealArray(");
1087        for (vmint i = 0; i < values.size(); ++i) {
1088            if (i % 12 == 0) {
1089                printf("\n");
1090                printIndents(level+1);
1091            }
1092            printf("%f, ", values[i]);
1093        }
1094        printIndents(level);
1095        printf(")\n");
1096    }
1097    
1098    BuiltInIntArrayVariable::BuiltInIntArrayVariable(const String& name,
1099                                                     VMInt8Array* array) :
1100        IntArrayVariable(NULL, false),
1101        name(name), array(array)
1102  {  {
1103  }  }
1104    
# Line 583  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 592  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  StringVariable::StringVariable(ParserContext* ctx)  RealArrayElement::RealArrayElement(RealArrayExprRef array, IntExprRef arrayIndex) :
1171      : Variable(ctx,ctx->globalStrVarCount++,false)      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    
1186  StringVariable::StringVariable(ParserContext* ctx, bool bConst)  void RealArrayElement::assign(Expression* expr) {
1187      : Variable(ctx,0,bConst)      RealExpr* valueExpr = dynamic_cast<RealExpr*>(expr);
1188        if (!valueExpr) return;
1189        vmfloat value = valueExpr->evalReal();
1190        vmfloat unitFactor = valueExpr->unitFactor();
1191    
1192        if (!index) return;
1193        vmint idx = currentIndex = index->evalInt();
1194        if (idx < 0 || idx >= array->arraySize()) return;
1195    
1196        array->assignRealElement(idx, value);
1197        array->assignElementUnitFactor(idx, unitFactor);
1198    }
1199    
1200    vmfloat RealArrayElement::evalReal() {
1201        if (!index) return 0;
1202        vmint idx = currentIndex = index->evalInt();
1203        if (idx < 0 || idx >= array->arraySize()) return 0;
1204    
1205        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) {
1217        printIndents(level);
1218        printf("RealArrayElement\n");
1219    }
1220    
1221    StringVariable::StringVariable(ParserContext* ctx) :
1222        Variable({
1223            .ctx = ctx,
1224            .elements = 1,
1225            .memPos = ctx->globalStrVarCount++
1226        })
1227    {
1228    }
1229    
1230    StringVariable::StringVariable(ParserContext* ctx, bool bConst) :
1231        Variable({
1232            .ctx = ctx,
1233            .memPos = 0,
1234            .isConst = bConst
1235        })
1236  {  {
1237  }  }
1238    
# Line 658  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    
1274  MetricPrefix_t IntBinaryOp::unitPrefix(vmuint i) const {  bool NumberBinaryOp::isFinal() const {
1275      IntExprRef l = (IntExprRef) lhs;      NumberExprRef l = (NumberExprRef) lhs;
1276      IntExprRef r = (IntExprRef) rhs;      NumberExprRef r = (NumberExprRef) rhs;
1277      return (r->unitFactor() < l->unitFactor()) ? r->unitPrefix(i) : l->unitPrefix(i);      return l->isFinal() || r->isFinal();
1278  }  }
1279    
1280  StdUnit_t IntBinaryOp::unitType() const {  ExprType_t VaritypeScalarBinaryOp::exprType() const {
1281      IntExprRef l = (IntExprRef) lhs;      return (lhs->exprType() == REAL_EXPR || rhs->exprType() == REAL_EXPR) ? REAL_EXPR : INT_EXPR;
     IntExprRef r = (IntExprRef) rhs;  
     return (l->unitType()) ? l->unitType() : r->unitType();  
1282  }  }
1283    
1284  bool IntBinaryOp::isFinal() const {  String VaritypeScalarBinaryOp::evalCastToStr() {
1285      IntExprRef l = (IntExprRef) lhs;      return (exprType() == REAL_EXPR) ?
1286      IntExprRef r = (IntExprRef) rhs;          RealExpr::evalCastToStr() : IntExpr::evalCastToStr();
     return l->isFinal() || r->isFinal();  
1287  }  }
1288    
1289  void If::dump(int level) {  void If::dump(int level) {
# Line 762  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 816  Statements* SyncBlock::statements() cons Line 1407  Statements* SyncBlock::statements() cons
1407      return (m_statements) ? const_cast<Statements*>( &*m_statements ) : NULL;      return (m_statements) ? const_cast<Statements*>( &*m_statements ) : NULL;
1408  }  }
1409    
1410    String Neg::evalCastToStr() {
1411        return expr->evalCastToStr();
1412    }
1413    
1414  void Neg::dump(int level) {  void Neg::dump(int level) {
1415      printIndents(level);      printIndents(level);
1416      printf("Negative Expr\n");      printf("Negative Expr\n");
# Line 849  bool ConcatString::isConstExpr() const { Line 1444  bool ConcatString::isConstExpr() const {
1444      return lhs->isConstExpr() && rhs->isConstExpr();      return lhs->isConstExpr() && rhs->isConstExpr();
1445  }  }
1446    
1447  vmint Relation::evalInt() {  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>
1494    inline vmint _evalRelation(Relation::Type type, T_LHS lhs, T_RHS rhs) {
1495      switch (type) {      switch (type) {
1496          case LESS_THAN:          case Relation::LESS_THAN:
1497              return lhs->evalInt() < rhs->evalInt();              return lhs < rhs;
1498          case GREATER_THAN:          case Relation::GREATER_THAN:
1499              return lhs->evalInt() > rhs->evalInt();              return lhs > rhs;
1500          case LESS_OR_EQUAL:          case Relation::LESS_OR_EQUAL:
1501              return lhs->evalInt() <= rhs->evalInt();              return lhs <= rhs;
1502          case GREATER_OR_EQUAL:          case Relation::GREATER_OR_EQUAL:
1503              return lhs->evalInt() >= rhs->evalInt();              return lhs >= rhs;
1504          case EQUAL:          case Relation::EQUAL:
1505              if (lhs->exprType() == STRING_EXPR || rhs->exprType() == STRING_EXPR)              return RelComparer<typeof(lhs),typeof(rhs)>::isEqual(lhs, rhs);
1506            case Relation::NOT_EQUAL:
1507                return RelComparer<typeof(lhs),typeof(rhs)>::isUnequal(lhs, rhs);
1508        }
1509        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() {
1539        const ExprType_t lType = lhs->exprType();
1540        const ExprType_t rType = rhs->exprType();
1541        if (lType == STRING_EXPR || rType == STRING_EXPR) {
1542            switch (type) {
1543                case EQUAL:
1544                  return lhs->evalCastToStr() == rhs->evalCastToStr();                  return lhs->evalCastToStr() == rhs->evalCastToStr();
1545              else              case NOT_EQUAL:
                 return lhs->evalInt() == rhs->evalInt();  
         case NOT_EQUAL:  
             if (lhs->exprType() == STRING_EXPR || rhs->exprType() == STRING_EXPR)  
1546                  return lhs->evalCastToStr() != rhs->evalCastToStr();                  return lhs->evalCastToStr() != rhs->evalCastToStr();
1547              else              default:
1548                  return lhs->evalInt() != rhs->evalInt();                  return 0;
1549            }
1550        } else if (lType == REAL_EXPR && rType == REAL_EXPR) {
1551            vmfloat lvalue = lhs->asReal()->evalReal();
1552            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) {
1557            vmfloat lvalue = lhs->asReal()->evalReal();
1558            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) {
1563            vmint lvalue = lhs->asInt()->evalInt();
1564            vmfloat rvalue = rhs->asReal()->evalReal();
1565            return _evalRealRelation(
1566                type, lvalue, rvalue, lhs->asInt(), rhs->asReal()
1567            );
1568        } else {
1569            vmint lvalue = lhs->asInt()->evalInt();
1570            vmint rvalue = rhs->asInt()->evalInt();
1571            return _evalIntRelation(
1572                type, lvalue, rvalue, lhs->asInt(), rhs->asInt()
1573            );
1574      }      }
     return 0;  
1575  }  }
1576    
1577  void Relation::dump(int level) {  void Relation::dump(int level) {
# Line 910  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 993  void BitwiseNot::dump(int level) { Line 1694  void BitwiseNot::dump(int level) {
1694      printf(")\n");      printf(")\n");
1695  }  }
1696    
1697    String Final::evalCastToStr() {
1698        if (exprType() == REAL_EXPR)
1699            return ToString(evalReal());
1700        else
1701            return ToString(evalInt());
1702    }
1703    
1704  void Final::dump(int level) {  void Final::dump(int level) {
1705      printIndents(level);      printIndents(level);
1706      printf("Final(\n");      printf("Final(\n");
# Line 1029  IntVariableRef ParserContext::globalIntV Line 1737  IntVariableRef ParserContext::globalIntV
1737      return globalVar(name);      return globalVar(name);
1738  }  }
1739    
1740    RealVariableRef ParserContext::globalRealVar(const String& name) {
1741        return globalVar(name);
1742    }
1743    
1744  StringVariableRef ParserContext::globalStrVar(const String& name) {  StringVariableRef ParserContext::globalStrVar(const String& name) {
1745      return globalVar(name);      return globalVar(name);
1746  }  }
# Line 1039  ParserContext::~ParserContext() { Line 1751  ParserContext::~ParserContext() {
1751          delete globalIntMemory;          delete globalIntMemory;
1752          globalIntMemory = NULL;          globalIntMemory = NULL;
1753      }      }
1754        if (globalRealMemory) {
1755            delete globalRealMemory;
1756            globalRealMemory = NULL;
1757        }
1758  }  }
1759    
1760  void ParserContext::addErr(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt) {  void ParserContext::addErr(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt) {
# Line 1123  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  }  }
# Line 1166  void ExecContext::forkTo(VMExecContext* Line 1884  void ExecContext::forkTo(VMExecContext*
1884      ExecContext* child = dynamic_cast<ExecContext*>(ectx);      ExecContext* child = dynamic_cast<ExecContext*>(ectx);
1885    
1886      child->polyphonicIntMemory.copyFlatFrom(polyphonicIntMemory);      child->polyphonicIntMemory.copyFlatFrom(polyphonicIntMemory);
1887        child->polyphonicRealMemory.copyFlatFrom(polyphonicRealMemory);
1888      child->status = VM_EXEC_SUSPENDED;      child->status = VM_EXEC_SUSPENDED;
1889      child->flags = STMT_SUCCESS;      child->flags = STMT_SUCCESS;
1890      child->stack.copyFlatFrom(stack);      child->stack.copyFlatFrom(stack);

Legend:
Removed from v.3561  
changed lines
  Added in v.3582

  ViewVC Help
Powered by ViewVC