/[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 2645 by schoenebeck, Wed Jun 18 00:14:57 2014 UTC revision 3714 by schoenebeck, Sat Jan 11 20:19:11 2020 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (c) 2014 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    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  int IntLiteral::evalInt() {  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 %" PRId64 "\n", (int64_t)value);
192    }
193    
194    RealLiteral::RealLiteral(const RealLitDef& def) :
195        RealExpr(), Unit(def.unitType),
196        value(def.value), unitPrefixFactor(def.unitFactor),
197        finalVal(def.isFinal)
198    {
199    }
200    
201    vmfloat RealLiteral::evalReal() {
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        //FIXME: asIntArray() not intended for evaluation semantics (for both
643        // performance reasons with arrays, but also to prevent undesired value
644        // mutation by implied (hidden) evaluation, as actually done here. We must
645        // force function evaluation here though, because we need it for function
646        // calls to be evaluated at all. This issue should be addressed cleanly by
647        // adjusting the API appropriately.
648        FunctionCall* rwSelf = const_cast<FunctionCall*>(this);
649        rwSelf->result = rwSelf->execVMFn();
650    
651        if (!result) return 0;
652        VMIntArrayExpr* intArrExpr = dynamic_cast<VMIntArrayExpr*>(result->resultValue());
653        return intArrExpr;
654    }
655    
656    VMRealArrayExpr* FunctionCall::asRealArray() const {
657        //FIXME: asRealArray() not intended for evaluation semantics (for both
658        // performance reasons with arrays, but also to prevent undesired value
659        // mutation by implied (hidden) evaluation, as actually done here. We must
660        // force function evaluation here though, because we need it for function
661        // calls to be evaluated at all. This issue should be addressed cleanly by
662        // adjusting the API appropriately.
663        FunctionCall* rwSelf = const_cast<FunctionCall*>(this);
664        rwSelf->result = rwSelf->execVMFn();
665    
666        if (!result) return 0;
667        VMRealArrayExpr* realArrExpr = dynamic_cast<VMRealArrayExpr*>(result->resultValue());
668        return realArrExpr;
669    }
670    
671  String FunctionCall::evalStr() {  String FunctionCall::evalStr() {
672      VMFnResult* result = execVMFn();      result = execVMFn();
673      if (!result) return "";      if (!result) return "";
674      VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());      VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());
675      if (!strExpr) return "";      if (!strExpr) return "";
# Line 287  String FunctionCall::evalStr() { Line 677  String FunctionCall::evalStr() {
677  }  }
678    
679  String FunctionCall::evalCastToStr() {  String FunctionCall::evalCastToStr() {
680      VMFnResult* result = execVMFn();      result = execVMFn();
681      if (!result) return "";      if (!result) return "";
682      if (result->resultValue()->exprType() == STRING_EXPR) {      const ExprType_t resultType = result->resultValue()->exprType();
683        if (resultType == STRING_EXPR) {
684          VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());          VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());
685          return strExpr ? strExpr->evalStr() : "";          return strExpr ? strExpr->evalStr() : "";
686        } else if (resultType == REAL_EXPR) {
687            VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());
688            return realExpr ? ToString(realExpr->evalReal()) : "";
689      } else {      } else {
690          VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());          VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());
691          return intExpr ? ToString(intExpr->evalInt()) : "";          return intExpr ? ToString(intExpr->evalInt()) : "";
692      }      }
693  }  }
694    
695  IntVariable::IntVariable(ParserContext* ctx)  Variable::Variable(const VariableDecl& decl) :
696      : Variable(ctx, ctx ? ctx->globalIntVarCount++ : 0, false), polyphonic(false)      context(decl.ctx), memPos(decl.memPos), bConst(decl.isConst)
697    {
698    }
699    
700    NumberVariable::NumberVariable(const VariableDecl& decl) :
701        Variable(decl),
702        Unit(decl.unitType),
703        unitFactorMemPos(decl.unitFactorMemPos), polyphonic(decl.isPolyphonic),
704        finalVal(decl.isFinal)
705  {  {
     //printf("globalIntVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);  
     assert(ctx);  
706  }  }
707    
708  inline static int postfixInc(int& object, int incBy) {  vmfloat NumberVariable::unitFactor() const {
709      const int i = object;      if (isPolyphonic()) {
710            return context->execContext->polyphonicUnitFactorMemory[unitFactorMemPos];
711        }
712        return (*context->globalUnitFactorMemory)[unitFactorMemPos];
713    }
714    
715    inline static vmint postfixInc(vmint& object, vmint incBy) {
716        const vmint i = object;
717      object += incBy;      object += incBy;
718      return i;      return i;
719  }  }
720    
721  IntVariable::IntVariable(ParserContext* ctx, bool polyphonic, bool bConst, int size)  IntVariable::IntVariable(const VariableDecl& decl) :
722      : Variable(ctx, !ctx ? 0 : polyphonic ? postfixInc(ctx->polyphonicIntVarCount, size) : postfixInc(ctx->globalIntVarCount, size), bConst),      NumberVariable({
723        polyphonic(polyphonic)          .ctx = decl.ctx,
724  {          .isPolyphonic = decl.isPolyphonic,
725      //printf("InvVar size=%d parserCtx=0x%lx\n", size, (uint64_t)ctx);          .isConst = decl.isConst,
726      if (polyphonic) {          .elements = decl.elements,
727          //printf("polyIntVar memPOS=%d\n", memPos);          .memPos = (
728          assert(ctx);              (!decl.ctx) ? 0 :
729      }                  (decl.isPolyphonic) ?
730                        postfixInc(decl.ctx->polyphonicIntVarCount, decl.elements) :
731                        postfixInc(decl.ctx->globalIntVarCount, decl.elements)
732            ),
733            .unitFactorMemPos = (
734                (!decl.ctx) ? 0 :
735                    (decl.isPolyphonic) ?
736                        postfixInc(decl.ctx->polyphonicUnitFactorCount, decl.elements) :
737                        postfixInc(decl.ctx->globalUnitFactorCount, decl.elements)
738            ),
739            .unitType = decl.unitType,
740            .isFinal = decl.isFinal,
741        }),
742        Unit(decl.unitType)
743    {
744        //printf("IntVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);
745        assert(!decl.isPolyphonic || decl.ctx);
746  }  }
747    
748  void IntVariable::assign(Expression* expr) {  void IntVariable::assign(Expression* expr) {
749      IntExpr* intExpr = dynamic_cast<IntExpr*>(expr);      IntExpr* intExpr = dynamic_cast<IntExpr*>(expr);
750      if (intExpr)      if (intExpr) {
751          if (polyphonic)          //NOTE: sequence matters! evalInt() must be called before getting unitFactor() !
752            if (isPolyphonic()) {
753              context->execContext->polyphonicIntMemory[memPos] = intExpr->evalInt();              context->execContext->polyphonicIntMemory[memPos] = intExpr->evalInt();
754          else              context->execContext->polyphonicUnitFactorMemory[unitFactorMemPos] = intExpr->unitFactor();
755            } else {
756              (*context->globalIntMemory)[memPos] = intExpr->evalInt();              (*context->globalIntMemory)[memPos] = intExpr->evalInt();
757                (*context->globalUnitFactorMemory)[unitFactorMemPos] = intExpr->unitFactor();
758            }
759        }
760  }  }
761    
762  int IntVariable::evalInt() {  vmint IntVariable::evalInt() {
763      //printf("IntVariable::eval pos=%d\n", memPos);      //printf("IntVariable::eval pos=%d\n", memPos);
764      if (polyphonic) {      if (isPolyphonic()) {
765          //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);
766          return context->execContext->polyphonicIntMemory[memPos];          return context->execContext->polyphonicIntMemory[memPos];
767      }      }
# Line 342  int IntVariable::evalInt() { Line 770  int IntVariable::evalInt() {
770    
771  void IntVariable::dump(int level) {  void IntVariable::dump(int level) {
772      printIndents(level);      printIndents(level);
773        printf("IntVariable\n");
774      //printf("IntVariable memPos=%d\n", memPos);      //printf("IntVariable memPos=%d\n", memPos);
775  }  }
776    
777  //ConstIntVariable::ConstIntVariable(ParserContext* ctx, int value)  RealVariable::RealVariable(const VariableDecl& decl) :
778  ConstIntVariable::ConstIntVariable(int value)      NumberVariable({
779      : IntVariable(NULL,false,true), value(value)          .ctx = decl.ctx,
780            .isPolyphonic = decl.isPolyphonic,
781            .isConst = decl.isConst,
782            .elements = decl.elements,
783            .memPos = (
784                (!decl.ctx) ? 0 :
785                    (decl.isPolyphonic) ?
786                        postfixInc(decl.ctx->polyphonicRealVarCount, decl.elements) :
787                        postfixInc(decl.ctx->globalRealVarCount, decl.elements)
788            ),
789            .unitFactorMemPos = (
790                (!decl.ctx) ? 0 :
791                    (decl.isPolyphonic) ?
792                        postfixInc(decl.ctx->polyphonicUnitFactorCount, decl.elements) :
793                        postfixInc(decl.ctx->globalUnitFactorCount, decl.elements)
794            ),
795            .unitType = decl.unitType,
796            .isFinal = decl.isFinal,
797        }),
798        Unit(decl.unitType)
799    {
800        //printf("RealVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);
801        assert(!decl.isPolyphonic || decl.ctx);
802    }
803    
804    void RealVariable::assign(Expression* expr) {
805        RealExpr* realExpr = dynamic_cast<RealExpr*>(expr);
806        if (realExpr) {
807            //NOTE: sequence matters! evalReal() must be called before getting unitFactor() !
808            if (isPolyphonic()) {
809                context->execContext->polyphonicRealMemory[memPos] = realExpr->evalReal();
810                context->execContext->polyphonicUnitFactorMemory[unitFactorMemPos] = realExpr->unitFactor();
811            } else {
812                (*context->globalRealMemory)[memPos] = realExpr->evalReal();
813                (*context->globalUnitFactorMemory)[unitFactorMemPos] = realExpr->unitFactor();
814            }
815        }
816    }
817    
818    vmfloat RealVariable::evalReal() {
819        //printf("RealVariable::eval pos=%d\n", memPos);
820        if (isPolyphonic()) {
821            //printf("evalReal() poly memPos=%d execCtx=0x%lx\n", memPos, (uint64_t)context->execContext);
822            return context->execContext->polyphonicRealMemory[memPos];
823        }
824        return (*context->globalRealMemory)[memPos];
825    }
826    
827    void RealVariable::dump(int level) {
828        printIndents(level);
829        printf("RealVariable\n");
830        //printf("RealVariable memPos=%d\n", memPos);
831    }
832    
833    ConstIntVariable::ConstIntVariable(const IntVarDef& def) :
834        IntVariable({
835            .ctx = def.ctx,
836            .isPolyphonic = false,
837            .isConst = true,
838            .elements = 1,
839            .memPos = def.memPos,
840            .unitFactorMemPos = def.unitFactorMemPos,
841            .unitType = def.unitType,
842            .isFinal = def.isFinal,
843        }),
844        Unit(def.unitType),
845        value(def.value), unitPrefixFactor(def.unitFactor)
846  {  {
847  }  }
848    
# Line 362  void ConstIntVariable::assign(Expression Line 857  void ConstIntVariable::assign(Expression
857  */  */
858  }  }
859    
860  int ConstIntVariable::evalInt() {  vmint ConstIntVariable::evalInt() {
861      return value;      return value;
862  }  }
863    
864  void ConstIntVariable::dump(int level) {  void ConstIntVariable::dump(int level) {
865      printIndents(level);      printIndents(level);
866      printf("ConstIntVariable val=%d\n", value);      printf("ConstIntVariable val=%" PRId64 "\n", (int64_t)value);
867    }
868    
869    ConstRealVariable::ConstRealVariable(const RealVarDef& def) :
870        RealVariable({
871            .ctx = def.ctx,
872            .isPolyphonic = false,
873            .isConst = true,
874            .elements = 1,
875            .memPos = def.memPos,
876            .unitFactorMemPos = def.unitFactorMemPos,
877            .unitType = def.unitType,
878            .isFinal = def.isFinal,
879        }),
880        Unit(def.unitType),
881        value(def.value), unitPrefixFactor(def.unitFactor)
882    {
883    }
884    
885    void ConstRealVariable::assign(Expression* expr) {
886        // ignore assignment
887    }
888    
889    vmfloat ConstRealVariable::evalReal() {
890        return value;
891    }
892    
893    void ConstRealVariable::dump(int level) {
894        printIndents(level);
895        printf("ConstRealVariable val=%f\n", value);
896  }  }
897    
898  BuiltInIntVariable::BuiltInIntVariable(const String& name, VMIntRelPtr* ptr)  BuiltInIntVariable::BuiltInIntVariable(const String& name, VMIntPtr* ptr) :
899      : IntVariable(NULL,false,false), name(name), ptr(ptr)      IntVariable({
900            .ctx = NULL,
901            .isPolyphonic = false,
902            .isConst = false, // may or may not be modifyable though!
903            .elements = 0,
904            .memPos = 0,
905            .unitFactorMemPos = 0,
906            .unitType = VM_NO_UNIT,
907            .isFinal = false,
908        }),
909        Unit(VM_NO_UNIT),
910        name(name), ptr(ptr)
911  {  {
912  }  }
913    
# Line 382  void BuiltInIntVariable::assign(Expressi Line 917  void BuiltInIntVariable::assign(Expressi
917      ptr->assign(valueExpr->evalInt());      ptr->assign(valueExpr->evalInt());
918  }  }
919    
920  int BuiltInIntVariable::evalInt() {  vmint BuiltInIntVariable::evalInt() {
921      return ptr->evalInt();      return ptr->evalInt();
922  }  }
923    
# Line 391  void BuiltInIntVariable::dump(int level) Line 926  void BuiltInIntVariable::dump(int level)
926      printf("Built-in IntVar '%s'\n", name.c_str());      printf("Built-in IntVar '%s'\n", name.c_str());
927  }  }
928    
929  PolyphonicIntVariable::PolyphonicIntVariable(ParserContext* ctx)  PolyphonicIntVariable::PolyphonicIntVariable(const VariableDecl& decl) :
930      : IntVariable(ctx,true,false)      IntVariable({
931            .ctx = decl.ctx,
932            .isPolyphonic = true,
933            .isConst = decl.isConst,
934            .elements = 1,
935            .memPos = 0,
936            .unitFactorMemPos = 0,
937            .unitType = decl.unitType,
938            .isFinal = decl.isFinal,
939        }),
940        Unit(decl.unitType)
941  {  {
942  }  }
943    
# Line 401  void PolyphonicIntVariable::dump(int lev Line 946  void PolyphonicIntVariable::dump(int lev
946      printf("PolyphonicIntVariable\n");      printf("PolyphonicIntVariable\n");
947  }  }
948    
949  IntArrayVariable::IntArrayVariable(ParserContext* ctx, int size)  PolyphonicRealVariable::PolyphonicRealVariable(const VariableDecl& decl) :
950      : Variable(ctx, 0, false)      RealVariable({
951            .ctx = decl.ctx,
952            .isPolyphonic = true,
953            .isConst = decl.isConst,
954            .elements = 1,
955            .memPos = 0,
956            .unitFactorMemPos = 0,
957            .unitType = decl.unitType,
958            .isFinal = decl.isFinal,
959        }),
960        Unit(decl.unitType)
961  {  {
     values.resize(size);  
     memset(&values[0], 0, size * sizeof(int));  
962  }  }
963    
964  IntArrayVariable::IntArrayVariable(ParserContext* ctx, int size, ArgsRef values)  void PolyphonicRealVariable::dump(int level) {
965      : Variable(ctx, 0, false)      printIndents(level);
966        printf("PolyphonicRealVariable\n");
967    }
968    
969    IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size) :
970        Variable({
971            .ctx = ctx,
972            .isPolyphonic = false,
973            .isConst = false,
974            .elements = 0,
975            .memPos = 0,
976            .unitFactorMemPos = 0,
977            .unitType = VM_NO_UNIT,
978            .isFinal = false,
979        })
980    {
981        values.resize(size);
982        memset(&values[0], 0, size * sizeof(vmint));
983    
984        unitFactors.resize(size);
985        for (size_t i = 0; i < size; ++i)
986            unitFactors[i] = VM_NO_FACTOR;
987    }
988    
989    IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size,
990                                       ArgsRef values, bool _bConst) :
991        Variable({
992            .ctx = ctx,
993            .isPolyphonic = false,
994            .isConst = _bConst,
995            .elements = 0,
996            .memPos = 0,
997            .unitFactorMemPos = 0,
998            .unitType = VM_NO_UNIT,
999            .isFinal = false,
1000        })
1001  {  {
1002      this->values.resize(size);      this->values.resize(size);
1003      for (int i = 0; i < values->argsCount(); ++i) {      this->unitFactors.resize(size);
1004        for (vmint i = 0; i < values->argsCount(); ++i) {
1005          VMIntExpr* expr = dynamic_cast<VMIntExpr*>(values->arg(i));          VMIntExpr* expr = dynamic_cast<VMIntExpr*>(values->arg(i));
1006          if (expr) this->values[i] = expr->evalInt();          if (expr) {
1007                this->values[i] = expr->evalInt();
1008                this->unitFactors[i] = expr->unitFactor();
1009            }
1010      }      }
1011  }  }
1012    
1013  IntArrayVariable::IntArrayVariable(ParserContext* ctx, bool bConst)  IntArrayVariable::IntArrayVariable(ParserContext* ctx, bool bConst) :
1014      : Variable(ctx, 0, bConst)      Variable({
1015            .ctx = ctx,
1016            .isPolyphonic = false,
1017            .isConst = bConst,
1018            .elements = 0,
1019            .memPos = 0,
1020            .unitFactorMemPos = 0,
1021            .unitType = VM_NO_UNIT,
1022            .isFinal = false,
1023        })
1024  {  {
1025  }  }
1026    
1027  int IntArrayVariable::evalIntElement(uint i) {  vmint IntArrayVariable::evalIntElement(vmuint i) {
1028      if (i >= values.size()) return 0;      if (i >= values.size()) return 0;
1029      return values[i];      return values[i];
1030  }  }
1031    
1032  void IntArrayVariable::assignIntElement(uint i, int value) {  void IntArrayVariable::assignIntElement(vmuint i, vmint value) {
1033      if (i >= values.size()) return;      if (i >= values.size()) return;
1034      values[i] = value;      values[i] = value;
1035  }  }
1036    
1037    vmfloat IntArrayVariable::unitFactorOfElement(vmuint i) const {
1038        if (i >= unitFactors.size()) return VM_NO_FACTOR;
1039        return unitFactors[i];
1040    }
1041    
1042    void IntArrayVariable::assignElementUnitFactor(vmuint i, vmfloat factor) {
1043        if (i >= unitFactors.size()) return;
1044        unitFactors[i] = factor;
1045    }
1046    
1047  void IntArrayVariable::dump(int level) {  void IntArrayVariable::dump(int level) {
1048      printIndents(level);      printIndents(level);
1049      printf("IntArray(");      printf("IntArray(");
1050      for (int i = 0; i < values.size(); ++i) {      for (vmint i = 0; i < values.size(); ++i) {
1051          if (i % 12 == 0) {          if (i % 12 == 0) {
1052              printf("\n");              printf("\n");
1053              printIndents(level+1);              printIndents(level+1);
1054          }          }
1055          printf("%d, ", values[i]);          printf("%" PRId64 ", ", (int64_t)values[i]);
1056      }      }
1057      printIndents(level);      printIndents(level);
1058      printf(")\n");      printf(")\n");
1059  }  }
1060    
1061  BuiltInIntArrayVariable::BuiltInIntArrayVariable(const String& name, VMInt8Array* array)  RealArrayVariable::RealArrayVariable(ParserContext* ctx, vmint size) :
1062      : IntArrayVariable(NULL, false), name(name), array(array)      Variable({
1063            .ctx = ctx,
1064            .isPolyphonic = false,
1065            .isConst = false,
1066            .elements = 0,
1067            .memPos = 0,
1068            .unitFactorMemPos = 0,
1069            .unitType = VM_NO_UNIT,
1070            .isFinal = false,
1071        })
1072    {
1073        values.resize(size);
1074        memset(&values[0], 0, size * sizeof(vmfloat));
1075    
1076        unitFactors.resize(size);
1077        for (size_t i = 0; i < size; ++i)
1078            unitFactors[i] = VM_NO_FACTOR;
1079    }
1080    
1081    RealArrayVariable::RealArrayVariable(ParserContext* ctx, vmint size,
1082                                         ArgsRef values, bool _bConst) :
1083        Variable({
1084            .ctx = ctx,
1085            .isPolyphonic = false,
1086            .isConst = _bConst,
1087            .elements = 0,
1088            .memPos = 0,
1089            .unitFactorMemPos = 0,
1090            .unitType = VM_NO_UNIT,
1091            .isFinal = false,
1092        })
1093  {  {
1094        this->values.resize(size);
1095        this->unitFactors.resize(size);
1096        for (vmint i = 0; i < values->argsCount(); ++i) {
1097            VMRealExpr* expr = dynamic_cast<VMRealExpr*>(values->arg(i));
1098            if (expr) {
1099                this->values[i] = expr->evalReal();
1100                this->unitFactors[i] = expr->unitFactor();
1101            }
1102        }
1103  }  }
1104    
1105  int BuiltInIntArrayVariable::evalIntElement(uint i) {  RealArrayVariable::RealArrayVariable(ParserContext* ctx, bool bConst) :
1106        Variable({
1107            .ctx = ctx,
1108            .isPolyphonic = false,
1109            .isConst = bConst,
1110            .elements = 0,
1111            .memPos = 0,
1112            .unitFactorMemPos = 0,
1113            .unitType = VM_NO_UNIT,
1114            .isFinal = false,
1115        })
1116    {
1117    }
1118    
1119    vmfloat RealArrayVariable::evalRealElement(vmuint i) {
1120        if (i >= values.size()) return 0;
1121        return values[i];
1122    }
1123    
1124    void RealArrayVariable::assignRealElement(vmuint i, vmfloat value) {
1125        if (i >= values.size()) return;
1126        values[i] = value;
1127    }
1128    
1129    vmfloat RealArrayVariable::unitFactorOfElement(vmuint i) const {
1130        if (i >= unitFactors.size()) return VM_NO_FACTOR;
1131        return unitFactors[i];
1132    }
1133    
1134    void RealArrayVariable::assignElementUnitFactor(vmuint i, vmfloat factor) {
1135        if (i >= unitFactors.size()) return;
1136        unitFactors[i] = factor;
1137    }
1138    
1139    void RealArrayVariable::dump(int level) {
1140        printIndents(level);
1141        printf("RealArray(");
1142        for (vmint i = 0; i < values.size(); ++i) {
1143            if (i % 12 == 0) {
1144                printf("\n");
1145                printIndents(level+1);
1146            }
1147            printf("%f, ", values[i]);
1148        }
1149        printIndents(level);
1150        printf(")\n");
1151    }
1152    
1153    BuiltInIntArrayVariable::BuiltInIntArrayVariable(const String& name,
1154                                                     VMInt8Array* array) :
1155        IntArrayVariable(NULL, false),
1156        name(name), array(array)
1157    {
1158    }
1159    
1160    vmint BuiltInIntArrayVariable::evalIntElement(vmuint i) {
1161      return i >= array->size ? 0 : array->data[i];      return i >= array->size ? 0 : array->data[i];
1162  }  }
1163    
1164  void BuiltInIntArrayVariable::assignIntElement(uint i, int value) {  void BuiltInIntArrayVariable::assignIntElement(vmuint i, vmint value) {
1165      if (i >= array->size) return;      if (i >= array->size) return;
1166      array->data[i] = value;      array->data[i] = value;
1167  }  }
# Line 466  void BuiltInIntArrayVariable::dump(int l Line 1171  void BuiltInIntArrayVariable::dump(int l
1171      printf("Built-In Int Array Variable '%s'\n", name.c_str());      printf("Built-In Int Array Variable '%s'\n", name.c_str());
1172  }  }
1173    
1174  IntArrayElement::IntArrayElement(IntArrayVariableRef array, IntExprRef arrayIndex)  IntArrayElement::IntArrayElement(IntArrayExprRef array, IntExprRef arrayIndex) :
1175      : IntVariable(NULL, false, false, 0), array(array), index(arrayIndex)      IntVariable({
1176  {              .ctx = NULL,
1177            .isPolyphonic = (array) ? array->isPolyphonic() : false,
1178            .isConst = (array) ? array->isConstExpr() : false,
1179            .elements = 0,
1180            .memPos = 0,
1181            .unitFactorMemPos = 0,
1182            .unitType = VM_NO_UNIT,
1183            .isFinal = false,
1184        }),
1185        Unit(VM_NO_UNIT),
1186        array(array), index(arrayIndex), currentIndex(-1)
1187    {
1188  }  }
1189    
1190  void IntArrayElement::assign(Expression* expr) {  void IntArrayElement::assign(Expression* expr) {
1191      IntExpr* valueExpr = dynamic_cast<IntExpr*>(expr);      IntExpr* valueExpr = dynamic_cast<IntExpr*>(expr);
1192      if (!valueExpr) return;      if (!valueExpr) return;
1193      int value = valueExpr->evalInt();      vmint value = valueExpr->evalInt();
1194        vmfloat unitFactor = valueExpr->unitFactor();
1195    
1196      if (!index) return;      if (!index) return;
1197      int idx = index->evalInt();      vmint idx = currentIndex = index->evalInt();
1198      if (idx < 0 || idx >= array->arraySize()) return;      if (idx < 0 || idx >= array->arraySize()) return;
1199    
1200      array->assignIntElement(idx, value);      array->assignIntElement(idx, value);
1201        array->assignElementUnitFactor(idx, unitFactor);
1202  }  }
1203    
1204  int IntArrayElement::evalInt() {  vmint IntArrayElement::evalInt() {
1205      if (!index) return 0;      if (!index) return 0;
1206      int idx = index->evalInt();      vmint idx = currentIndex = index->evalInt();
1207      if (idx < 0 || idx >= array->arraySize()) return 0;      if (idx < 0 || idx >= array->arraySize()) return 0;
1208    
1209      return array->evalIntElement(idx);      return array->evalIntElement(idx);
1210  }  }
1211    
1212    vmfloat IntArrayElement::unitFactor() const {
1213        if (!index) return VM_NO_FACTOR;
1214        vmint idx = currentIndex;
1215        if (idx < 0 || idx >= array->arraySize()) return 0;
1216    
1217        return array->unitFactorOfElement(idx);
1218    }
1219    
1220  void IntArrayElement::dump(int level) {  void IntArrayElement::dump(int level) {
1221      printIndents(level);      printIndents(level);
1222      printf("IntArrayElement\n");      printf("IntArrayElement\n");
1223  }  }
1224    
1225  StringVariable::StringVariable(ParserContext* ctx)  RealArrayElement::RealArrayElement(RealArrayExprRef array, IntExprRef arrayIndex) :
1226      : Variable(ctx,ctx->globalStrVarCount++,false)      RealVariable({
1227            .ctx = NULL,
1228            .isPolyphonic = (array) ? array->isPolyphonic() : false,
1229            .isConst = (array) ? array->isConstExpr() : false,
1230            .elements = 0,
1231            .memPos = 0,
1232            .unitFactorMemPos = 0,
1233            .unitType = VM_NO_UNIT,
1234            .isFinal = false,
1235        }),
1236        Unit(VM_NO_UNIT),
1237        array(array), index(arrayIndex), currentIndex(-1)
1238  {  {
1239  }  }
1240    
1241  StringVariable::StringVariable(ParserContext* ctx, bool bConst)  void RealArrayElement::assign(Expression* expr) {
1242      : Variable(ctx,0,bConst)      RealExpr* valueExpr = dynamic_cast<RealExpr*>(expr);
1243        if (!valueExpr) return;
1244        vmfloat value = valueExpr->evalReal();
1245        vmfloat unitFactor = valueExpr->unitFactor();
1246    
1247        if (!index) return;
1248        vmint idx = currentIndex = index->evalInt();
1249        if (idx < 0 || idx >= array->arraySize()) return;
1250    
1251        array->assignRealElement(idx, value);
1252        array->assignElementUnitFactor(idx, unitFactor);
1253    }
1254    
1255    vmfloat RealArrayElement::evalReal() {
1256        if (!index) return 0;
1257        vmint idx = currentIndex = index->evalInt();
1258        if (idx < 0 || idx >= array->arraySize()) return 0;
1259    
1260        return array->evalRealElement(idx);
1261    }
1262    
1263    vmfloat RealArrayElement::unitFactor() const {
1264        if (!index) return VM_NO_FACTOR;
1265        vmint idx = currentIndex;
1266        if (idx < 0 || idx >= array->arraySize()) return 0;
1267    
1268        return array->unitFactorOfElement(idx);
1269    }
1270    
1271    void RealArrayElement::dump(int level) {
1272        printIndents(level);
1273        printf("RealArrayElement\n");
1274    }
1275    
1276    StringVariable::StringVariable(ParserContext* ctx) :
1277        Variable({
1278            .ctx = ctx,
1279            .elements = 1,
1280            .memPos = ctx->globalStrVarCount++
1281        })
1282    {
1283    }
1284    
1285    StringVariable::StringVariable(ParserContext* ctx, bool bConst) :
1286        Variable({
1287            .ctx = ctx,
1288            .isConst = bConst,
1289            .memPos = 0,
1290        })
1291  {  {
1292  }  }
1293    
# Line 518  String StringVariable::evalStr() { Line 1303  String StringVariable::evalStr() {
1303    
1304  void StringVariable::dump(int level) {  void StringVariable::dump(int level) {
1305      printIndents(level);      printIndents(level);
1306      printf("StringVariable memPos=%d\n", memPos);      printf("StringVariable memPos=%" PRId64 "\n", (int64_t)memPos);
1307  }  }
1308    
1309  ConstStringVariable::ConstStringVariable(ParserContext* ctx, String _value)  ConstStringVariable::ConstStringVariable(ParserContext* ctx, String _value)
# Line 541  void ConstStringVariable::dump(int level Line 1326  void ConstStringVariable::dump(int level
1326      printf("ConstStringVariable val='%s'\n", value.c_str());      printf("ConstStringVariable val='%s'\n", value.c_str());
1327  }  }
1328    
1329    bool NumberBinaryOp::isFinal() const {
1330        NumberExprRef l = (NumberExprRef) lhs;
1331        NumberExprRef r = (NumberExprRef) rhs;
1332        return l->isFinal() || r->isFinal();
1333    }
1334    
1335    ExprType_t VaritypeScalarBinaryOp::exprType() const {
1336        return (lhs->exprType() == REAL_EXPR || rhs->exprType() == REAL_EXPR) ? REAL_EXPR : INT_EXPR;
1337    }
1338    
1339    String VaritypeScalarBinaryOp::evalCastToStr() {
1340        return (exprType() == REAL_EXPR) ?
1341            RealExpr::evalCastToStr() : IntExpr::evalCastToStr();
1342    }
1343    
1344  void If::dump(int level) {  void If::dump(int level) {
1345      printIndents(level);      printIndents(level);
1346      if (ifStatements && elseStatements)      if (ifStatements && elseStatements)
# Line 551  void If::dump(int level) { Line 1351  void If::dump(int level) {
1351          printf("if [INVALID]\n");          printf("if [INVALID]\n");
1352  }  }
1353    
1354  int If::evalBranch() {  vmint If::evalBranch() {
1355      if (condition->evalInt()) return 0;      if (condition->evalInt()) return 0;
1356      if (elseStatements) return 1;      if (elseStatements) return 1;
1357      return -1;      return -1;
1358  }  }
1359    
1360  Statements* If::branch(uint i) const {  Statements* If::branch(vmuint i) const {
1361      if (i == 0) return (Statements*) &*ifStatements;      if (i == 0) return (Statements*) &*ifStatements;
1362      if (i == 1) return (elseStatements) ? (Statements*) &*elseStatements : NULL;      if (i == 1) return (elseStatements) ? (Statements*) &*elseStatements : NULL;
1363      return NULL;      return NULL;
# Line 573  void SelectCase::dump(int level) { Line 1373  void SelectCase::dump(int level) {
1373      printIndents(level);      printIndents(level);
1374      if (select)      if (select)
1375          if (select->isConstExpr())          if (select->isConstExpr())
1376              printf("Case select %d\n", select->evalInt());              printf("Case select %" PRId64 "\n", (int64_t)select->evalInt());
1377          else          else
1378              printf("Case select [runtime expr]\n");              printf("Case select [runtime expr]\n");
1379      else      else
1380          printf("Case select NULL\n");          printf("Case select NULL\n");
1381      for (int i = 0; i < branches.size(); ++i) {      for (vmint i = 0; i < branches.size(); ++i) {
1382          printIndents(level+1);          printIndents(level+1);
1383          CaseBranch& branch = branches[i];          CaseBranch& branch = branches[i];
1384          if (branch.from && branch.to)          if (branch.from && branch.to)
1385              if (branch.from->isConstExpr() && branch.to->isConstExpr())              if (branch.from->isConstExpr() && branch.to->isConstExpr())
1386                  printf("case %d to %d\n", branch.from->evalInt(), branch.to->evalInt());                  printf("case %" PRId64 " to %" PRId64 "\n", (int64_t)branch.from->evalInt(), (int64_t)branch.to->evalInt());
1387              else if (branch.from->isConstExpr() && !branch.to->isConstExpr())              else if (branch.from->isConstExpr() && !branch.to->isConstExpr())
1388                  printf("case %d to [runtime expr]\n", branch.from->evalInt());                  printf("case %" PRId64 " to [runtime expr]\n", (int64_t)branch.from->evalInt());
1389              else if (!branch.from->isConstExpr() && branch.to->isConstExpr())              else if (!branch.from->isConstExpr() && branch.to->isConstExpr())
1390                  printf("case [runtime expr] to %d\n", branch.to->evalInt());                  printf("case [runtime expr] to %" PRId64 "\n", (int64_t)branch.to->evalInt());
1391              else              else
1392                  printf("case [runtime expr] to [runtime expr]\n");                  printf("case [runtime expr] to [runtime expr]\n");
1393          else if (branch.from)          else if (branch.from)
1394              if (branch.from->isConstExpr())              if (branch.from->isConstExpr())
1395                  printf("case %d\n", branch.from->evalInt());                  printf("case %" PRId64 "\n", (int64_t)branch.from->evalInt());
1396              else              else
1397                  printf("case [runtime expr]\n");                  printf("case [runtime expr]\n");
1398          else          else
# Line 600  void SelectCase::dump(int level) { Line 1400  void SelectCase::dump(int level) {
1400      }      }
1401  }  }
1402    
1403  int SelectCase::evalBranch() {  vmint SelectCase::evalBranch() {
1404      int value = select->evalInt();      vmint value = select->evalInt();
1405      for (int i = 0; i < branches.size(); ++i) {      for (vmint i = 0; i < branches.size(); ++i) {
1406          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" ...
1407              if (branches.at(i).from->evalInt() <= value &&              if (branches.at(i).from->evalInt() <= value &&
1408                  branches.at(i).to->evalInt() >= value) return i;                  branches.at(i).to->evalInt() >= value) return i;
# Line 613  int SelectCase::evalBranch() { Line 1413  int SelectCase::evalBranch() {
1413      return -1;      return -1;
1414  }  }
1415    
1416  Statements* SelectCase::branch(uint i) const {  Statements* SelectCase::branch(vmuint i) const {
1417      if (i < branches.size())      if (i < branches.size())
1418          return const_cast<Statements*>( &*branches[i].statements );          return const_cast<Statements*>( &*branches[i].statements );
1419      return NULL;      return NULL;
# Line 621  Statements* SelectCase::branch(uint i) c Line 1421  Statements* SelectCase::branch(uint i) c
1421    
1422  bool SelectCase::isPolyphonic() const {  bool SelectCase::isPolyphonic() const {
1423      if (select->isPolyphonic()) return true;      if (select->isPolyphonic()) return true;
1424      for (int i = 0; i < branches.size(); ++i)      for (vmint i = 0; i < branches.size(); ++i)
1425          if (branches[i].statements->isPolyphonic())          if (branches[i].statements->isPolyphonic())
1426              return true;              return true;
1427      return false;      return false;
1428  }  }
1429    
 // 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);  
 // }  
   
1430  void While::dump(int level) {  void While::dump(int level) {
1431      printIndents(level);      printIndents(level);
1432      if (m_condition)      if (m_condition)
1433          if (m_condition->isConstExpr())          if (m_condition->isConstExpr())
1434              printf("while (%d) {\n", m_condition->evalInt());              printf("while (%" PRId64 ") {\n", (int64_t)m_condition->evalInt());
1435          else          else
1436              printf("while ([runtime expr]) {\n");              printf("while ([runtime expr]) {\n");
1437      else      else
# Line 669  bool While::evalLoopStartCondition() { Line 1450  bool While::evalLoopStartCondition() {
1450      return m_condition->evalInt();      return m_condition->evalInt();
1451  }  }
1452    
1453    void SyncBlock::dump(int level) {
1454        printIndents(level);
1455        printf("sync {\n");
1456        m_statements->dump(level+1);
1457        printIndents(level);
1458        printf("}\n");
1459    }
1460    
1461    Statements* SyncBlock::statements() const {
1462        return (m_statements) ? const_cast<Statements*>( &*m_statements ) : NULL;
1463    }
1464    
1465    String Neg::evalCastToStr() {
1466        return expr->evalCastToStr();
1467    }
1468    
1469  void Neg::dump(int level) {  void Neg::dump(int level) {
1470      printIndents(level);      printIndents(level);
1471      printf("Negative Expr\n");      printf("Negative Expr\n");
1472  }  }
1473    
1474  String ConcatString::evalStr() {  String ConcatString::evalStr() {
1475      return lhs->evalCastToStr() + rhs->evalCastToStr();      // temporaries required here to enforce the associative left (to right) order
1476        // ( required for GCC and Visual Studio, see:
1477        //   http://stackoverflow.com/questions/25842902/why-stdstring-concatenation-operator-works-like-right-associative-one
1478        //   Personally I am not convinced that this is "not a bug" of the
1479        //   compiler/STL implementation and the allegedly underlying "function call"
1480        //   nature causing this is IMO no profound reason that the C++ language's
1481        //   "+" operator's left associativity is ignored. -- Christian, 2016-07-14 )
1482        String l = lhs->evalCastToStr();
1483        String r = rhs->evalCastToStr();
1484        return l + r;
1485  }  }
1486    
1487  void ConcatString::dump(int level) {  void ConcatString::dump(int level) {
# Line 693  bool ConcatString::isConstExpr() const { Line 1499  bool ConcatString::isConstExpr() const {
1499      return lhs->isConstExpr() && rhs->isConstExpr();      return lhs->isConstExpr() && rhs->isConstExpr();
1500  }  }
1501    
1502  int Relation::evalInt() {  Relation::Relation(ExpressionRef lhs, Type type, ExpressionRef rhs) :
1503        Unit(VM_NO_UNIT),
1504        lhs(lhs), rhs(rhs), type(type)
1505    {
1506    }
1507    
1508    // Equal / unequal comparison of real numbers in NKSP scripts:
1509    //
1510    // Unlike system level languages like C/C++ we are less conservative about
1511    // comparing floating point numbers for 'equalness' or 'unequalness' in NKSP
1512    // scripts. Due to the musical context of the NKSP language we automatically
1513    // take the (to be) expected floating point tolerances into account when
1514    // comparing two floating point numbers with each other, however only for '='
1515    // and '#' operators. The '<=' and '>=' still use conservative low level
1516    // floating point comparison for not breaking their transitivity feature.
1517    
1518    template<typename T_LHS, typename T_RHS>
1519    struct RelComparer {
1520        static inline bool isEqual(T_LHS a, T_RHS b) { // for int comparison ('3 = 3')
1521            return a == b;
1522        }
1523        static inline bool isUnequal(T_LHS a, T_RHS b) { // for int comparison ('3 # 3')
1524            return a != b;
1525        }
1526    };
1527    
1528    template<>
1529    struct RelComparer<float,float> {
1530        static inline bool isEqual(float a, float b) { // for real number comparison ('3.1 = 3.1')
1531            return RTMath::fEqual32(a, b);
1532        }
1533        static inline bool isUnequal(float a, float b) { // for real number comparison ('3.1 # 3.1')
1534            return !RTMath::fEqual32(a, b);
1535        }
1536    };
1537    
1538    template<>
1539    struct RelComparer<double,double> {
1540        static inline bool isEqual(double a, double b) { // for future purpose
1541            return RTMath::fEqual64(a, b);
1542        }
1543        static inline bool isUnqqual(double a, double b) { // for future purpose
1544            return !RTMath::fEqual64(a, b);
1545        }
1546    };
1547    
1548    template<class T_LHS, class T_RHS>
1549    inline vmint _evalRelation(Relation::Type type, T_LHS lhs, T_RHS rhs) {
1550      switch (type) {      switch (type) {
1551          case LESS_THAN:          case Relation::LESS_THAN:
1552              return lhs->evalInt() < rhs->evalInt();              return lhs < rhs;
1553          case GREATER_THAN:          case Relation::GREATER_THAN:
1554              return lhs->evalInt() > rhs->evalInt();              return lhs > rhs;
1555          case LESS_OR_EQUAL:          case Relation::LESS_OR_EQUAL:
1556              return lhs->evalInt() <= rhs->evalInt();              return lhs <= rhs;
1557          case GREATER_OR_EQUAL:          case Relation::GREATER_OR_EQUAL:
1558              return lhs->evalInt() >= rhs->evalInt();              return lhs >= rhs;
1559          case EQUAL:          case Relation::EQUAL:
1560              if (lhs->exprType() == STRING_EXPR || rhs->exprType() == STRING_EXPR)              return RelComparer<typeof(lhs),typeof(rhs)>::isEqual(lhs, rhs);
1561            case Relation::NOT_EQUAL:
1562                return RelComparer<typeof(lhs),typeof(rhs)>::isUnequal(lhs, rhs);
1563        }
1564        return 0;
1565    }
1566    
1567    template<class T_LVALUE, class T_RVALUE, class T_LEXPR, class T_REXPR>
1568    inline vmint _evalRealRelation(Relation::Type type,
1569                                   T_LVALUE lvalue, T_RVALUE rvalue,
1570                                   T_LEXPR* pLHS, T_REXPR* pRHS)
1571    {
1572        if (pLHS->unitFactor() == pRHS->unitFactor())
1573            return _evalRelation(type, lvalue, rvalue);
1574        if (pLHS->unitFactor() < pRHS->unitFactor())
1575            return _evalRelation(type, lvalue, Unit::convRealToUnitFactor(rvalue, pRHS, pLHS));
1576        else
1577            return _evalRelation(type, Unit::convRealToUnitFactor(lvalue, pLHS, pRHS), rvalue);
1578    }
1579    
1580    template<class T_LEXPR, class T_REXPR>
1581    inline vmint _evalIntRelation(Relation::Type type,
1582                                  vmint lvalue, vmint rvalue,
1583                                  T_LEXPR* pLHS, T_REXPR* pRHS)
1584    {
1585        if (pLHS->unitFactor() == pRHS->unitFactor())
1586            return _evalRelation(type, lvalue, rvalue);
1587        if (pLHS->unitFactor() < pRHS->unitFactor())
1588            return _evalRelation(type, lvalue, Unit::convIntToUnitFactor(rvalue, pRHS, pLHS));
1589        else
1590            return _evalRelation(type, Unit::convIntToUnitFactor(lvalue, pLHS, pRHS), rvalue);
1591    }
1592    
1593    vmint Relation::evalInt() {
1594        const ExprType_t lType = lhs->exprType();
1595        const ExprType_t rType = rhs->exprType();
1596        if (lType == STRING_EXPR || rType == STRING_EXPR) {
1597            switch (type) {
1598                case EQUAL:
1599                  return lhs->evalCastToStr() == rhs->evalCastToStr();                  return lhs->evalCastToStr() == rhs->evalCastToStr();
1600              else              case NOT_EQUAL:
                 return lhs->evalInt() == rhs->evalInt();  
         case NOT_EQUAL:  
             if (lhs->exprType() == STRING_EXPR || rhs->exprType() == STRING_EXPR)  
1601                  return lhs->evalCastToStr() != rhs->evalCastToStr();                  return lhs->evalCastToStr() != rhs->evalCastToStr();
1602              else              default:
1603                  return lhs->evalInt() != rhs->evalInt();                  return 0;
1604            }
1605        } else if (lType == REAL_EXPR && rType == REAL_EXPR) {
1606            vmfloat lvalue = lhs->asReal()->evalReal();
1607            vmfloat rvalue = rhs->asReal()->evalReal();
1608            return _evalRealRelation(
1609                type, lvalue, rvalue, lhs->asReal(), rhs->asReal()
1610            );
1611        } else if (lType == REAL_EXPR && rType == INT_EXPR) {
1612            vmfloat lvalue = lhs->asReal()->evalReal();
1613            vmint rvalue = rhs->asInt()->evalInt();
1614            return _evalRealRelation(
1615                type, lvalue, rvalue, lhs->asReal(), rhs->asInt()
1616            );
1617        } else if (lType == INT_EXPR && rType == REAL_EXPR) {
1618            vmint lvalue = lhs->asInt()->evalInt();
1619            vmfloat rvalue = rhs->asReal()->evalReal();
1620            return _evalRealRelation(
1621                type, lvalue, rvalue, lhs->asInt(), rhs->asReal()
1622            );
1623        } else {
1624            vmint lvalue = lhs->asInt()->evalInt();
1625            vmint rvalue = rhs->asInt()->evalInt();
1626            return _evalIntRelation(
1627                type, lvalue, rvalue, lhs->asInt(), rhs->asInt()
1628            );
1629      }      }
     return 0;  
1630  }  }
1631    
1632  void Relation::dump(int level) {  void Relation::dump(int level) {
# Line 751  bool Relation::isConstExpr() const { Line 1663  bool Relation::isConstExpr() const {
1663      return lhs->isConstExpr() && rhs->isConstExpr();      return lhs->isConstExpr() && rhs->isConstExpr();
1664  }  }
1665    
1666  int Or::evalInt() {  vmint Or::evalInt() {
1667      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1668      if (pLHS->evalInt()) return 1;      if (pLHS->evalInt()) return 1;
1669      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
1670      return (pRHS->evalInt()) ? 1 : 0;      return (pRHS->evalInt()) ? 1 : 0;
1671  }  }
1672    
# Line 769  void Or::dump(int level) { Line 1681  void Or::dump(int level) {
1681      printf(")\n");      printf(")\n");
1682  }  }
1683    
1684  int And::evalInt() {  vmint BitwiseOr::evalInt() {
1685        IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1686        IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
1687        return pLHS->evalInt() | pRHS->evalInt();
1688    }
1689    
1690    void BitwiseOr::dump(int level) {
1691        printIndents(level);
1692        printf("BitwiseOr(\n");
1693        lhs->dump(level+1);
1694        printIndents(level);
1695        printf(",\n");
1696        rhs->dump(level+1);
1697        printIndents(level);
1698        printf(")\n");
1699    }
1700    
1701    vmint And::evalInt() {
1702      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1703      if (!pLHS->evalInt()) return 0;      if (!pLHS->evalInt()) return 0;
1704      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
# Line 787  void And::dump(int level) { Line 1716  void And::dump(int level) {
1716      printf(")\n");      printf(")\n");
1717  }  }
1718    
1719    vmint BitwiseAnd::evalInt() {
1720        IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1721        IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
1722        return pLHS->evalInt() & pRHS->evalInt();
1723    }
1724    
1725    void BitwiseAnd::dump(int level) {
1726        printIndents(level);
1727        printf("BitwiseAnd(\n");
1728        lhs->dump(level+1);
1729        printIndents(level);
1730        printf(",\n");
1731        rhs->dump(level+1);
1732        printIndents(level);
1733        printf(")\n");
1734    }
1735    
1736  void Not::dump(int level) {  void Not::dump(int level) {
1737      printIndents(level);      printIndents(level);
1738      printf("Not(\n");      printf("Not(\n");
# Line 795  void Not::dump(int level) { Line 1741  void Not::dump(int level) {
1741      printf(")\n");      printf(")\n");
1742  }  }
1743    
1744    void BitwiseNot::dump(int level) {
1745        printIndents(level);
1746        printf("BitwiseNot(\n");
1747        expr->dump(level+1);
1748        printIndents(level);
1749        printf(")\n");
1750    }
1751    
1752    String Final::evalCastToStr() {
1753        if (exprType() == REAL_EXPR)
1754            return ToString(evalReal());
1755        else
1756            return ToString(evalInt());
1757    }
1758    
1759    void Final::dump(int level) {
1760        printIndents(level);
1761        printf("Final(\n");
1762        expr->dump(level+1);
1763        printIndents(level);
1764        printf(")\n");
1765    }
1766    
1767    StatementsRef ParserContext::userFunctionByName(const String& name) {
1768        if (!userFnTable.count(name)) {
1769            return StatementsRef();
1770        }
1771        return userFnTable.find(name)->second;
1772    }
1773    
1774  VariableRef ParserContext::variableByName(const String& name) {  VariableRef ParserContext::variableByName(const String& name) {
1775      if (!vartable.count(name)) {      if (!vartable.count(name)) {
1776          return VariableRef();          return VariableRef();
# Line 816  IntVariableRef ParserContext::globalIntV Line 1792  IntVariableRef ParserContext::globalIntV
1792      return globalVar(name);      return globalVar(name);
1793  }  }
1794    
1795    RealVariableRef ParserContext::globalRealVar(const String& name) {
1796        return globalVar(name);
1797    }
1798    
1799  StringVariableRef ParserContext::globalStrVar(const String& name) {  StringVariableRef ParserContext::globalStrVar(const String& name) {
1800      return globalVar(name);      return globalVar(name);
1801  }  }
# Line 826  ParserContext::~ParserContext() { Line 1806  ParserContext::~ParserContext() {
1806          delete globalIntMemory;          delete globalIntMemory;
1807          globalIntMemory = NULL;          globalIntMemory = NULL;
1808      }      }
1809        if (globalRealMemory) {
1810            delete globalRealMemory;
1811            globalRealMemory = NULL;
1812        }
1813  }  }
1814    
1815  void ParserContext::addErr(int line, const char* txt) {  void ParserContext::addErr(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt) {
1816      ParserIssue e;      ParserIssue e;
1817      e.type = PARSER_ERROR;      e.type = PARSER_ERROR;
1818      e.txt = txt;      e.txt = txt;
1819      e.line = line;      e.firstLine = firstLine;
1820        e.lastLine = lastLine;
1821        e.firstColumn = firstColumn;
1822        e.lastColumn = lastColumn;
1823      vErrors.push_back(e);      vErrors.push_back(e);
1824      vIssues.push_back(e);      vIssues.push_back(e);
1825  }  }
1826    
1827  void ParserContext::addWrn(int line, const char* txt) {  void ParserContext::addWrn(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt) {
1828      ParserIssue w;      ParserIssue w;
1829      w.type = PARSER_WARNING;      w.type = PARSER_WARNING;
1830      w.txt = txt;      w.txt = txt;
1831      w.line = line;      w.firstLine = firstLine;
1832        w.lastLine = lastLine;
1833        w.firstColumn = firstColumn;
1834        w.lastColumn = lastColumn;
1835      vWarnings.push_back(w);      vWarnings.push_back(w);
1836      vIssues.push_back(w);      vIssues.push_back(w);
1837  }  }
1838    
1839    void ParserContext::addPreprocessorComment(int firstLine, int lastLine, int firstColumn, int lastColumn) {
1840        CodeBlock block;
1841        block.firstLine = firstLine;
1842        block.lastLine = lastLine;
1843        block.firstColumn = firstColumn;
1844        block.lastColumn = lastColumn;
1845        vPreprocessorComments.push_back(block);
1846    }
1847    
1848  bool ParserContext::setPreprocessorCondition(const char* name) {  bool ParserContext::setPreprocessorCondition(const char* name) {
1849      if (builtinPreprocessorConditions.count(name)) return false;      if (builtinPreprocessorConditions.count(name)) return false;
1850      if (userPreprocessorConditions.count(name)) return false;      if (userPreprocessorConditions.count(name)) return false;
# Line 877  std::vector<ParserIssue> ParserContext:: Line 1876  std::vector<ParserIssue> ParserContext::
1876      return vWarnings;      return vWarnings;
1877  }  }
1878    
1879    std::vector<CodeBlock> ParserContext::preprocessorComments() const {
1880        return vPreprocessorComments;
1881    }
1882    
1883  VMEventHandler* ParserContext::eventHandler(uint index) {  VMEventHandler* ParserContext::eventHandler(uint index) {
1884      if (!handlers) return NULL;      if (!handlers) return NULL;
1885      return handlers->eventHandler(index);      return handlers->eventHandler(index);
# Line 887  VMEventHandler* ParserContext::eventHand Line 1890  VMEventHandler* ParserContext::eventHand
1890      return handlers->eventHandlerByName(name);      return handlers->eventHandlerByName(name);
1891  }  }
1892    
1893  void ParserContext::registerBuiltInConstIntVariables(const std::map<String,int>& vars) {  void ParserContext::registerBuiltInConstIntVariables(const std::map<String,vmint>& vars) {
1894      for (std::map<String,int>::const_iterator it = vars.begin();      for (std::map<String,vmint>::const_iterator it = vars.begin();
1895           it != vars.end(); ++it)           it != vars.end(); ++it)
1896      {      {
1897          ConstIntVariableRef ref = new ConstIntVariable(it->second);          ConstIntVariableRef ref = new ConstIntVariable({
1898                .value = it->second
1899            });
1900          vartable[it->first] = ref;          vartable[it->first] = ref;
1901      }      }
1902  }  }
1903    
1904  void ParserContext::registerBuiltInIntVariables(const std::map<String,VMIntRelPtr*>& vars) {  void ParserContext::registerBuiltInConstRealVariables(const std::map<String,vmfloat>& vars) {
1905      for (std::map<String,VMIntRelPtr*>::const_iterator it = vars.begin();      for (std::map<String,vmfloat>::const_iterator it = vars.begin();
1906             it != vars.end(); ++it)
1907        {
1908            ConstRealVariableRef ref = new ConstRealVariable({
1909                .value = it->second
1910            });
1911            vartable[it->first] = ref;
1912        }
1913    }
1914    
1915    void ParserContext::registerBuiltInIntVariables(const std::map<String,VMIntPtr*>& vars) {
1916        for (std::map<String,VMIntPtr*>::const_iterator it = vars.begin();
1917           it != vars.end(); ++it)           it != vars.end(); ++it)
1918      {      {
1919          BuiltInIntVariableRef ref = new BuiltInIntVariable(it->first, it->second);          BuiltInIntVariableRef ref = new BuiltInIntVariable(it->first, it->second);
# Line 914  void ParserContext::registerBuiltInIntAr Line 1930  void ParserContext::registerBuiltInIntAr
1930      }      }
1931  }  }
1932    
1933    void ParserContext::registerBuiltInDynVariables(const std::map<String,VMDynVar*>& vars) {
1934        for (std::map<String,VMDynVar*>::const_iterator it = vars.begin();
1935             it != vars.end(); ++it)
1936        {
1937            DynamicVariableCallRef ref = new DynamicVariableCall(it->first, this, it->second);
1938            vartable[it->first] = ref;
1939        }
1940    }
1941    
1942    ExecContext::ExecContext() :
1943        status(VM_EXEC_NOT_RUNNING), flags(STMT_SUCCESS), stackFrame(-1),
1944        suspendMicroseconds(0), instructionsCount(0)
1945    {
1946        exitRes.value = NULL;
1947    }
1948    
1949    void ExecContext::forkTo(VMExecContext* ectx) const {
1950        ExecContext* child = dynamic_cast<ExecContext*>(ectx);
1951    
1952        child->polyphonicIntMemory.copyFlatFrom(polyphonicIntMemory);
1953        child->polyphonicRealMemory.copyFlatFrom(polyphonicRealMemory);
1954        child->status = VM_EXEC_SUSPENDED;
1955        child->flags = STMT_SUCCESS;
1956        child->stack.copyFlatFrom(stack);
1957        child->stackFrame = stackFrame;
1958        child->suspendMicroseconds = 0;
1959        child->instructionsCount = 0;
1960    }
1961    
1962  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.2645  
changed lines
  Added in v.3714

  ViewVC Help
Powered by ViewVC