/[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 2935 by schoenebeck, Sun Jul 10 14:24:13 2016 UTC revision 3590 by schoenebeck, Mon Sep 2 09:03:31 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;
21      return noOp;  }
22    
23    String acceptedArgTypesStr(VMFunction* fn, vmint iArg) {
24        static const ExprType_t allTypes[] = {
25            INT_EXPR,
26            INT_ARR_EXPR,
27            REAL_EXPR,
28            REAL_ARR_EXPR,
29            STRING_EXPR,
30            STRING_ARR_EXPR,
31        };
32        const size_t nTypes = sizeof(allTypes) / sizeof(ExprType_t);
33    
34        std::vector<ExprType_t> supportedTypes;
35        for (int iType = 0; iType < nTypes; ++iType) {
36            const ExprType_t& type = allTypes[iType];
37            if (fn->acceptsArgType(iArg, type))
38                supportedTypes.push_back(type);
39        }
40        assert(!supportedTypes.empty());
41    
42        if (supportedTypes.size() == 1) {
43            return typeStr(*supportedTypes.begin());
44        } else {
45            String s = "either ";
46            for (size_t i = 0; i < supportedTypes.size(); ++i) {
47                const ExprType_t& type = supportedTypes[i];
48                if (i == 0) {
49                    s += typeStr(type);
50                } else if (i == supportedTypes.size() - 1) {
51                    s += " or " + typeStr(type);
52                } else {
53                    s += ", " + typeStr(type);
54                }
55            }
56            return s;
57        }
58  }  }
59            
60  Node::Node() {  Node::Node() {
# Line 31  void Node::printIndents(int n) { Line 68  void Node::printIndents(int n) {
68      fflush(stdout);      fflush(stdout);
69  }  }
70    
71    vmint Unit::convIntToUnitFactor(vmint iValue, VMUnit* srcUnit, VMUnit* dstUnit) {
72        vmfloat f = (vmfloat) iValue;
73        vmfloat factor = srcUnit->unitFactor() / dstUnit->unitFactor();
74        if (sizeof(vmfloat) == sizeof(float))
75            return llroundf(f * factor);
76        else
77            return llround(f * factor);
78    }
79    
80    vmint Unit::convIntToUnitFactor(vmint iValue, vmfloat srcFactor, vmfloat dstFactor) {
81        vmfloat f = (vmfloat) iValue;
82        vmfloat factor = srcFactor / dstFactor;
83        if (sizeof(vmfloat) == sizeof(float))
84            return llroundf(f * factor);
85        else
86            return llround(f * factor);
87    }
88    
89    vmfloat Unit::convRealToUnitFactor(vmfloat fValue, VMUnit* srcUnit, VMUnit* dstUnit) {
90        vmfloat factor = srcUnit->unitFactor() / dstUnit->unitFactor();
91        return fValue * factor;
92    }
93    
94    vmfloat Unit::convRealToUnitFactor(vmfloat fValue, vmfloat srcFactor, vmfloat dstFactor) {
95        vmfloat factor = srcFactor / dstFactor;
96        return fValue * factor;
97    }
98    
99    vmint IntExpr::evalIntToUnitFactor(vmfloat unitFactor) {
100        vmfloat f = (vmfloat) evalInt();
101        vmfloat factor = this->unitFactor() / unitFactor;
102        if (sizeof(vmfloat) == sizeof(float))
103            return llroundf(f * factor);
104        else
105            return llround(f * factor);
106    }
107    
108    static String _unitFactorToShortStr(vmfloat unitFactor) {
109        const long int tens = lround( log10(unitFactor) );
110        switch (tens) {
111            case  3: return "k";  // kilo  = 10^3
112            case  2: return "h";  // hecto = 10^2
113            case  1: return "da"; // deca  = 10
114            case  0: return "" ;  //  --   = 1
115            case -1: return "d";  // deci  = 10^-1
116            case -2: return "c";  // centi = 10^-2 (this is also used for tuning "cents")
117            case -3: return "m";  // milli = 10^-3
118            case -4: return "md"; // milli deci = 10^-4
119            case -5: return "mc"; // milli centi = 10^-5 (this is also used for tuning "cents")
120            case -6: return "u";  // micro = 10^-6
121            default: return "*10^" + ToString(tens);
122        }
123    }
124    
125    static String _unitToStr(Unit* unit) {
126        const StdUnit_t type = unit->unitType();
127        String sType;
128        switch (type) {
129            case VM_NO_UNIT: break;
130            case VM_SECOND: sType = "s"; break;
131            case VM_HERTZ: sType = "Hz"; break;
132            case VM_BEL: sType = "B"; break;
133        }
134    
135        String prefix = _unitFactorToShortStr( unit->unitFactor() );
136    
137        return prefix + sType;
138    }
139    
140  String IntExpr::evalCastToStr() {  String IntExpr::evalCastToStr() {
141      return ToString(evalInt());      return ToString(evalInt()) + _unitToStr(this);
142    }
143    
144    vmfloat RealExpr::evalRealToUnitFactor(vmfloat unitFactor) {
145        vmfloat f = evalReal();
146        vmfloat factor = this->unitFactor() / unitFactor;
147        return f * factor;
148  }  }
149    
150  int IntLiteral::evalInt() {  String RealExpr::evalCastToStr() {
151        return ToString(evalReal()) + _unitToStr(this);
152    }
153    
154    String IntArrayExpr::evalCastToStr() {
155        String s = "{";
156        for (vmint i = 0; i < arraySize(); ++i) {
157            vmint val = evalIntElement(i);
158            vmfloat factor = unitFactorOfElement(i);
159            if (i) s += ",";
160            s += ToString(val) + _unitFactorToShortStr(factor);
161        }
162        s += "}";
163        return s;
164    }
165    
166    String RealArrayExpr::evalCastToStr() {
167        String s = "{";
168        for (vmint i = 0; i < arraySize(); ++i) {
169            vmfloat val = evalRealElement(i);
170            vmfloat factor = unitFactorOfElement(i);
171            if (i) s += ",";
172            s += ToString(val) + _unitFactorToShortStr(factor);
173        }
174        s += "}";
175        return s;
176    }
177    
178    IntLiteral::IntLiteral(const IntLitDef& def) :
179        IntExpr(), Unit(def.unitType),
180        value(def.value), unitPrefixFactor(def.unitFactor),
181        finalVal(def.isFinal)
182    {
183    }
184    
185    vmint IntLiteral::evalInt() {
186      return value;      return value;
187  }  }
188    
189  void IntLiteral::dump(int level) {  void IntLiteral::dump(int level) {
190      printIndents(level);      printIndents(level);
191      printf("IntLiteral %d\n", value);      printf("IntLiteral %lld\n", value);
192    }
193    
194    RealLiteral::RealLiteral(const RealLitDef& def) :
195        RealExpr(), Unit(def.unitType),
196        value(def.value), unitPrefixFactor(def.unitFactor),
197        finalVal(def.isFinal)
198    {
199    }
200    
201    vmfloat RealLiteral::evalReal() {
202        return value;
203    }
204    
205    void RealLiteral::dump(int level) {
206        printIndents(level);
207        printf("RealLiteral %f\n", value);
208  }  }
209    
210  void StringLiteral::dump(int level) {  void StringLiteral::dump(int level) {
# Line 49  void StringLiteral::dump(int level) { Line 212  void StringLiteral::dump(int level) {
212      printf("StringLiteral: '%s'\n", value.c_str());      printf("StringLiteral: '%s'\n", value.c_str());
213  }  }
214    
215  int Add::evalInt() {  Add::Add(NumberExprRef lhs, NumberExprRef rhs) :
216        VaritypeScalarBinaryOp(lhs, rhs),
217        Unit(
218            // lhs and rhs are forced to be same unit type at parse time, so either one is fine here
219            (lhs) ? lhs->unitType() : VM_NO_UNIT
220        )
221    {
222    }
223    
224    vmint Add::evalInt() {
225      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
226      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
227      return (pLHS && pRHS) ? pLHS->evalInt() + pRHS->evalInt() : 0;      if (!pLHS || !pRHS) return 0;
228        // eval*() call is required before calling unitFactor(), since the latter does not evaluate expressions!
229        vmint lvalue = pLHS->evalInt();
230        vmint rvalue = pRHS->evalInt();
231        if (pLHS->unitFactor() == pRHS->unitFactor())
232            return lvalue + rvalue;
233        if (pLHS->unitFactor() < pRHS->unitFactor())
234            return lvalue + Unit::convIntToUnitFactor(rvalue, pRHS, pLHS);
235        else
236            return Unit::convIntToUnitFactor(lvalue, pLHS, pRHS) + rvalue;
237    }
238    
239    vmfloat Add::evalReal() {
240        RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
241        RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);
242        if (!pLHS || !pRHS) return 0;
243        // eval*() call is required before calling unitFactor(), since the latter does not evaluate expressions!
244        vmfloat lvalue = pLHS->evalReal();
245        vmfloat rvalue = pRHS->evalReal();
246        if (pLHS->unitFactor() == pRHS->unitFactor())
247            return lvalue + rvalue;
248        if (pLHS->unitFactor() < pRHS->unitFactor())
249            return lvalue + Unit::convRealToUnitFactor(rvalue, pRHS, pLHS);
250        else
251            return Unit::convRealToUnitFactor(lvalue, pLHS, pRHS) + rvalue;
252    }
253    
254    vmfloat Add::unitFactor() const {
255        const NumberExpr* pLHS = dynamic_cast<const NumberExpr*>(&*lhs);
256        const NumberExpr* pRHS = dynamic_cast<const NumberExpr*>(&*rhs);
257        return (pLHS->unitFactor() < pRHS->unitFactor()) ? pLHS->unitFactor() : pRHS->unitFactor();
258  }  }
259    
260  void Add::dump(int level) {  void Add::dump(int level) {
# Line 66  void Add::dump(int level) { Line 268  void Add::dump(int level) {
268      printf(")\n");      printf(")\n");
269  }  }
270    
271  int Sub::evalInt() {  Sub::Sub(NumberExprRef lhs, NumberExprRef rhs) :
272        VaritypeScalarBinaryOp(lhs, rhs),
273        Unit(
274            // lhs and rhs are forced to be same unit type at parse time, so either one is fine here
275            (lhs) ? lhs->unitType() : VM_NO_UNIT
276        )
277    {
278    }
279    
280    vmint Sub::evalInt() {
281      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
282      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
283      return (pLHS && pRHS) ? pLHS->evalInt() - pRHS->evalInt() : 0;      if (!pLHS || !pRHS) return 0;
284        // eval*() call is required before calling unitFactor(), since the latter does not evaluate expressions!
285        vmint lvalue = pLHS->evalInt();
286        vmint rvalue = pRHS->evalInt();
287        if (pLHS->unitFactor() == pRHS->unitFactor())
288            return lvalue - rvalue;
289        if (pLHS->unitFactor() < pRHS->unitFactor())
290            return lvalue - Unit::convIntToUnitFactor(rvalue, pRHS, pLHS);
291        else
292            return Unit::convIntToUnitFactor(lvalue, pLHS, pRHS) - rvalue;
293    }
294    
295    vmfloat Sub::evalReal() {
296        RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
297        RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);
298        if (!pLHS || !pRHS) return 0;
299        // eval*() call is required before calling unitFactor(), since the latter does not evaluate expressions!
300        vmfloat lvalue = pLHS->evalReal();
301        vmfloat rvalue = pRHS->evalReal();
302        if (pLHS->unitFactor() == pRHS->unitFactor())
303            return lvalue - rvalue;
304        if (pLHS->unitFactor() < pRHS->unitFactor())
305            return lvalue - Unit::convRealToUnitFactor(rvalue, pRHS, pLHS);
306        else
307            return Unit::convRealToUnitFactor(lvalue, pLHS, pRHS) - rvalue;
308    }
309    
310    vmfloat Sub::unitFactor() const {
311        const NumberExpr* pLHS = dynamic_cast<const NumberExpr*>(&*lhs);
312        const NumberExpr* pRHS = dynamic_cast<const NumberExpr*>(&*rhs);
313        return (pLHS->unitFactor() < pRHS->unitFactor()) ? pLHS->unitFactor() : pRHS->unitFactor();
314  }  }
315    
316  void Sub::dump(int level) {  void Sub::dump(int level) {
# Line 83  void Sub::dump(int level) { Line 324  void Sub::dump(int level) {
324      printf(")\n");      printf(")\n");
325  }  }
326    
327  int Mul::evalInt() {  Mul::Mul(NumberExprRef lhs, NumberExprRef rhs) :
328        VaritypeScalarBinaryOp(lhs, rhs),
329        Unit(
330            // currently the NKSP parser only allows a unit type on either side on multiplications
331            (lhs->unitType()) ? lhs->unitType() : rhs->unitType()
332        )
333    {
334    }
335    
336    vmint Mul::evalInt() {
337      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
338      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;
339      return (pLHS && pRHS) ? pLHS->evalInt() * pRHS->evalInt() : 0;      return (pLHS && pRHS) ? pLHS->evalInt() * pRHS->evalInt() : 0;
340  }  }
341    
342    vmfloat Mul::evalReal() {
343        RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
344        RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);;
345        return (pLHS && pRHS) ? pLHS->evalReal() * pRHS->evalReal() : 0;
346    }
347    
348  void Mul::dump(int level) {  void Mul::dump(int level) {
349      printIndents(level);      printIndents(level);
350      printf("Mul(\n");      printf("Mul(\n");
# Line 100  void Mul::dump(int level) { Line 356  void Mul::dump(int level) {
356      printf(")\n");      printf(")\n");
357  }  }
358    
359  int Div::evalInt() {  vmfloat Mul::unitFactor() const {
360        const NumberExpr* pLHS = dynamic_cast<const NumberExpr*>(&*lhs);
361        const NumberExpr* pRHS = dynamic_cast<const NumberExpr*>(&*rhs);
362        return pLHS->unitFactor() * pRHS->unitFactor();
363    }
364    
365    Div::Div(NumberExprRef lhs, NumberExprRef rhs) :
366        VaritypeScalarBinaryOp(lhs, rhs),
367        Unit(
368            // the NKSP parser only allows either A) a unit type on left side and none
369            // on right side or B) an identical unit type on both sides
370            (lhs->unitType() && rhs->unitType()) ? VM_NO_UNIT : lhs->unitType()
371        )
372    {
373    }
374    
375    vmint Div::evalInt() {
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) ? pRHS->evalInt() == 0 ? 0 : pLHS->evalInt() / pRHS->evalInt() : 0;      if (!pLHS || !pRHS) return 0;
379        vmint l = pLHS->evalInt();
380        vmint r = pRHS->evalInt();
381        if (r == 0) return 0;
382        return l / r;
383    }
384    
385    vmfloat Div::evalReal() {
386        RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
387        RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);
388        if (!pLHS || !pRHS) return 0;
389        vmfloat l = pLHS->evalReal();
390        vmfloat r = pRHS->evalReal();
391        if (r == vmfloat(0)) return 0;
392        return l / r;
393  }  }
394    
395  void Div::dump(int level) {  void Div::dump(int level) {
# Line 117  void Div::dump(int level) { Line 403  void Div::dump(int level) {
403      printf(")\n");      printf(")\n");
404  }  }
405    
406  int Mod::evalInt() {  vmfloat Div::unitFactor() const {
407        const NumberExpr* pLHS = dynamic_cast<const NumberExpr*>(&*lhs);
408        const NumberExpr* pRHS = dynamic_cast<const NumberExpr*>(&*rhs);
409        return pLHS->unitFactor() / pRHS->unitFactor();
410    }
411    
412    vmint Mod::evalInt() {
413      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
414      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
415      return (pLHS && pRHS) ? pLHS->evalInt() % pRHS->evalInt() : 0;      return (pLHS && pRHS) ? pLHS->evalInt() % pRHS->evalInt() : 0;
416  }  }
417    
# Line 145  void Args::dump(int level) { Line 437  void Args::dump(int level) {
437  }  }
438    
439  bool Args::isPolyphonic() const {  bool Args::isPolyphonic() const {
440      for (int i = 0; i < args.size(); ++i)      for (vmint i = 0; i < args.size(); ++i)
441          if (args[i]->isPolyphonic())          if (args[i]->isPolyphonic())
442              return true;              return true;
443      return false;      return false;
# Line 173  void EventHandlers::dump(int level) { Line 465  void EventHandlers::dump(int level) {
465  }  }
466    
467  EventHandler* EventHandlers::eventHandlerByName(const String& name) const {  EventHandler* EventHandlers::eventHandlerByName(const String& name) const {
468      for (int i = 0; i < args.size(); ++i)      for (vmint i = 0; i < args.size(); ++i)
469          if (args.at(i)->eventHandlerName() == name)          if (args.at(i)->eventHandlerName() == name)
470              return const_cast<EventHandler*>(&*args.at(i));              return const_cast<EventHandler*>(&*args.at(i));
471      return NULL;      return NULL;
# Line 185  EventHandler* EventHandlers::eventHandle Line 477  EventHandler* EventHandlers::eventHandle
477  }  }
478    
479  bool EventHandlers::isPolyphonic() const {  bool EventHandlers::isPolyphonic() const {
480      for (int i = 0; i < args.size(); ++i)      for (vmint i = 0; i < args.size(); ++i)
481          if (args[i]->isPolyphonic())          if (args[i]->isPolyphonic())
482              return true;              return true;
483      return false;      return false;
# Line 237  Statement* Statements::statement(uint i) Line 529  Statement* Statements::statement(uint i)
529  }  }
530    
531  bool Statements::isPolyphonic() const {  bool Statements::isPolyphonic() const {
532      for (int i = 0; i < args.size(); ++i)      for (vmint i = 0; i < args.size(); ++i)
533          if (args[i]->isPolyphonic())          if (args[i]->isPolyphonic())
534              return true;              return true;
535      return false;      return false;
536  }  }
537    
538    DynamicVariableCall::DynamicVariableCall(const String& name, ParserContext* ctx, VMDynVar* v) :
539        Variable({
540            .ctx = ctx,
541            .elements = 0
542        }),
543        Unit(VM_NO_UNIT),
544        dynVar(v), varName(name)
545    {
546    }
547    
548    vmint DynamicVariableCall::evalInt() {
549        VMIntExpr* expr = dynamic_cast<VMIntExpr*>(dynVar);
550        if (!expr) return 0;
551        return expr->evalInt();
552    }
553    
554    String DynamicVariableCall::evalStr() {
555        VMStringExpr* expr = dynamic_cast<VMStringExpr*>(dynVar);
556        if (!expr) return "";
557        return expr->evalStr();
558    }
559    
560    String DynamicVariableCall::evalCastToStr() {
561        if (dynVar->exprType() == STRING_EXPR) {
562            return evalStr();
563        } else {
564            VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(dynVar);
565            return intExpr ? ToString(intExpr->evalInt()) : "";
566        }
567    }
568    
569    void DynamicVariableCall::dump(int level) {
570        printIndents(level);
571        printf("Dynamic Variable '%s'\n", varName.c_str());
572    }
573    
574    FunctionCall::FunctionCall(const char* function, ArgsRef args, VMFunction* fn) :
575        Unit(
576            (fn) ? fn->returnUnitType(dynamic_cast<VMFnArgs*>(&*args)) : VM_NO_UNIT
577        ),
578        functionName(function), args(args), fn(fn), result(NULL)
579    {
580    }
581    
582  void FunctionCall::dump(int level) {  void FunctionCall::dump(int level) {
583      printIndents(level);      printIndents(level);
584      printf("FunctionCall '%s' args={\n", functionName.c_str());      printf("FunctionCall '%s' args={\n", functionName.c_str());
# Line 253  void FunctionCall::dump(int level) { Line 589  void FunctionCall::dump(int level) {
589    
590  ExprType_t FunctionCall::exprType() const {  ExprType_t FunctionCall::exprType() const {
591      if (!fn) return EMPTY_EXPR;      if (!fn) return EMPTY_EXPR;
592      return fn->returnType();      FunctionCall* self = const_cast<FunctionCall*>(this);
593        return fn->returnType(dynamic_cast<VMFnArgs*>(&*self->args));
594    }
595    
596    vmfloat FunctionCall::unitFactor() const {
597        if (!fn || !result) return VM_NO_FACTOR;
598        VMExpr* expr = result->resultValue();
599        if (!expr) return VM_NO_FACTOR;
600        VMNumberExpr* scalar = expr->asNumber();
601        if (!scalar) return VM_NO_FACTOR;
602        return scalar->unitFactor();
603    }
604    
605    bool FunctionCall::isFinal() const {
606        if (!fn) return false;
607        FunctionCall* self = const_cast<FunctionCall*>(this);
608        return fn->returnsFinal(dynamic_cast<VMFnArgs*>(&*self->args));
609  }  }
610    
611  VMFnResult* FunctionCall::execVMFn() {  VMFnResult* FunctionCall::execVMFn() {
# Line 264  VMFnResult* FunctionCall::execVMFn() { Line 616  VMFnResult* FunctionCall::execVMFn() {
616  }  }
617    
618  StmtFlags_t FunctionCall::exec() {  StmtFlags_t FunctionCall::exec() {
619      VMFnResult* result = execVMFn();      result = execVMFn();
620      if (!result)      if (!result)
621          return StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);          return StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
622      return result->resultFlags();      return result->resultFlags();
623  }  }
624    
625  int FunctionCall::evalInt() {  vmint FunctionCall::evalInt() {
626      VMFnResult* result = execVMFn();      result = execVMFn();
627      if (!result) return 0;      if (!result) return 0;
628      VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());      VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());
629      if (!intExpr) return 0;      if (!intExpr) return 0;
630      return intExpr->evalInt();      return intExpr->evalInt();
631  }  }
632    
633    vmfloat FunctionCall::evalReal() {
634        result = execVMFn();
635        if (!result) return 0;
636        VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());
637        if (!realExpr) return 0;
638        return realExpr->evalReal();
639    }
640    
641    VMIntArrayExpr* FunctionCall::asIntArray() const {
642        if (!result) return 0;
643        VMIntArrayExpr* intArrExpr = dynamic_cast<VMIntArrayExpr*>(result->resultValue());
644        return intArrExpr;
645    }
646    
647    VMRealArrayExpr* FunctionCall::asRealArray() const {
648        if (!result) return 0;
649        VMRealArrayExpr* realArrExpr = dynamic_cast<VMRealArrayExpr*>(result->resultValue());
650        return realArrExpr;
651    }
652    
653  String FunctionCall::evalStr() {  String FunctionCall::evalStr() {
654      VMFnResult* result = execVMFn();      result = execVMFn();
655      if (!result) return "";      if (!result) return "";
656      VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());      VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());
657      if (!strExpr) return "";      if (!strExpr) return "";
# Line 287  String FunctionCall::evalStr() { Line 659  String FunctionCall::evalStr() {
659  }  }
660    
661  String FunctionCall::evalCastToStr() {  String FunctionCall::evalCastToStr() {
662      VMFnResult* result = execVMFn();      result = execVMFn();
663      if (!result) return "";      if (!result) return "";
664      if (result->resultValue()->exprType() == STRING_EXPR) {      const ExprType_t resultType = result->resultValue()->exprType();
665        if (resultType == STRING_EXPR) {
666          VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());          VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());
667          return strExpr ? strExpr->evalStr() : "";          return strExpr ? strExpr->evalStr() : "";
668        } else if (resultType == REAL_EXPR) {
669            VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());
670            return realExpr ? ToString(realExpr->evalReal()) : "";
671      } else {      } else {
672          VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());          VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());
673          return intExpr ? ToString(intExpr->evalInt()) : "";          return intExpr ? ToString(intExpr->evalInt()) : "";
674      }      }
675  }  }
676    
677  IntVariable::IntVariable(ParserContext* ctx)  Variable::Variable(const VariableDecl& decl) :
678      : Variable(ctx, ctx ? ctx->globalIntVarCount++ : 0, false), polyphonic(false)      context(decl.ctx), memPos(decl.memPos), bConst(decl.isConst)
679    {
680    }
681    
682    NumberVariable::NumberVariable(const VariableDecl& decl) :
683        Variable(decl),
684        Unit(decl.unitType),
685        unitFactorMemPos(decl.unitFactorMemPos), polyphonic(decl.isPolyphonic),
686        finalVal(decl.isFinal)
687  {  {
     //printf("globalIntVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);  
     assert(ctx);  
688  }  }
689    
690  inline static int postfixInc(int& object, int incBy) {  vmfloat NumberVariable::unitFactor() const {
691      const int i = object;      if (isPolyphonic()) {
692            return context->execContext->polyphonicUnitFactorMemory[unitFactorMemPos];
693        }
694        return (*context->globalUnitFactorMemory)[unitFactorMemPos];
695    }
696    
697    inline static vmint postfixInc(vmint& object, vmint incBy) {
698        const vmint i = object;
699      object += incBy;      object += incBy;
700      return i;      return i;
701  }  }
702    
703  IntVariable::IntVariable(ParserContext* ctx, bool polyphonic, bool bConst, int size)  IntVariable::IntVariable(const VariableDecl& decl) :
704      : Variable(ctx, !ctx ? 0 : polyphonic ? postfixInc(ctx->polyphonicIntVarCount, size) : postfixInc(ctx->globalIntVarCount, size), bConst),      NumberVariable({
705        polyphonic(polyphonic)          .ctx = decl.ctx,
706  {          .isPolyphonic = decl.isPolyphonic,
707      //printf("InvVar size=%d parserCtx=0x%lx\n", size, (uint64_t)ctx);          .isConst = decl.isConst,
708      if (polyphonic) {          .isFinal = decl.isFinal,
709          //printf("polyIntVar memPOS=%d\n", memPos);          .elements = decl.elements,
710          assert(ctx);          .memPos = (
711      }              (!decl.ctx) ? 0 :
712                    (decl.isPolyphonic) ?
713                        postfixInc(decl.ctx->polyphonicIntVarCount, decl.elements) :
714                        postfixInc(decl.ctx->globalIntVarCount, decl.elements)
715            ),
716            .unitFactorMemPos = (
717                (!decl.ctx) ? 0 :
718                    (decl.isPolyphonic) ?
719                        postfixInc(decl.ctx->polyphonicUnitFactorCount, decl.elements) :
720                        postfixInc(decl.ctx->globalUnitFactorCount, decl.elements)
721            ),
722            .unitType = decl.unitType
723        }),
724        Unit(decl.unitType)
725    {
726        //printf("IntVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);
727        assert(!decl.isPolyphonic || decl.ctx);
728  }  }
729    
730  void IntVariable::assign(Expression* expr) {  void IntVariable::assign(Expression* expr) {
731      IntExpr* intExpr = dynamic_cast<IntExpr*>(expr);      IntExpr* intExpr = dynamic_cast<IntExpr*>(expr);
732      if (intExpr)      if (intExpr) {
733          if (polyphonic)          //NOTE: sequence matters! evalInt() must be called before getting unitFactor() !
734            if (isPolyphonic()) {
735              context->execContext->polyphonicIntMemory[memPos] = intExpr->evalInt();              context->execContext->polyphonicIntMemory[memPos] = intExpr->evalInt();
736          else              context->execContext->polyphonicUnitFactorMemory[unitFactorMemPos] = intExpr->unitFactor();
737            } else {
738              (*context->globalIntMemory)[memPos] = intExpr->evalInt();              (*context->globalIntMemory)[memPos] = intExpr->evalInt();
739                (*context->globalUnitFactorMemory)[unitFactorMemPos] = intExpr->unitFactor();
740            }
741        }
742  }  }
743    
744  int IntVariable::evalInt() {  vmint IntVariable::evalInt() {
745      //printf("IntVariable::eval pos=%d\n", memPos);      //printf("IntVariable::eval pos=%d\n", memPos);
746      if (polyphonic) {      if (isPolyphonic()) {
747          //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);
748          return context->execContext->polyphonicIntMemory[memPos];          return context->execContext->polyphonicIntMemory[memPos];
749      }      }
# Line 342  int IntVariable::evalInt() { Line 752  int IntVariable::evalInt() {
752    
753  void IntVariable::dump(int level) {  void IntVariable::dump(int level) {
754      printIndents(level);      printIndents(level);
755        printf("IntVariable\n");
756      //printf("IntVariable memPos=%d\n", memPos);      //printf("IntVariable memPos=%d\n", memPos);
757  }  }
758    
759  //ConstIntVariable::ConstIntVariable(ParserContext* ctx, int value)  RealVariable::RealVariable(const VariableDecl& decl) :
760  ConstIntVariable::ConstIntVariable(int value)      NumberVariable({
761      : IntVariable(NULL,false,true), value(value)          .ctx = decl.ctx,
762            .isPolyphonic = decl.isPolyphonic,
763            .isConst = decl.isConst,
764            .isFinal = decl.isFinal,
765            .elements = decl.elements,
766            .memPos = (
767                (!decl.ctx) ? 0 :
768                    (decl.isPolyphonic) ?
769                        postfixInc(decl.ctx->polyphonicRealVarCount, decl.elements) :
770                        postfixInc(decl.ctx->globalRealVarCount, decl.elements)
771            ),
772            .unitFactorMemPos = (
773                (!decl.ctx) ? 0 :
774                    (decl.isPolyphonic) ?
775                        postfixInc(decl.ctx->polyphonicUnitFactorCount, decl.elements) :
776                        postfixInc(decl.ctx->globalUnitFactorCount, decl.elements)
777            ),
778            .unitType = decl.unitType
779        }),
780        Unit(decl.unitType)
781    {
782        //printf("RealVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);
783        assert(!decl.isPolyphonic || decl.ctx);
784    }
785    
786    void RealVariable::assign(Expression* expr) {
787        RealExpr* realExpr = dynamic_cast<RealExpr*>(expr);
788        if (realExpr) {
789            //NOTE: sequence matters! evalReal() must be called before getting unitFactor() !
790            if (isPolyphonic()) {
791                context->execContext->polyphonicRealMemory[memPos] = realExpr->evalReal();
792                context->execContext->polyphonicUnitFactorMemory[unitFactorMemPos] = realExpr->unitFactor();
793            } else {
794                (*context->globalRealMemory)[memPos] = realExpr->evalReal();
795                (*context->globalUnitFactorMemory)[unitFactorMemPos] = realExpr->unitFactor();
796            }
797        }
798    }
799    
800    vmfloat RealVariable::evalReal() {
801        //printf("RealVariable::eval pos=%d\n", memPos);
802        if (isPolyphonic()) {
803            //printf("evalReal() poly memPos=%d execCtx=0x%lx\n", memPos, (uint64_t)context->execContext);
804            return context->execContext->polyphonicRealMemory[memPos];
805        }
806        return (*context->globalRealMemory)[memPos];
807    }
808    
809    void RealVariable::dump(int level) {
810        printIndents(level);
811        printf("RealVariable\n");
812        //printf("RealVariable memPos=%d\n", memPos);
813    }
814    
815    ConstIntVariable::ConstIntVariable(const IntVarDef& def) :
816        IntVariable({
817            .ctx = def.ctx,
818            .isPolyphonic = false,
819            .isConst = true,
820            .isFinal = def.isFinal,
821            .elements = 1,
822            .memPos = def.memPos,
823            .unitFactorMemPos = def.unitFactorMemPos,
824            .unitType = def.unitType
825        }),
826        Unit(def.unitType),
827        value(def.value), unitPrefixFactor(def.unitFactor)
828  {  {
829  }  }
830    
# Line 362  void ConstIntVariable::assign(Expression Line 839  void ConstIntVariable::assign(Expression
839  */  */
840  }  }
841    
842  int ConstIntVariable::evalInt() {  vmint ConstIntVariable::evalInt() {
843      return value;      return value;
844  }  }
845    
846  void ConstIntVariable::dump(int level) {  void ConstIntVariable::dump(int level) {
847      printIndents(level);      printIndents(level);
848      printf("ConstIntVariable val=%d\n", value);      printf("ConstIntVariable val=%lld\n", value);
849    }
850    
851    ConstRealVariable::ConstRealVariable(const RealVarDef& def) :
852        RealVariable({
853            .ctx = def.ctx,
854            .isPolyphonic = false,
855            .isConst = true,
856            .isFinal = def.isFinal,
857            .elements = 1,
858            .memPos = def.memPos,
859            .unitFactorMemPos = def.unitFactorMemPos,
860            .unitType = def.unitType
861        }),
862        Unit(def.unitType),
863        value(def.value), unitPrefixFactor(def.unitFactor)
864    {
865    }
866    
867    void ConstRealVariable::assign(Expression* expr) {
868        // ignore assignment
869    }
870    
871    vmfloat ConstRealVariable::evalReal() {
872        return value;
873    }
874    
875    void ConstRealVariable::dump(int level) {
876        printIndents(level);
877        printf("ConstRealVariable val=%f\n", value);
878  }  }
879    
880  BuiltInIntVariable::BuiltInIntVariable(const String& name, VMIntRelPtr* ptr)  BuiltInIntVariable::BuiltInIntVariable(const String& name, VMIntPtr* ptr) :
881      : IntVariable(NULL,false,false), name(name), ptr(ptr)      IntVariable({
882            .ctx = NULL,
883            .isPolyphonic = false,
884            .isConst = false, // may or may not be modifyable though!
885            .isFinal = false,
886            .elements = 0,
887            .memPos = 0,
888            .unitFactorMemPos = 0,
889            .unitType = VM_NO_UNIT
890        }),
891        Unit(VM_NO_UNIT),
892        name(name), ptr(ptr)
893  {  {
894  }  }
895    
# Line 382  void BuiltInIntVariable::assign(Expressi Line 899  void BuiltInIntVariable::assign(Expressi
899      ptr->assign(valueExpr->evalInt());      ptr->assign(valueExpr->evalInt());
900  }  }
901    
902  int BuiltInIntVariable::evalInt() {  vmint BuiltInIntVariable::evalInt() {
903      return ptr->evalInt();      return ptr->evalInt();
904  }  }
905    
# Line 391  void BuiltInIntVariable::dump(int level) Line 908  void BuiltInIntVariable::dump(int level)
908      printf("Built-in IntVar '%s'\n", name.c_str());      printf("Built-in IntVar '%s'\n", name.c_str());
909  }  }
910    
911  PolyphonicIntVariable::PolyphonicIntVariable(ParserContext* ctx)  PolyphonicIntVariable::PolyphonicIntVariable(const VariableDecl& decl) :
912      : IntVariable(ctx,true,false)      IntVariable({
913            .ctx = decl.ctx,
914            .isPolyphonic = true,
915            .isConst = decl.isConst,
916            .isFinal = decl.isFinal,
917            .elements = 1,
918            .memPos = 0,
919            .unitFactorMemPos = 0,
920            .unitType = decl.unitType
921        }),
922        Unit(decl.unitType)
923  {  {
924  }  }
925    
# Line 401  void PolyphonicIntVariable::dump(int lev Line 928  void PolyphonicIntVariable::dump(int lev
928      printf("PolyphonicIntVariable\n");      printf("PolyphonicIntVariable\n");
929  }  }
930    
931  IntArrayVariable::IntArrayVariable(ParserContext* ctx, int size)  PolyphonicRealVariable::PolyphonicRealVariable(const VariableDecl& decl) :
932      : Variable(ctx, 0, false)      RealVariable({
933            .ctx = decl.ctx,
934            .isPolyphonic = true,
935            .isConst = decl.isConst,
936            .isFinal = decl.isFinal,
937            .elements = 1,
938            .memPos = 0,
939            .unitFactorMemPos = 0,
940            .unitType = decl.unitType
941        }),
942        Unit(decl.unitType)
943  {  {
     values.resize(size);  
     memset(&values[0], 0, size * sizeof(int));  
944  }  }
945    
946  IntArrayVariable::IntArrayVariable(ParserContext* ctx, int size, ArgsRef values)  void PolyphonicRealVariable::dump(int level) {
947      : Variable(ctx, 0, false)      printIndents(level);
948        printf("PolyphonicRealVariable\n");
949    }
950    
951    IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size) :
952        Variable({
953            .ctx = ctx,
954            .isPolyphonic = false,
955            .isConst = false,
956            .isFinal = false,
957            .elements = 0,
958            .memPos = 0,
959            .unitFactorMemPos = 0,
960            .unitType = VM_NO_UNIT
961        })
962    {
963        values.resize(size);
964        memset(&values[0], 0, size * sizeof(vmint));
965    
966        unitFactors.resize(size);
967        for (size_t i = 0; i < size; ++i)
968            unitFactors[i] = VM_NO_FACTOR;
969    }
970    
971    IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size,
972                                       ArgsRef values, bool _bConst) :
973        Variable({
974            .ctx = ctx,
975            .isPolyphonic = false,
976            .isConst = _bConst,
977            .isFinal = false,
978            .elements = 0,
979            .memPos = 0,
980            .unitFactorMemPos = 0,
981            .unitType = VM_NO_UNIT
982        })
983  {  {
984      this->values.resize(size);      this->values.resize(size);
985      for (int i = 0; i < values->argsCount(); ++i) {      this->unitFactors.resize(size);
986        for (vmint i = 0; i < values->argsCount(); ++i) {
987          VMIntExpr* expr = dynamic_cast<VMIntExpr*>(values->arg(i));          VMIntExpr* expr = dynamic_cast<VMIntExpr*>(values->arg(i));
988          if (expr) this->values[i] = expr->evalInt();          if (expr) {
989                this->values[i] = expr->evalInt();
990                this->unitFactors[i] = expr->unitFactor();
991            }
992      }      }
993  }  }
994    
995  IntArrayVariable::IntArrayVariable(ParserContext* ctx, bool bConst)  IntArrayVariable::IntArrayVariable(ParserContext* ctx, bool bConst) :
996      : Variable(ctx, 0, bConst)      Variable({
997            .ctx = ctx,
998            .isPolyphonic = false,
999            .isConst = bConst,
1000            .isFinal = false,
1001            .elements = 0,
1002            .memPos = 0,
1003            .unitFactorMemPos = 0,
1004            .unitType = VM_NO_UNIT
1005        })
1006  {  {
1007  }  }
1008    
1009  int IntArrayVariable::evalIntElement(uint i) {  vmint IntArrayVariable::evalIntElement(vmuint i) {
1010      if (i >= values.size()) return 0;      if (i >= values.size()) return 0;
1011      return values[i];      return values[i];
1012  }  }
1013    
1014  void IntArrayVariable::assignIntElement(uint i, int value) {  void IntArrayVariable::assignIntElement(vmuint i, vmint value) {
1015      if (i >= values.size()) return;      if (i >= values.size()) return;
1016      values[i] = value;      values[i] = value;
1017  }  }
1018    
1019    vmfloat IntArrayVariable::unitFactorOfElement(vmuint i) const {
1020        if (i >= unitFactors.size()) return VM_NO_FACTOR;
1021        return unitFactors[i];
1022    }
1023    
1024    void IntArrayVariable::assignElementUnitFactor(vmuint i, vmfloat factor) {
1025        if (i >= unitFactors.size()) return;
1026        unitFactors[i] = factor;
1027    }
1028    
1029  void IntArrayVariable::dump(int level) {  void IntArrayVariable::dump(int level) {
1030      printIndents(level);      printIndents(level);
1031      printf("IntArray(");      printf("IntArray(");
1032      for (int i = 0; i < values.size(); ++i) {      for (vmint i = 0; i < values.size(); ++i) {
1033          if (i % 12 == 0) {          if (i % 12 == 0) {
1034              printf("\n");              printf("\n");
1035              printIndents(level+1);              printIndents(level+1);
1036          }          }
1037          printf("%d, ", values[i]);          printf("%lld, ", values[i]);
1038      }      }
1039      printIndents(level);      printIndents(level);
1040      printf(")\n");      printf(")\n");
1041  }  }
1042    
1043  BuiltInIntArrayVariable::BuiltInIntArrayVariable(const String& name, VMInt8Array* array)  RealArrayVariable::RealArrayVariable(ParserContext* ctx, vmint size) :
1044      : IntArrayVariable(NULL, false), name(name), array(array)      Variable({
1045            .ctx = ctx,
1046            .isPolyphonic = false,
1047            .isConst = false,
1048            .isFinal = false,
1049            .elements = 0,
1050            .memPos = 0,
1051            .unitFactorMemPos = 0,
1052            .unitType = VM_NO_UNIT
1053        })
1054    {
1055        values.resize(size);
1056        memset(&values[0], 0, size * sizeof(vmfloat));
1057    
1058        unitFactors.resize(size);
1059        for (size_t i = 0; i < size; ++i)
1060            unitFactors[i] = VM_NO_FACTOR;
1061    }
1062    
1063    RealArrayVariable::RealArrayVariable(ParserContext* ctx, vmint size,
1064                                         ArgsRef values, bool _bConst) :
1065        Variable({
1066            .ctx = ctx,
1067            .isPolyphonic = false,
1068            .isConst = _bConst,
1069            .isFinal = false,
1070            .elements = 0,
1071            .memPos = 0,
1072            .unitFactorMemPos = 0,
1073            .unitType = VM_NO_UNIT
1074        })
1075  {  {
1076        this->values.resize(size);
1077        this->unitFactors.resize(size);
1078        for (vmint i = 0; i < values->argsCount(); ++i) {
1079            VMRealExpr* expr = dynamic_cast<VMRealExpr*>(values->arg(i));
1080            if (expr) {
1081                this->values[i] = expr->evalReal();
1082                this->unitFactors[i] = expr->unitFactor();
1083            }
1084        }
1085    }
1086    
1087    RealArrayVariable::RealArrayVariable(ParserContext* ctx, bool bConst) :
1088        Variable({
1089            .ctx = ctx,
1090            .isPolyphonic = false,
1091            .isConst = bConst,
1092            .isFinal = false,
1093            .elements = 0,
1094            .memPos = 0,
1095            .unitFactorMemPos = 0,
1096            .unitType = VM_NO_UNIT
1097        })
1098    {
1099    }
1100    
1101    vmfloat RealArrayVariable::evalRealElement(vmuint i) {
1102        if (i >= values.size()) return 0;
1103        return values[i];
1104  }  }
1105    
1106  int BuiltInIntArrayVariable::evalIntElement(uint i) {  void RealArrayVariable::assignRealElement(vmuint i, vmfloat value) {
1107        if (i >= values.size()) return;
1108        values[i] = value;
1109    }
1110    
1111    vmfloat RealArrayVariable::unitFactorOfElement(vmuint i) const {
1112        if (i >= unitFactors.size()) return VM_NO_FACTOR;
1113        return unitFactors[i];
1114    }
1115    
1116    void RealArrayVariable::assignElementUnitFactor(vmuint i, vmfloat factor) {
1117        if (i >= unitFactors.size()) return;
1118        unitFactors[i] = factor;
1119    }
1120    
1121    void RealArrayVariable::dump(int level) {
1122        printIndents(level);
1123        printf("RealArray(");
1124        for (vmint i = 0; i < values.size(); ++i) {
1125            if (i % 12 == 0) {
1126                printf("\n");
1127                printIndents(level+1);
1128            }
1129            printf("%f, ", values[i]);
1130        }
1131        printIndents(level);
1132        printf(")\n");
1133    }
1134    
1135    BuiltInIntArrayVariable::BuiltInIntArrayVariable(const String& name,
1136                                                     VMInt8Array* array) :
1137        IntArrayVariable(NULL, false),
1138        name(name), array(array)
1139    {
1140    }
1141    
1142    vmint BuiltInIntArrayVariable::evalIntElement(vmuint i) {
1143      return i >= array->size ? 0 : array->data[i];      return i >= array->size ? 0 : array->data[i];
1144  }  }
1145    
1146  void BuiltInIntArrayVariable::assignIntElement(uint i, int value) {  void BuiltInIntArrayVariable::assignIntElement(vmuint i, vmint value) {
1147      if (i >= array->size) return;      if (i >= array->size) return;
1148      array->data[i] = value;      array->data[i] = value;
1149  }  }
# Line 466  void BuiltInIntArrayVariable::dump(int l Line 1153  void BuiltInIntArrayVariable::dump(int l
1153      printf("Built-In Int Array Variable '%s'\n", name.c_str());      printf("Built-In Int Array Variable '%s'\n", name.c_str());
1154  }  }
1155    
1156  IntArrayElement::IntArrayElement(IntArrayVariableRef array, IntExprRef arrayIndex)  IntArrayElement::IntArrayElement(IntArrayExprRef array, IntExprRef arrayIndex) :
1157      : IntVariable(NULL, false, false, 0), array(array), index(arrayIndex)      IntVariable({
1158            .ctx = NULL,
1159            .isPolyphonic = (array) ? array->isPolyphonic() : false,
1160            .isConst = (array) ? array->isConstExpr() : false,
1161            .isFinal = false,
1162            .elements = 0,
1163            .memPos = 0,
1164            .unitFactorMemPos = 0,
1165            .unitType = VM_NO_UNIT
1166        }),
1167        Unit(VM_NO_UNIT),
1168        array(array), index(arrayIndex), currentIndex(-1)
1169  {      {    
1170  }  }
1171    
1172  void IntArrayElement::assign(Expression* expr) {  void IntArrayElement::assign(Expression* expr) {
1173      IntExpr* valueExpr = dynamic_cast<IntExpr*>(expr);      IntExpr* valueExpr = dynamic_cast<IntExpr*>(expr);
1174      if (!valueExpr) return;      if (!valueExpr) return;
1175      int value = valueExpr->evalInt();      vmint value = valueExpr->evalInt();
1176        vmfloat unitFactor = valueExpr->unitFactor();
1177    
1178      if (!index) return;      if (!index) return;
1179      int idx = index->evalInt();      vmint idx = currentIndex = index->evalInt();
1180      if (idx < 0 || idx >= array->arraySize()) return;      if (idx < 0 || idx >= array->arraySize()) return;
1181    
1182      array->assignIntElement(idx, value);      array->assignIntElement(idx, value);
1183        array->assignElementUnitFactor(idx, unitFactor);
1184  }  }
1185    
1186  int IntArrayElement::evalInt() {  vmint IntArrayElement::evalInt() {
1187      if (!index) return 0;      if (!index) return 0;
1188      int idx = index->evalInt();      vmint idx = currentIndex = index->evalInt();
1189      if (idx < 0 || idx >= array->arraySize()) return 0;      if (idx < 0 || idx >= array->arraySize()) return 0;
1190    
1191      return array->evalIntElement(idx);      return array->evalIntElement(idx);
1192  }  }
1193    
1194    vmfloat IntArrayElement::unitFactor() const {
1195        if (!index) return VM_NO_FACTOR;
1196        vmint idx = currentIndex;
1197        if (idx < 0 || idx >= array->arraySize()) return 0;
1198    
1199        return array->unitFactorOfElement(idx);
1200    }
1201    
1202  void IntArrayElement::dump(int level) {  void IntArrayElement::dump(int level) {
1203      printIndents(level);      printIndents(level);
1204      printf("IntArrayElement\n");      printf("IntArrayElement\n");
1205  }  }
1206    
1207  StringVariable::StringVariable(ParserContext* ctx)  RealArrayElement::RealArrayElement(RealArrayExprRef array, IntExprRef arrayIndex) :
1208      : Variable(ctx,ctx->globalStrVarCount++,false)      RealVariable({
1209            .ctx = NULL,
1210            .isPolyphonic = (array) ? array->isPolyphonic() : false,
1211            .isConst = (array) ? array->isConstExpr() : false,
1212            .isFinal = false,
1213            .elements = 0,
1214            .memPos = 0,
1215            .unitFactorMemPos = 0,
1216            .unitType = VM_NO_UNIT
1217        }),
1218        Unit(VM_NO_UNIT),
1219        array(array), index(arrayIndex), currentIndex(-1)
1220    {
1221    }
1222    
1223    void RealArrayElement::assign(Expression* expr) {
1224        RealExpr* valueExpr = dynamic_cast<RealExpr*>(expr);
1225        if (!valueExpr) return;
1226        vmfloat value = valueExpr->evalReal();
1227        vmfloat unitFactor = valueExpr->unitFactor();
1228    
1229        if (!index) return;
1230        vmint idx = currentIndex = index->evalInt();
1231        if (idx < 0 || idx >= array->arraySize()) return;
1232    
1233        array->assignRealElement(idx, value);
1234        array->assignElementUnitFactor(idx, unitFactor);
1235    }
1236    
1237    vmfloat RealArrayElement::evalReal() {
1238        if (!index) return 0;
1239        vmint idx = currentIndex = index->evalInt();
1240        if (idx < 0 || idx >= array->arraySize()) return 0;
1241    
1242        return array->evalRealElement(idx);
1243    }
1244    
1245    vmfloat RealArrayElement::unitFactor() const {
1246        if (!index) return VM_NO_FACTOR;
1247        vmint idx = currentIndex;
1248        if (idx < 0 || idx >= array->arraySize()) return 0;
1249    
1250        return array->unitFactorOfElement(idx);
1251    }
1252    
1253    void RealArrayElement::dump(int level) {
1254        printIndents(level);
1255        printf("RealArrayElement\n");
1256    }
1257    
1258    StringVariable::StringVariable(ParserContext* ctx) :
1259        Variable({
1260            .ctx = ctx,
1261            .elements = 1,
1262            .memPos = ctx->globalStrVarCount++
1263        })
1264  {  {
1265  }  }
1266    
1267  StringVariable::StringVariable(ParserContext* ctx, bool bConst)  StringVariable::StringVariable(ParserContext* ctx, bool bConst) :
1268      : Variable(ctx,0,bConst)      Variable({
1269            .ctx = ctx,
1270            .memPos = 0,
1271            .isConst = bConst
1272        })
1273  {  {
1274  }  }
1275    
# Line 518  String StringVariable::evalStr() { Line 1285  String StringVariable::evalStr() {
1285    
1286  void StringVariable::dump(int level) {  void StringVariable::dump(int level) {
1287      printIndents(level);      printIndents(level);
1288      printf("StringVariable memPos=%d\n", memPos);      printf("StringVariable memPos=%lld\n", memPos);
1289  }  }
1290    
1291  ConstStringVariable::ConstStringVariable(ParserContext* ctx, String _value)  ConstStringVariable::ConstStringVariable(ParserContext* ctx, String _value)
# Line 541  void ConstStringVariable::dump(int level Line 1308  void ConstStringVariable::dump(int level
1308      printf("ConstStringVariable val='%s'\n", value.c_str());      printf("ConstStringVariable val='%s'\n", value.c_str());
1309  }  }
1310    
1311    bool NumberBinaryOp::isFinal() const {
1312        NumberExprRef l = (NumberExprRef) lhs;
1313        NumberExprRef r = (NumberExprRef) rhs;
1314        return l->isFinal() || r->isFinal();
1315    }
1316    
1317    ExprType_t VaritypeScalarBinaryOp::exprType() const {
1318        return (lhs->exprType() == REAL_EXPR || rhs->exprType() == REAL_EXPR) ? REAL_EXPR : INT_EXPR;
1319    }
1320    
1321    String VaritypeScalarBinaryOp::evalCastToStr() {
1322        return (exprType() == REAL_EXPR) ?
1323            RealExpr::evalCastToStr() : IntExpr::evalCastToStr();
1324    }
1325    
1326  void If::dump(int level) {  void If::dump(int level) {
1327      printIndents(level);      printIndents(level);
1328      if (ifStatements && elseStatements)      if (ifStatements && elseStatements)
# Line 551  void If::dump(int level) { Line 1333  void If::dump(int level) {
1333          printf("if [INVALID]\n");          printf("if [INVALID]\n");
1334  }  }
1335    
1336  int If::evalBranch() {  vmint If::evalBranch() {
1337      if (condition->evalInt()) return 0;      if (condition->evalInt()) return 0;
1338      if (elseStatements) return 1;      if (elseStatements) return 1;
1339      return -1;      return -1;
1340  }  }
1341    
1342  Statements* If::branch(uint i) const {  Statements* If::branch(vmuint i) const {
1343      if (i == 0) return (Statements*) &*ifStatements;      if (i == 0) return (Statements*) &*ifStatements;
1344      if (i == 1) return (elseStatements) ? (Statements*) &*elseStatements : NULL;      if (i == 1) return (elseStatements) ? (Statements*) &*elseStatements : NULL;
1345      return NULL;      return NULL;
# Line 573  void SelectCase::dump(int level) { Line 1355  void SelectCase::dump(int level) {
1355      printIndents(level);      printIndents(level);
1356      if (select)      if (select)
1357          if (select->isConstExpr())          if (select->isConstExpr())
1358              printf("Case select %d\n", select->evalInt());              printf("Case select %lld\n", select->evalInt());
1359          else          else
1360              printf("Case select [runtime expr]\n");              printf("Case select [runtime expr]\n");
1361      else      else
1362          printf("Case select NULL\n");          printf("Case select NULL\n");
1363      for (int i = 0; i < branches.size(); ++i) {      for (vmint i = 0; i < branches.size(); ++i) {
1364          printIndents(level+1);          printIndents(level+1);
1365          CaseBranch& branch = branches[i];          CaseBranch& branch = branches[i];
1366          if (branch.from && branch.to)          if (branch.from && branch.to)
1367              if (branch.from->isConstExpr() && branch.to->isConstExpr())              if (branch.from->isConstExpr() && branch.to->isConstExpr())
1368                  printf("case %d to %d\n", branch.from->evalInt(), branch.to->evalInt());                  printf("case %lld to %lld\n", branch.from->evalInt(), branch.to->evalInt());
1369              else if (branch.from->isConstExpr() && !branch.to->isConstExpr())              else if (branch.from->isConstExpr() && !branch.to->isConstExpr())
1370                  printf("case %d to [runtime expr]\n", branch.from->evalInt());                  printf("case %lld to [runtime expr]\n", branch.from->evalInt());
1371              else if (!branch.from->isConstExpr() && branch.to->isConstExpr())              else if (!branch.from->isConstExpr() && branch.to->isConstExpr())
1372                  printf("case [runtime expr] to %d\n", branch.to->evalInt());                  printf("case [runtime expr] to %lld\n", branch.to->evalInt());
1373              else              else
1374                  printf("case [runtime expr] to [runtime expr]\n");                  printf("case [runtime expr] to [runtime expr]\n");
1375          else if (branch.from)          else if (branch.from)
1376              if (branch.from->isConstExpr())              if (branch.from->isConstExpr())
1377                  printf("case %d\n", branch.from->evalInt());                  printf("case %lld\n", branch.from->evalInt());
1378              else              else
1379                  printf("case [runtime expr]\n");                  printf("case [runtime expr]\n");
1380          else          else
# Line 600  void SelectCase::dump(int level) { Line 1382  void SelectCase::dump(int level) {
1382      }      }
1383  }  }
1384    
1385  int SelectCase::evalBranch() {  vmint SelectCase::evalBranch() {
1386      int value = select->evalInt();      vmint value = select->evalInt();
1387      for (int i = 0; i < branches.size(); ++i) {      for (vmint i = 0; i < branches.size(); ++i) {
1388          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" ...
1389              if (branches.at(i).from->evalInt() <= value &&              if (branches.at(i).from->evalInt() <= value &&
1390                  branches.at(i).to->evalInt() >= value) return i;                  branches.at(i).to->evalInt() >= value) return i;
# Line 613  int SelectCase::evalBranch() { Line 1395  int SelectCase::evalBranch() {
1395      return -1;      return -1;
1396  }  }
1397    
1398  Statements* SelectCase::branch(uint i) const {  Statements* SelectCase::branch(vmuint i) const {
1399      if (i < branches.size())      if (i < branches.size())
1400          return const_cast<Statements*>( &*branches[i].statements );          return const_cast<Statements*>( &*branches[i].statements );
1401      return NULL;      return NULL;
# Line 621  Statements* SelectCase::branch(uint i) c Line 1403  Statements* SelectCase::branch(uint i) c
1403    
1404  bool SelectCase::isPolyphonic() const {  bool SelectCase::isPolyphonic() const {
1405      if (select->isPolyphonic()) return true;      if (select->isPolyphonic()) return true;
1406      for (int i = 0; i < branches.size(); ++i)      for (vmint i = 0; i < branches.size(); ++i)
1407          if (branches[i].statements->isPolyphonic())          if (branches[i].statements->isPolyphonic())
1408              return true;              return true;
1409      return false;      return false;
1410  }  }
1411    
 // void Case::addBranch(IntExprRef condition, StatementsRef statements) {  
 //     CaseBranchRef b = new CaseBranchRef;  
 //     b->from = condition;  
 //     b->statements = statements;  
 //     branches.push_back(b);  
 // }  
 //  
 // void Case::addBranch(IntExprRef from, IntExprRef to, StatementsRef statements) {  
 //     CaseBranchRef b = new CaseBranchRef;  
 //     b->from = from;  
 //     b->to   = to;  
 //     b->statements = statements;  
 //     branches.push_back(b);  
 // }  
 //  
 // void Case::addBranch(CaseBranchRef branch) {  
 //     branches.push_back(branch);  
 // }  
   
1412  void While::dump(int level) {  void While::dump(int level) {
1413      printIndents(level);      printIndents(level);
1414      if (m_condition)      if (m_condition)
1415          if (m_condition->isConstExpr())          if (m_condition->isConstExpr())
1416              printf("while (%d) {\n", m_condition->evalInt());              printf("while (%lld) {\n", m_condition->evalInt());
1417          else          else
1418              printf("while ([runtime expr]) {\n");              printf("while ([runtime expr]) {\n");
1419      else      else
# Line 669  bool While::evalLoopStartCondition() { Line 1432  bool While::evalLoopStartCondition() {
1432      return m_condition->evalInt();      return m_condition->evalInt();
1433  }  }
1434    
1435    void SyncBlock::dump(int level) {
1436        printIndents(level);
1437        printf("sync {\n");
1438        m_statements->dump(level+1);
1439        printIndents(level);
1440        printf("}\n");
1441    }
1442    
1443    Statements* SyncBlock::statements() const {
1444        return (m_statements) ? const_cast<Statements*>( &*m_statements ) : NULL;
1445    }
1446    
1447    String Neg::evalCastToStr() {
1448        return expr->evalCastToStr();
1449    }
1450    
1451  void Neg::dump(int level) {  void Neg::dump(int level) {
1452      printIndents(level);      printIndents(level);
1453      printf("Negative Expr\n");      printf("Negative Expr\n");
1454  }  }
1455    
1456  String ConcatString::evalStr() {  String ConcatString::evalStr() {
1457      return lhs->evalCastToStr() + rhs->evalCastToStr();      // temporaries required here to enforce the associative left (to right) order
1458        // ( required for GCC and Visual Studio, see:
1459        //   http://stackoverflow.com/questions/25842902/why-stdstring-concatenation-operator-works-like-right-associative-one
1460        //   Personally I am not convinced that this is "not a bug" of the
1461        //   compiler/STL implementation and the allegedly underlying "function call"
1462        //   nature causing this is IMO no profound reason that the C++ language's
1463        //   "+" operator's left associativity is ignored. -- Christian, 2016-07-14 )
1464        String l = lhs->evalCastToStr();
1465        String r = rhs->evalCastToStr();
1466        return l + r;
1467  }  }
1468    
1469  void ConcatString::dump(int level) {  void ConcatString::dump(int level) {
# Line 693  bool ConcatString::isConstExpr() const { Line 1481  bool ConcatString::isConstExpr() const {
1481      return lhs->isConstExpr() && rhs->isConstExpr();      return lhs->isConstExpr() && rhs->isConstExpr();
1482  }  }
1483    
1484  int Relation::evalInt() {  Relation::Relation(ExpressionRef lhs, Type type, ExpressionRef rhs) :
1485        Unit(VM_NO_UNIT),
1486        lhs(lhs), rhs(rhs), type(type)
1487    {
1488    }
1489    
1490    // Equal / unequal comparison of real numbers in NKSP scripts:
1491    //
1492    // Unlike system level languages like C/C++ we are less conservative about
1493    // comparing floating point numbers for 'equalness' or 'unequalness' in NKSP
1494    // scripts. Due to the musical context of the NKSP language we automatically
1495    // take the (to be) expected floating point tolerances into account when
1496    // comparing two floating point numbers with each other, however only for '='
1497    // and '#' operators. The '<=' and '>=' still use conservative low level
1498    // floating point comparison for not breaking their transitivity feature.
1499    
1500    template<typename T_LHS, typename T_RHS>
1501    struct RelComparer {
1502        static inline bool isEqual(T_LHS a, T_RHS b) { // for int comparison ('3 = 3')
1503            return a == b;
1504        }
1505        static inline bool isUnequal(T_LHS a, T_RHS b) { // for int comparison ('3 # 3')
1506            return a != b;
1507        }
1508    };
1509    
1510    template<>
1511    struct RelComparer<float,float> {
1512        static inline bool isEqual(float a, float b) { // for real number comparison ('3.1 = 3.1')
1513            return RTMath::fEqual32(a, b);
1514        }
1515        static inline bool isUnequal(float a, float b) { // for real number comparison ('3.1 # 3.1')
1516            return !RTMath::fEqual32(a, b);
1517        }
1518    };
1519    
1520    template<>
1521    struct RelComparer<double,double> {
1522        static inline bool isEqual(double a, double b) { // for future purpose
1523            return RTMath::fEqual64(a, b);
1524        }
1525        static inline bool isUnqqual(double a, double b) { // for future purpose
1526            return !RTMath::fEqual64(a, b);
1527        }
1528    };
1529    
1530    template<class T_LHS, class T_RHS>
1531    inline vmint _evalRelation(Relation::Type type, T_LHS lhs, T_RHS rhs) {
1532      switch (type) {      switch (type) {
1533          case LESS_THAN:          case Relation::LESS_THAN:
1534              return lhs->evalInt() < rhs->evalInt();              return lhs < rhs;
1535          case GREATER_THAN:          case Relation::GREATER_THAN:
1536              return lhs->evalInt() > rhs->evalInt();              return lhs > rhs;
1537          case LESS_OR_EQUAL:          case Relation::LESS_OR_EQUAL:
1538              return lhs->evalInt() <= rhs->evalInt();              return lhs <= rhs;
1539          case GREATER_OR_EQUAL:          case Relation::GREATER_OR_EQUAL:
1540              return lhs->evalInt() >= rhs->evalInt();              return lhs >= rhs;
1541          case EQUAL:          case Relation::EQUAL:
1542              if (lhs->exprType() == STRING_EXPR || rhs->exprType() == STRING_EXPR)              return RelComparer<typeof(lhs),typeof(rhs)>::isEqual(lhs, rhs);
1543            case Relation::NOT_EQUAL:
1544                return RelComparer<typeof(lhs),typeof(rhs)>::isUnequal(lhs, rhs);
1545        }
1546        return 0;
1547    }
1548    
1549    template<class T_LVALUE, class T_RVALUE, class T_LEXPR, class T_REXPR>
1550    inline vmint _evalRealRelation(Relation::Type type,
1551                                   T_LVALUE lvalue, T_RVALUE rvalue,
1552                                   T_LEXPR* pLHS, T_REXPR* pRHS)
1553    {
1554        if (pLHS->unitFactor() == pRHS->unitFactor())
1555            return _evalRelation(type, lvalue, rvalue);
1556        if (pLHS->unitFactor() < pRHS->unitFactor())
1557            return _evalRelation(type, lvalue, Unit::convRealToUnitFactor(rvalue, pRHS, pLHS));
1558        else
1559            return _evalRelation(type, Unit::convRealToUnitFactor(lvalue, pLHS, pRHS), rvalue);
1560    }
1561    
1562    template<class T_LEXPR, class T_REXPR>
1563    inline vmint _evalIntRelation(Relation::Type type,
1564                                  vmint lvalue, vmint rvalue,
1565                                  T_LEXPR* pLHS, T_REXPR* pRHS)
1566    {
1567        if (pLHS->unitFactor() == pRHS->unitFactor())
1568            return _evalRelation(type, lvalue, rvalue);
1569        if (pLHS->unitFactor() < pRHS->unitFactor())
1570            return _evalRelation(type, lvalue, Unit::convIntToUnitFactor(rvalue, pRHS, pLHS));
1571        else
1572            return _evalRelation(type, Unit::convIntToUnitFactor(lvalue, pLHS, pRHS), rvalue);
1573    }
1574    
1575    vmint Relation::evalInt() {
1576        const ExprType_t lType = lhs->exprType();
1577        const ExprType_t rType = rhs->exprType();
1578        if (lType == STRING_EXPR || rType == STRING_EXPR) {
1579            switch (type) {
1580                case EQUAL:
1581                  return lhs->evalCastToStr() == rhs->evalCastToStr();                  return lhs->evalCastToStr() == rhs->evalCastToStr();
1582              else              case NOT_EQUAL:
                 return lhs->evalInt() == rhs->evalInt();  
         case NOT_EQUAL:  
             if (lhs->exprType() == STRING_EXPR || rhs->exprType() == STRING_EXPR)  
1583                  return lhs->evalCastToStr() != rhs->evalCastToStr();                  return lhs->evalCastToStr() != rhs->evalCastToStr();
1584              else              default:
1585                  return lhs->evalInt() != rhs->evalInt();                  return 0;
1586            }
1587        } else if (lType == REAL_EXPR && rType == REAL_EXPR) {
1588            vmfloat lvalue = lhs->asReal()->evalReal();
1589            vmfloat rvalue = rhs->asReal()->evalReal();
1590            return _evalRealRelation(
1591                type, lvalue, rvalue, lhs->asReal(), rhs->asReal()
1592            );
1593        } else if (lType == REAL_EXPR && rType == INT_EXPR) {
1594            vmfloat lvalue = lhs->asReal()->evalReal();
1595            vmint rvalue = rhs->asInt()->evalInt();
1596            return _evalRealRelation(
1597                type, lvalue, rvalue, lhs->asReal(), rhs->asInt()
1598            );
1599        } else if (lType == INT_EXPR && rType == REAL_EXPR) {
1600            vmint lvalue = lhs->asInt()->evalInt();
1601            vmfloat rvalue = rhs->asReal()->evalReal();
1602            return _evalRealRelation(
1603                type, lvalue, rvalue, lhs->asInt(), rhs->asReal()
1604            );
1605        } else {
1606            vmint lvalue = lhs->asInt()->evalInt();
1607            vmint rvalue = rhs->asInt()->evalInt();
1608            return _evalIntRelation(
1609                type, lvalue, rvalue, lhs->asInt(), rhs->asInt()
1610            );
1611      }      }
     return 0;  
1612  }  }
1613    
1614  void Relation::dump(int level) {  void Relation::dump(int level) {
# Line 751  bool Relation::isConstExpr() const { Line 1645  bool Relation::isConstExpr() const {
1645      return lhs->isConstExpr() && rhs->isConstExpr();      return lhs->isConstExpr() && rhs->isConstExpr();
1646  }  }
1647    
1648  int Or::evalInt() {  vmint Or::evalInt() {
1649      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1650      if (pLHS->evalInt()) return 1;      if (pLHS->evalInt()) return 1;
1651      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
1652      return (pRHS->evalInt()) ? 1 : 0;      return (pRHS->evalInt()) ? 1 : 0;
1653  }  }
1654    
# Line 769  void Or::dump(int level) { Line 1663  void Or::dump(int level) {
1663      printf(")\n");      printf(")\n");
1664  }  }
1665    
1666  int BitwiseOr::evalInt() {  vmint BitwiseOr::evalInt() {
1667      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1668      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
1669      return pLHS->evalInt() | pRHS->evalInt();      return pLHS->evalInt() | pRHS->evalInt();
# Line 786  void BitwiseOr::dump(int level) { Line 1680  void BitwiseOr::dump(int level) {
1680      printf(")\n");      printf(")\n");
1681  }  }
1682    
1683  int And::evalInt() {  vmint And::evalInt() {
1684      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1685      if (!pLHS->evalInt()) return 0;      if (!pLHS->evalInt()) return 0;
1686      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
# Line 804  void And::dump(int level) { Line 1698  void And::dump(int level) {
1698      printf(")\n");      printf(")\n");
1699  }  }
1700    
1701  int BitwiseAnd::evalInt() {  vmint BitwiseAnd::evalInt() {
1702      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1703      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
1704      return pLHS->evalInt() & pRHS->evalInt();      return pLHS->evalInt() & pRHS->evalInt();
# Line 837  void BitwiseNot::dump(int level) { Line 1731  void BitwiseNot::dump(int level) {
1731      printf(")\n");      printf(")\n");
1732  }  }
1733    
1734    String Final::evalCastToStr() {
1735        if (exprType() == REAL_EXPR)
1736            return ToString(evalReal());
1737        else
1738            return ToString(evalInt());
1739    }
1740    
1741    void Final::dump(int level) {
1742        printIndents(level);
1743        printf("Final(\n");
1744        expr->dump(level+1);
1745        printIndents(level);
1746        printf(")\n");
1747    }
1748    
1749    StatementsRef ParserContext::userFunctionByName(const String& name) {
1750        if (!userFnTable.count(name)) {
1751            return StatementsRef();
1752        }
1753        return userFnTable.find(name)->second;
1754    }
1755    
1756  VariableRef ParserContext::variableByName(const String& name) {  VariableRef ParserContext::variableByName(const String& name) {
1757      if (!vartable.count(name)) {      if (!vartable.count(name)) {
1758          return VariableRef();          return VariableRef();
# Line 858  IntVariableRef ParserContext::globalIntV Line 1774  IntVariableRef ParserContext::globalIntV
1774      return globalVar(name);      return globalVar(name);
1775  }  }
1776    
1777    RealVariableRef ParserContext::globalRealVar(const String& name) {
1778        return globalVar(name);
1779    }
1780    
1781  StringVariableRef ParserContext::globalStrVar(const String& name) {  StringVariableRef ParserContext::globalStrVar(const String& name) {
1782      return globalVar(name);      return globalVar(name);
1783  }  }
# Line 868  ParserContext::~ParserContext() { Line 1788  ParserContext::~ParserContext() {
1788          delete globalIntMemory;          delete globalIntMemory;
1789          globalIntMemory = NULL;          globalIntMemory = NULL;
1790      }      }
1791        if (globalRealMemory) {
1792            delete globalRealMemory;
1793            globalRealMemory = NULL;
1794        }
1795  }  }
1796    
1797  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 894  void ParserContext::addWrn(int firstLine Line 1818  void ParserContext::addWrn(int firstLine
1818      vIssues.push_back(w);      vIssues.push_back(w);
1819  }  }
1820    
1821    void ParserContext::addPreprocessorComment(int firstLine, int lastLine, int firstColumn, int lastColumn) {
1822        CodeBlock block;
1823        block.firstLine = firstLine;
1824        block.lastLine = lastLine;
1825        block.firstColumn = firstColumn;
1826        block.lastColumn = lastColumn;
1827        vPreprocessorComments.push_back(block);
1828    }
1829    
1830  bool ParserContext::setPreprocessorCondition(const char* name) {  bool ParserContext::setPreprocessorCondition(const char* name) {
1831      if (builtinPreprocessorConditions.count(name)) return false;      if (builtinPreprocessorConditions.count(name)) return false;
1832      if (userPreprocessorConditions.count(name)) return false;      if (userPreprocessorConditions.count(name)) return false;
# Line 925  std::vector<ParserIssue> ParserContext:: Line 1858  std::vector<ParserIssue> ParserContext::
1858      return vWarnings;      return vWarnings;
1859  }  }
1860    
1861    std::vector<CodeBlock> ParserContext::preprocessorComments() const {
1862        return vPreprocessorComments;
1863    }
1864    
1865  VMEventHandler* ParserContext::eventHandler(uint index) {  VMEventHandler* ParserContext::eventHandler(uint index) {
1866      if (!handlers) return NULL;      if (!handlers) return NULL;
1867      return handlers->eventHandler(index);      return handlers->eventHandler(index);
# Line 935  VMEventHandler* ParserContext::eventHand Line 1872  VMEventHandler* ParserContext::eventHand
1872      return handlers->eventHandlerByName(name);      return handlers->eventHandlerByName(name);
1873  }  }
1874    
1875  void ParserContext::registerBuiltInConstIntVariables(const std::map<String,int>& vars) {  void ParserContext::registerBuiltInConstIntVariables(const std::map<String,vmint>& vars) {
1876      for (std::map<String,int>::const_iterator it = vars.begin();      for (std::map<String,vmint>::const_iterator it = vars.begin();
1877             it != vars.end(); ++it)
1878        {
1879            ConstIntVariableRef ref = new ConstIntVariable({
1880                .value = it->second
1881            });
1882            vartable[it->first] = ref;
1883        }
1884    }
1885    
1886    void ParserContext::registerBuiltInConstRealVariables(const std::map<String,vmfloat>& vars) {
1887        for (std::map<String,vmfloat>::const_iterator it = vars.begin();
1888           it != vars.end(); ++it)           it != vars.end(); ++it)
1889      {      {
1890          ConstIntVariableRef ref = new ConstIntVariable(it->second);          ConstRealVariableRef ref = new ConstRealVariable({
1891                .value = it->second
1892            });
1893          vartable[it->first] = ref;          vartable[it->first] = ref;
1894      }      }
1895  }  }
1896    
1897  void ParserContext::registerBuiltInIntVariables(const std::map<String,VMIntRelPtr*>& vars) {  void ParserContext::registerBuiltInIntVariables(const std::map<String,VMIntPtr*>& vars) {
1898      for (std::map<String,VMIntRelPtr*>::const_iterator it = vars.begin();      for (std::map<String,VMIntPtr*>::const_iterator it = vars.begin();
1899           it != vars.end(); ++it)           it != vars.end(); ++it)
1900      {      {
1901          BuiltInIntVariableRef ref = new BuiltInIntVariable(it->first, it->second);          BuiltInIntVariableRef ref = new BuiltInIntVariable(it->first, it->second);
# Line 962  void ParserContext::registerBuiltInIntAr Line 1912  void ParserContext::registerBuiltInIntAr
1912      }      }
1913  }  }
1914    
1915    void ParserContext::registerBuiltInDynVariables(const std::map<String,VMDynVar*>& vars) {
1916        for (std::map<String,VMDynVar*>::const_iterator it = vars.begin();
1917             it != vars.end(); ++it)
1918        {
1919            DynamicVariableCallRef ref = new DynamicVariableCall(it->first, this, it->second);
1920            vartable[it->first] = ref;
1921        }
1922    }
1923    
1924    ExecContext::ExecContext() :
1925        status(VM_EXEC_NOT_RUNNING), flags(STMT_SUCCESS), stackFrame(-1),
1926        suspendMicroseconds(0), instructionsCount(0)
1927    {
1928        exitRes.value = NULL;
1929    }
1930    
1931    void ExecContext::forkTo(VMExecContext* ectx) const {
1932        ExecContext* child = dynamic_cast<ExecContext*>(ectx);
1933    
1934        child->polyphonicIntMemory.copyFlatFrom(polyphonicIntMemory);
1935        child->polyphonicRealMemory.copyFlatFrom(polyphonicRealMemory);
1936        child->status = VM_EXEC_SUSPENDED;
1937        child->flags = STMT_SUCCESS;
1938        child->stack.copyFlatFrom(stack);
1939        child->stackFrame = stackFrame;
1940        child->suspendMicroseconds = 0;
1941        child->instructionsCount = 0;
1942    }
1943    
1944  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.2935  
changed lines
  Added in v.3590

  ViewVC Help
Powered by ViewVC