/[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 3034 by schoenebeck, Mon Oct 31 00:05:00 2016 UTC revision 3582 by schoenebeck, Fri Aug 30 12:23:40 2019 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (c) 2014 - 2016 Christian Schoenebeck and Andreas Persson   * Copyright (c) 2014 - 2019 Christian Schoenebeck and Andreas Persson
3   *   *
4   * http://www.linuxsampler.org   * http://www.linuxsampler.org
5   *   *
# 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 {
18            
19  bool isNoOperation(StatementRef statement) {  bool isNoOperation(StatementRef statement) {
20      NoOperation* noOp = dynamic_cast<NoOperation*>(&*statement);      return statement->statementType() == STMT_NOOP;
     return noOp;  
21  }  }
22            
23  Node::Node() {  Node::Node() {
# Line 31  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() {
118        String s = "{";
119        for (vmint i = 0; i < arraySize(); ++i) {
120            vmint val = evalIntElement(i);
121            vmfloat factor = unitFactorOfElement(i);
122            if (i) s += ",";
123            s += ToString(val) + _unitFactorToShortStr(factor);
124        }
125        s += "}";
126        return s;
127    }
128    
129    String RealArrayExpr::evalCastToStr() {
130        String s = "{";
131        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    IntLiteral::IntLiteral(const IntLitDef& def) :
142        IntExpr(), Unit(def.unitType),
143        value(def.value), unitPrefixFactor(def.unitFactor),
144        finalVal(def.isFinal)
145    {
146  }  }
147    
148  int IntLiteral::evalInt() {  vmint IntLiteral::evalInt() {
149      return value;      return value;
150  }  }
151    
152  void IntLiteral::dump(int level) {  void IntLiteral::dump(int level) {
153      printIndents(level);      printIndents(level);
154      printf("IntLiteral %d\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() {
165        return value;
166    }
167    
168    void RealLiteral::dump(int level) {
169        printIndents(level);
170        printf("RealLiteral %f\n", value);
171  }  }
172    
173  void StringLiteral::dump(int level) {  void StringLiteral::dump(int level) {
# Line 49  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  int Add::evalInt() {  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() {
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 66  void Add::dump(int level) { Line 231  void Add::dump(int level) {
231      printf(")\n");      printf(")\n");
232  }  }
233    
234  int Sub::evalInt() {  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() {
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 83  void Sub::dump(int level) { Line 287  void Sub::dump(int level) {
287      printf(")\n");      printf(")\n");
288  }  }
289    
290  int Mul::evalInt() {  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() {
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 100  void Mul::dump(int level) { Line 319  void Mul::dump(int level) {
319      printf(")\n");      printf(")\n");
320  }  }
321    
322  int Div::evalInt() {  vmfloat Mul::unitFactor() const {
323        const NumberExpr* pLHS = dynamic_cast<const NumberExpr*>(&*lhs);
324        const NumberExpr* pRHS = dynamic_cast<const NumberExpr*>(&*rhs);
325        return pLHS->unitFactor() * pRHS->unitFactor();
326    }
327    
328    Div::Div(NumberExprRef lhs, NumberExprRef rhs) :
329        VaritypeScalarBinaryOp(lhs, rhs),
330        Unit(
331            // the NKSP parser only allows either A) a unit type on left side and none
332            // 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() {
339      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
340      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
341      if (!pLHS || !pRHS) return 0;      if (!pLHS || !pRHS) return 0;
342      int l = pLHS->evalInt();      vmint l = pLHS->evalInt();
343      int r = pRHS->evalInt();      vmint r = pRHS->evalInt();
344      if (r == 0) return 0;      if (r == 0) return 0;
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 121  void Div::dump(int level) { Line 366  void Div::dump(int level) {
366      printf(")\n");      printf(")\n");
367  }  }
368    
369  int Mod::evalInt() {  vmfloat Div::unitFactor() const {
370        const NumberExpr* pLHS = dynamic_cast<const NumberExpr*>(&*lhs);
371        const NumberExpr* pRHS = dynamic_cast<const NumberExpr*>(&*rhs);
372        return pLHS->unitFactor() / pRHS->unitFactor();
373    }
374    
375    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 149  void Args::dump(int level) { Line 400  void Args::dump(int level) {
400  }  }
401    
402  bool Args::isPolyphonic() const {  bool Args::isPolyphonic() const {
403      for (int i = 0; i < args.size(); ++i)      for (vmint i = 0; i < args.size(); ++i)
404          if (args[i]->isPolyphonic())          if (args[i]->isPolyphonic())
405              return true;              return true;
406      return false;      return false;
# Line 177  void EventHandlers::dump(int level) { Line 428  void EventHandlers::dump(int level) {
428  }  }
429    
430  EventHandler* EventHandlers::eventHandlerByName(const String& name) const {  EventHandler* EventHandlers::eventHandlerByName(const String& name) const {
431      for (int i = 0; i < args.size(); ++i)      for (vmint i = 0; i < args.size(); ++i)
432          if (args.at(i)->eventHandlerName() == name)          if (args.at(i)->eventHandlerName() == name)
433              return const_cast<EventHandler*>(&*args.at(i));              return const_cast<EventHandler*>(&*args.at(i));
434      return NULL;      return NULL;
# Line 189  EventHandler* EventHandlers::eventHandle Line 440  EventHandler* EventHandlers::eventHandle
440  }  }
441    
442  bool EventHandlers::isPolyphonic() const {  bool EventHandlers::isPolyphonic() const {
443      for (int i = 0; i < args.size(); ++i)      for (vmint i = 0; i < args.size(); ++i)
444          if (args[i]->isPolyphonic())          if (args[i]->isPolyphonic())
445              return true;              return true;
446      return false;      return false;
# Line 241  Statement* Statements::statement(uint i) Line 492  Statement* Statements::statement(uint i)
492  }  }
493    
494  bool Statements::isPolyphonic() const {  bool Statements::isPolyphonic() const {
495      for (int i = 0; i < args.size(); ++i)      for (vmint i = 0; i < args.size(); ++i)
496          if (args[i]->isPolyphonic())          if (args[i]->isPolyphonic())
497              return true;              return true;
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    
511  int DynamicVariableCall::evalInt() {  vmint DynamicVariableCall::evalInt() {
512      VMIntExpr* expr = dynamic_cast<VMIntExpr*>(dynVar);      VMIntExpr* expr = dynamic_cast<VMIntExpr*>(dynVar);
513      if (!expr) return 0;      if (!expr) return 0;
514      return expr->evalInt();      return expr->evalInt();
# Line 278  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 288  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 299  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  int 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 {
605        if (!result) return 0;
606        VMIntArrayExpr* intArrExpr = dynamic_cast<VMIntArrayExpr*>(result->resultValue());
607        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 322  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), polyphonic(false)      context(decl.ctx), memPos(decl.memPos), bConst(decl.isConst)
642  {  {
     //printf("globalIntVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);  
     assert(ctx);  
643  }  }
644    
645  inline static int postfixInc(int& object, int incBy) {  NumberVariable::NumberVariable(const VariableDecl& decl) :
646      const int i = object;      Variable(decl),
647        Unit(decl.unitType),
648        unitFactorMemPos(decl.unitFactorMemPos), polyphonic(decl.isPolyphonic),
649        finalVal(decl.isFinal)
650    {
651    }
652    
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) {
661        const vmint i = object;
662      object += incBy;      object += incBy;
663      return i;      return i;
664  }  }
665    
666  IntVariable::IntVariable(ParserContext* ctx, bool polyphonic, bool bConst, int size)  IntVariable::IntVariable(const VariableDecl& decl) :
667      : Variable(ctx, !ctx ? 0 : polyphonic ? postfixInc(ctx->polyphonicIntVarCount, size) : postfixInc(ctx->globalIntVarCount, size), bConst),      NumberVariable({
668        polyphonic(polyphonic)          .ctx = decl.ctx,
669  {          .isPolyphonic = decl.isPolyphonic,
670      //printf("InvVar size=%d parserCtx=0x%lx\n", size, (uint64_t)ctx);          .isConst = decl.isConst,
671      if (polyphonic) {          .isFinal = decl.isFinal,
672          //printf("polyIntVar memPOS=%d\n", memPos);          .elements = decl.elements,
673          assert(ctx);          .memPos = (
674      }              (!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  int 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 382  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(int 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 399  void ConstIntVariable::assign(Expression Line 802  void ConstIntVariable::assign(Expression
802  */  */
803  }  }
804    
805  int ConstIntVariable::evalInt() {  vmint ConstIntVariable::evalInt() {
806      return value;      return value;
807  }  }
808    
809  void ConstIntVariable::dump(int level) {  void ConstIntVariable::dump(int level) {
810      printIndents(level);      printIndents(level);
811      printf("ConstIntVariable val=%d\n", value);      printf("ConstIntVariable val=%lld\n", value);
812    }
813    
814    ConstRealVariable::ConstRealVariable(const RealVarDef& def) :
815        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, VMIntRelPtr* 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 419  void BuiltInIntVariable::assign(Expressi Line 862  void BuiltInIntVariable::assign(Expressi
862      ptr->assign(valueExpr->evalInt());      ptr->assign(valueExpr->evalInt());
863  }  }
864    
865  int BuiltInIntVariable::evalInt() {  vmint BuiltInIntVariable::evalInt() {
866      return ptr->evalInt();      return ptr->evalInt();
867  }  }
868    
# Line 428  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 438  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, int 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  {  {
     values.resize(size);  
     memset(&values[0], 0, size * sizeof(int));  
907  }  }
908    
909  IntArrayVariable::IntArrayVariable(ParserContext* ctx, int size, ArgsRef values)  void PolyphonicRealVariable::dump(int level) {
910      : Variable(ctx, 0, false)      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);
927        memset(&values[0], 0, size * sizeof(vmint));
928    
929        unitFactors.resize(size);
930        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      for (int i = 0; i < values->argsCount(); ++i) {      this->unitFactors.resize(size);
949        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    
972  int IntArrayVariable::evalIntElement(uint i) {  vmint IntArrayVariable::evalIntElement(vmuint i) {
973      if (i >= values.size()) return 0;      if (i >= values.size()) return 0;
974      return values[i];      return values[i];
975  }  }
976    
977  void IntArrayVariable::assignIntElement(uint i, int value) {  void IntArrayVariable::assignIntElement(vmuint i, vmint value) {
978      if (i >= values.size()) return;      if (i >= values.size()) return;
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(");
995      for (int i = 0; i < values.size(); ++i) {      for (vmint i = 0; i < values.size(); ++i) {
996          if (i % 12 == 0) {          if (i % 12 == 0) {
997              printf("\n");              printf("\n");
998              printIndents(level+1);              printIndents(level+1);
999          }          }
1000          printf("%d, ", values[i]);          printf("%lld, ", values[i]);
1001      }      }
1002      printIndents(level);      printIndents(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  int BuiltInIntArrayVariable::evalIntElement(uint i) {  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    
1105    vmint BuiltInIntArrayVariable::evalIntElement(vmuint i) {
1106      return i >= array->size ? 0 : array->data[i];      return i >= array->size ? 0 : array->data[i];
1107  }  }
1108    
1109  void BuiltInIntArrayVariable::assignIntElement(uint i, int value) {  void BuiltInIntArrayVariable::assignIntElement(vmuint i, vmint value) {
1110      if (i >= array->size) return;      if (i >= array->size) return;
1111      array->data[i] = value;      array->data[i] = value;
1112  }  }
# Line 503  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(IntArrayVariableRef 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    
1135  void IntArrayElement::assign(Expression* expr) {  void IntArrayElement::assign(Expression* expr) {
1136      IntExpr* valueExpr = dynamic_cast<IntExpr*>(expr);      IntExpr* valueExpr = dynamic_cast<IntExpr*>(expr);
1137      if (!valueExpr) return;      if (!valueExpr) return;
1138      int value = valueExpr->evalInt();      vmint value = valueExpr->evalInt();
1139        vmfloat unitFactor = valueExpr->unitFactor();
1140    
1141      if (!index) return;      if (!index) return;
1142      int 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  int IntArrayElement::evalInt() {  vmint IntArrayElement::evalInt() {
1150      if (!index) return 0;      if (!index) return 0;
1151      int 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    void RealArrayElement::assign(Expression* expr) {
1187        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)  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 555  String StringVariable::evalStr() { Line 1248  String StringVariable::evalStr() {
1248    
1249  void StringVariable::dump(int level) {  void StringVariable::dump(int level) {
1250      printIndents(level);      printIndents(level);
1251      printf("StringVariable memPos=%d\n", memPos);      printf("StringVariable memPos=%lld\n", memPos);
1252  }  }
1253    
1254  ConstStringVariable::ConstStringVariable(ParserContext* ctx, String _value)  ConstStringVariable::ConstStringVariable(ParserContext* ctx, String _value)
# Line 578  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    bool NumberBinaryOp::isFinal() const {
1275        NumberExprRef l = (NumberExprRef) lhs;
1276        NumberExprRef r = (NumberExprRef) rhs;
1277        return l->isFinal() || r->isFinal();
1278    }
1279    
1280    ExprType_t VaritypeScalarBinaryOp::exprType() const {
1281        return (lhs->exprType() == REAL_EXPR || rhs->exprType() == REAL_EXPR) ? REAL_EXPR : INT_EXPR;
1282    }
1283    
1284    String VaritypeScalarBinaryOp::evalCastToStr() {
1285        return (exprType() == REAL_EXPR) ?
1286            RealExpr::evalCastToStr() : IntExpr::evalCastToStr();
1287    }
1288    
1289  void If::dump(int level) {  void If::dump(int level) {
1290      printIndents(level);      printIndents(level);
1291      if (ifStatements && elseStatements)      if (ifStatements && elseStatements)
# Line 588  void If::dump(int level) { Line 1296  void If::dump(int level) {
1296          printf("if [INVALID]\n");          printf("if [INVALID]\n");
1297  }  }
1298    
1299  int If::evalBranch() {  vmint If::evalBranch() {
1300      if (condition->evalInt()) return 0;      if (condition->evalInt()) return 0;
1301      if (elseStatements) return 1;      if (elseStatements) return 1;
1302      return -1;      return -1;
1303  }  }
1304    
1305  Statements* If::branch(uint i) const {  Statements* If::branch(vmuint i) const {
1306      if (i == 0) return (Statements*) &*ifStatements;      if (i == 0) return (Statements*) &*ifStatements;
1307      if (i == 1) return (elseStatements) ? (Statements*) &*elseStatements : NULL;      if (i == 1) return (elseStatements) ? (Statements*) &*elseStatements : NULL;
1308      return NULL;      return NULL;
# Line 610  void SelectCase::dump(int level) { Line 1318  void SelectCase::dump(int level) {
1318      printIndents(level);      printIndents(level);
1319      if (select)      if (select)
1320          if (select->isConstExpr())          if (select->isConstExpr())
1321              printf("Case select %d\n", select->evalInt());              printf("Case select %lld\n", select->evalInt());
1322          else          else
1323              printf("Case select [runtime expr]\n");              printf("Case select [runtime expr]\n");
1324      else      else
1325          printf("Case select NULL\n");          printf("Case select NULL\n");
1326      for (int i = 0; i < branches.size(); ++i) {      for (vmint i = 0; i < branches.size(); ++i) {
1327          printIndents(level+1);          printIndents(level+1);
1328          CaseBranch& branch = branches[i];          CaseBranch& branch = branches[i];
1329          if (branch.from && branch.to)          if (branch.from && branch.to)
1330              if (branch.from->isConstExpr() && branch.to->isConstExpr())              if (branch.from->isConstExpr() && branch.to->isConstExpr())
1331                  printf("case %d to %d\n", branch.from->evalInt(), branch.to->evalInt());                  printf("case %lld to %lld\n", branch.from->evalInt(), branch.to->evalInt());
1332              else if (branch.from->isConstExpr() && !branch.to->isConstExpr())              else if (branch.from->isConstExpr() && !branch.to->isConstExpr())
1333                  printf("case %d to [runtime expr]\n", branch.from->evalInt());                  printf("case %lld to [runtime expr]\n", branch.from->evalInt());
1334              else if (!branch.from->isConstExpr() && branch.to->isConstExpr())              else if (!branch.from->isConstExpr() && branch.to->isConstExpr())
1335                  printf("case [runtime expr] to %d\n", branch.to->evalInt());                  printf("case [runtime expr] to %lld\n", branch.to->evalInt());
1336              else              else
1337                  printf("case [runtime expr] to [runtime expr]\n");                  printf("case [runtime expr] to [runtime expr]\n");
1338          else if (branch.from)          else if (branch.from)
1339              if (branch.from->isConstExpr())              if (branch.from->isConstExpr())
1340                  printf("case %d\n", branch.from->evalInt());                  printf("case %lld\n", branch.from->evalInt());
1341              else              else
1342                  printf("case [runtime expr]\n");                  printf("case [runtime expr]\n");
1343          else          else
# Line 637  void SelectCase::dump(int level) { Line 1345  void SelectCase::dump(int level) {
1345      }      }
1346  }  }
1347    
1348  int SelectCase::evalBranch() {  vmint SelectCase::evalBranch() {
1349      int value = select->evalInt();      vmint value = select->evalInt();
1350      for (int i = 0; i < branches.size(); ++i) {      for (vmint i = 0; i < branches.size(); ++i) {
1351          if (branches.at(i).from && branches.at(i).to) { // i.e. "case 4 to 7" ...          if (branches.at(i).from && branches.at(i).to) { // i.e. "case 4 to 7" ...
1352              if (branches.at(i).from->evalInt() <= value &&              if (branches.at(i).from->evalInt() <= value &&
1353                  branches.at(i).to->evalInt() >= value) return i;                  branches.at(i).to->evalInt() >= value) return i;
# Line 650  int SelectCase::evalBranch() { Line 1358  int SelectCase::evalBranch() {
1358      return -1;      return -1;
1359  }  }
1360    
1361  Statements* SelectCase::branch(uint i) const {  Statements* SelectCase::branch(vmuint i) const {
1362      if (i < branches.size())      if (i < branches.size())
1363          return const_cast<Statements*>( &*branches[i].statements );          return const_cast<Statements*>( &*branches[i].statements );
1364      return NULL;      return NULL;
# Line 658  Statements* SelectCase::branch(uint i) c Line 1366  Statements* SelectCase::branch(uint i) c
1366    
1367  bool SelectCase::isPolyphonic() const {  bool SelectCase::isPolyphonic() const {
1368      if (select->isPolyphonic()) return true;      if (select->isPolyphonic()) return true;
1369      for (int i = 0; i < branches.size(); ++i)      for (vmint i = 0; i < branches.size(); ++i)
1370          if (branches[i].statements->isPolyphonic())          if (branches[i].statements->isPolyphonic())
1371              return true;              return true;
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)
1378          if (m_condition->isConstExpr())          if (m_condition->isConstExpr())
1379              printf("while (%d) {\n", m_condition->evalInt());              printf("while (%lld) {\n", m_condition->evalInt());
1380          else          else
1381              printf("while ([runtime expr]) {\n");              printf("while ([runtime expr]) {\n");
1382      else      else
# Line 706  bool While::evalLoopStartCondition() { Line 1395  bool While::evalLoopStartCondition() {
1395      return m_condition->evalInt();      return m_condition->evalInt();
1396  }  }
1397    
1398    void SyncBlock::dump(int level) {
1399        printIndents(level);
1400        printf("sync {\n");
1401        m_statements->dump(level+1);
1402        printIndents(level);
1403        printf("}\n");
1404    }
1405    
1406    Statements* SyncBlock::statements() const {
1407        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 739  bool ConcatString::isConstExpr() const { Line 1444  bool ConcatString::isConstExpr() const {
1444      return lhs->isConstExpr() && rhs->isConstExpr();      return lhs->isConstExpr() && rhs->isConstExpr();
1445  }  }
1446    
1447  int 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 797  bool Relation::isConstExpr() const { Line 1608  bool Relation::isConstExpr() const {
1608      return lhs->isConstExpr() && rhs->isConstExpr();      return lhs->isConstExpr() && rhs->isConstExpr();
1609  }  }
1610    
1611  int 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 815  void Or::dump(int level) { Line 1626  void Or::dump(int level) {
1626      printf(")\n");      printf(")\n");
1627  }  }
1628    
1629  int BitwiseOr::evalInt() {  vmint BitwiseOr::evalInt() {
1630      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1631      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
1632      return pLHS->evalInt() | pRHS->evalInt();      return pLHS->evalInt() | pRHS->evalInt();
# Line 832  void BitwiseOr::dump(int level) { Line 1643  void BitwiseOr::dump(int level) {
1643      printf(")\n");      printf(")\n");
1644  }  }
1645    
1646  int And::evalInt() {  vmint And::evalInt() {
1647      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1648      if (!pLHS->evalInt()) return 0;      if (!pLHS->evalInt()) return 0;
1649      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
# Line 850  void And::dump(int level) { Line 1661  void And::dump(int level) {
1661      printf(")\n");      printf(")\n");
1662  }  }
1663    
1664  int BitwiseAnd::evalInt() {  vmint BitwiseAnd::evalInt() {
1665      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1666      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
1667      return pLHS->evalInt() & pRHS->evalInt();      return pLHS->evalInt() & pRHS->evalInt();
# Line 883  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) {
1705        printIndents(level);
1706        printf("Final(\n");
1707        expr->dump(level+1);
1708        printIndents(level);
1709        printf(")\n");
1710    }
1711    
1712  StatementsRef ParserContext::userFunctionByName(const String& name) {  StatementsRef ParserContext::userFunctionByName(const String& name) {
1713      if (!userFnTable.count(name)) {      if (!userFnTable.count(name)) {
1714          return StatementsRef();          return StatementsRef();
# Line 911  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 921  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 947  void ParserContext::addWrn(int firstLine Line 1781  void ParserContext::addWrn(int firstLine
1781      vIssues.push_back(w);      vIssues.push_back(w);
1782  }  }
1783    
1784    void ParserContext::addPreprocessorComment(int firstLine, int lastLine, int firstColumn, int lastColumn) {
1785        CodeBlock block;
1786        block.firstLine = firstLine;
1787        block.lastLine = lastLine;
1788        block.firstColumn = firstColumn;
1789        block.lastColumn = lastColumn;
1790        vPreprocessorComments.push_back(block);
1791    }
1792    
1793  bool ParserContext::setPreprocessorCondition(const char* name) {  bool ParserContext::setPreprocessorCondition(const char* name) {
1794      if (builtinPreprocessorConditions.count(name)) return false;      if (builtinPreprocessorConditions.count(name)) return false;
1795      if (userPreprocessorConditions.count(name)) return false;      if (userPreprocessorConditions.count(name)) return false;
# Line 978  std::vector<ParserIssue> ParserContext:: Line 1821  std::vector<ParserIssue> ParserContext::
1821      return vWarnings;      return vWarnings;
1822  }  }
1823    
1824    std::vector<CodeBlock> ParserContext::preprocessorComments() const {
1825        return vPreprocessorComments;
1826    }
1827    
1828  VMEventHandler* ParserContext::eventHandler(uint index) {  VMEventHandler* ParserContext::eventHandler(uint index) {
1829      if (!handlers) return NULL;      if (!handlers) return NULL;
1830      return handlers->eventHandler(index);      return handlers->eventHandler(index);
# Line 988  VMEventHandler* ParserContext::eventHand Line 1835  VMEventHandler* ParserContext::eventHand
1835      return handlers->eventHandlerByName(name);      return handlers->eventHandlerByName(name);
1836  }  }
1837    
1838  void ParserContext::registerBuiltInConstIntVariables(const std::map<String,int>& vars) {  void ParserContext::registerBuiltInConstIntVariables(const std::map<String,vmint>& vars) {
1839      for (std::map<String,int>::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  }  }
1848    
1849  void ParserContext::registerBuiltInIntVariables(const std::map<String,VMIntRelPtr*>& vars) {  void ParserContext::registerBuiltInIntVariables(const std::map<String,VMIntPtr*>& vars) {
1850      for (std::map<String,VMIntRelPtr*>::const_iterator it = vars.begin();      for (std::map<String,VMIntPtr*>::const_iterator it = vars.begin();
1851           it != vars.end(); ++it)           it != vars.end(); ++it)
1852      {      {
1853          BuiltInIntVariableRef ref = new BuiltInIntVariable(it->first, it->second);          BuiltInIntVariableRef ref = new BuiltInIntVariable(it->first, it->second);
# Line 1024  void ParserContext::registerBuiltInDynVa Line 1873  void ParserContext::registerBuiltInDynVa
1873      }      }
1874  }  }
1875    
1876    ExecContext::ExecContext() :
1877        status(VM_EXEC_NOT_RUNNING), flags(STMT_SUCCESS), stackFrame(-1),
1878        suspendMicroseconds(0), instructionsCount(0)
1879    {
1880        exitRes.value = NULL;
1881    }
1882    
1883    void ExecContext::forkTo(VMExecContext* ectx) const {
1884        ExecContext* child = dynamic_cast<ExecContext*>(ectx);
1885    
1886        child->polyphonicIntMemory.copyFlatFrom(polyphonicIntMemory);
1887        child->polyphonicRealMemory.copyFlatFrom(polyphonicRealMemory);
1888        child->status = VM_EXEC_SUSPENDED;
1889        child->flags = STMT_SUCCESS;
1890        child->stack.copyFlatFrom(stack);
1891        child->stackFrame = stackFrame;
1892        child->suspendMicroseconds = 0;
1893        child->instructionsCount = 0;
1894    }
1895    
1896  } // namespace LinuxSampler  } // namespace LinuxSampler

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

  ViewVC Help
Powered by ViewVC