/[svn]/linuxsampler/trunk/src/scriptvm/tree.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/scriptvm/tree.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 3034 by schoenebeck, Mon Oct 31 00:05:00 2016 UTC revision 3792 by schoenebeck, Mon Jun 15 15:26:10 2020 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    #include "CoreVMFunctions.h" // for VMIntResult, VMRealResult
17    
18  namespace LinuxSampler {  namespace LinuxSampler {
19            
20  bool isNoOperation(StatementRef statement) {  bool isNoOperation(StatementRef statement) {
21      NoOperation* noOp = dynamic_cast<NoOperation*>(&*statement);      return statement->statementType() == STMT_NOOP;
22      return noOp;  }
23    
24    String acceptedArgTypesStr(VMFunction* fn, vmint iArg) {
25        static const ExprType_t allTypes[] = {
26            INT_EXPR,
27            INT_ARR_EXPR,
28            REAL_EXPR,
29            REAL_ARR_EXPR,
30            STRING_EXPR,
31            STRING_ARR_EXPR,
32        };
33        const size_t nTypes = sizeof(allTypes) / sizeof(ExprType_t);
34    
35        std::vector<ExprType_t> supportedTypes;
36        for (int iType = 0; iType < nTypes; ++iType) {
37            const ExprType_t& type = allTypes[iType];
38            if (fn->acceptsArgType(iArg, type))
39                supportedTypes.push_back(type);
40        }
41        assert(!supportedTypes.empty());
42    
43        if (supportedTypes.size() == 1) {
44            return typeStr(*supportedTypes.begin());
45        } else {
46            String s = "either ";
47            for (size_t i = 0; i < supportedTypes.size(); ++i) {
48                const ExprType_t& type = supportedTypes[i];
49                if (i == 0) {
50                    s += typeStr(type);
51                } else if (i == supportedTypes.size() - 1) {
52                    s += " or " + typeStr(type);
53                } else {
54                    s += ", " + typeStr(type);
55                }
56            }
57            return s;
58        }
59  }  }
60            
61  Node::Node() {  Node::Node() {
# Line 31  void Node::printIndents(int n) { Line 69  void Node::printIndents(int n) {
69      fflush(stdout);      fflush(stdout);
70  }  }
71    
72    vmint Unit::convIntToUnitFactor(vmint iValue, VMUnit* srcUnit, VMUnit* dstUnit) {
73        vmfloat f = (vmfloat) iValue;
74        vmfloat factor = srcUnit->unitFactor() / dstUnit->unitFactor();
75        if (sizeof(vmfloat) == sizeof(float))
76            return llroundf(f * factor);
77        else
78            return llround(f * factor);
79    }
80    
81    vmint Unit::convIntToUnitFactor(vmint iValue, vmfloat srcFactor, vmfloat dstFactor) {
82        vmfloat f = (vmfloat) iValue;
83        vmfloat factor = srcFactor / dstFactor;
84        if (sizeof(vmfloat) == sizeof(float))
85            return llroundf(f * factor);
86        else
87            return llround(f * factor);
88    }
89    
90    vmfloat Unit::convRealToUnitFactor(vmfloat fValue, VMUnit* srcUnit, VMUnit* dstUnit) {
91        vmfloat factor = srcUnit->unitFactor() / dstUnit->unitFactor();
92        return fValue * factor;
93    }
94    
95    vmfloat Unit::convRealToUnitFactor(vmfloat fValue, vmfloat srcFactor, vmfloat dstFactor) {
96        vmfloat factor = srcFactor / dstFactor;
97        return fValue * factor;
98    }
99    
100    vmint IntExpr::evalIntToUnitFactor(vmfloat unitFactor) {
101        vmfloat f = (vmfloat) evalInt();
102        vmfloat factor = this->unitFactor() / unitFactor;
103        if (sizeof(vmfloat) == sizeof(float))
104            return llroundf(f * factor);
105        else
106            return llround(f * factor);
107    }
108    
109    static String _unitFactorToShortStr(vmfloat unitFactor) {
110        const long int tens = lround( log10(unitFactor) );
111        switch (tens) {
112            case  3: return "k";  // kilo  = 10^3
113            case  2: return "h";  // hecto = 10^2
114            case  1: return "da"; // deca  = 10
115            case  0: return "" ;  //  --   = 1
116            case -1: return "d";  // deci  = 10^-1
117            case -2: return "c";  // centi = 10^-2 (this is also used for tuning "cents")
118            case -3: return "m";  // milli = 10^-3
119            case -4: return "md"; // milli deci = 10^-4
120            case -5: return "mc"; // milli centi = 10^-5 (this is also used for tuning "cents")
121            case -6: return "u";  // micro = 10^-6
122            default: return "*10^" + ToString(tens);
123        }
124    }
125    
126    static String _unitToStr(VMUnit* unit) {
127        const StdUnit_t type = unit->unitType();
128        String sType;
129        switch (type) {
130            case VM_NO_UNIT: break;
131            case VM_SECOND: sType = "s"; break;
132            case VM_HERTZ: sType = "Hz"; break;
133            case VM_BEL: sType = "B"; break;
134        }
135    
136        String prefix = _unitFactorToShortStr( unit->unitFactor() );
137    
138        return prefix + sType;
139    }
140    
141  String IntExpr::evalCastToStr() {  String IntExpr::evalCastToStr() {
142      return ToString(evalInt());      return ToString(evalInt()) + _unitToStr(this);
143    }
144    
145    vmfloat RealExpr::evalRealToUnitFactor(vmfloat unitFactor) {
146        vmfloat f = evalReal();
147        vmfloat factor = this->unitFactor() / unitFactor;
148        return f * factor;
149    }
150    
151    String RealExpr::evalCastToStr() {
152        return ToString(evalReal()) + _unitToStr(this);
153    }
154    
155    String IntArrayExpr::evalCastToStr() {
156        String s = "{";
157        for (vmint i = 0; i < arraySize(); ++i) {
158            vmint val = evalIntElement(i);
159            vmfloat factor = unitFactorOfElement(i);
160            if (i) s += ",";
161            s += ToString(val) + _unitFactorToShortStr(factor);
162        }
163        s += "}";
164        return s;
165    }
166    
167    String RealArrayExpr::evalCastToStr() {
168        String s = "{";
169        for (vmint i = 0; i < arraySize(); ++i) {
170            vmfloat val = evalRealElement(i);
171            vmfloat factor = unitFactorOfElement(i);
172            if (i) s += ",";
173            s += ToString(val) + _unitFactorToShortStr(factor);
174        }
175        s += "}";
176        return s;
177  }  }
178    
179  int IntLiteral::evalInt() {  IntLiteral::IntLiteral(const IntLitDef& def) :
180        IntExpr(), Unit(def.unitType),
181        value(def.value), unitPrefixFactor(def.unitFactor),
182        finalVal(def.isFinal)
183    {
184    }
185    
186    vmint IntLiteral::evalInt() {
187      return value;      return value;
188  }  }
189    
190  void IntLiteral::dump(int level) {  void IntLiteral::dump(int level) {
191      printIndents(level);      printIndents(level);
192      printf("IntLiteral %d\n", value);      printf("IntLiteral %" PRId64 "\n", (int64_t)value);
193    }
194    
195    RealLiteral::RealLiteral(const RealLitDef& def) :
196        RealExpr(), Unit(def.unitType),
197        value(def.value), unitPrefixFactor(def.unitFactor),
198        finalVal(def.isFinal)
199    {
200    }
201    
202    vmfloat RealLiteral::evalReal() {
203        return value;
204    }
205    
206    void RealLiteral::dump(int level) {
207        printIndents(level);
208        printf("RealLiteral %f\n", value);
209  }  }
210    
211  void StringLiteral::dump(int level) {  void StringLiteral::dump(int level) {
# Line 49  void StringLiteral::dump(int level) { Line 213  void StringLiteral::dump(int level) {
213      printf("StringLiteral: '%s'\n", value.c_str());      printf("StringLiteral: '%s'\n", value.c_str());
214  }  }
215    
216  int Add::evalInt() {  Add::Add(NumberExprRef lhs, NumberExprRef rhs) :
217        VaritypeScalarBinaryOp(lhs, rhs),
218        Unit(
219            // lhs and rhs are forced to be same unit type at parse time, so either one is fine here
220            (lhs) ? lhs->unitType() : VM_NO_UNIT
221        )
222    {
223    }
224    
225    vmint Add::evalInt() {
226      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
227      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
228      return (pLHS && pRHS) ? pLHS->evalInt() + pRHS->evalInt() : 0;      if (!pLHS || !pRHS) return 0;
229        // eval*() call is required before calling unitFactor(), since the latter does not evaluate expressions!
230        vmint lvalue = pLHS->evalInt();
231        vmint rvalue = pRHS->evalInt();
232        if (pLHS->unitFactor() == pRHS->unitFactor())
233            return lvalue + rvalue;
234        if (pLHS->unitFactor() < pRHS->unitFactor())
235            return lvalue + Unit::convIntToUnitFactor(rvalue, pRHS, pLHS);
236        else
237            return Unit::convIntToUnitFactor(lvalue, pLHS, pRHS) + rvalue;
238    }
239    
240    vmfloat Add::evalReal() {
241        RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
242        RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);
243        if (!pLHS || !pRHS) return 0;
244        // eval*() call is required before calling unitFactor(), since the latter does not evaluate expressions!
245        vmfloat lvalue = pLHS->evalReal();
246        vmfloat rvalue = pRHS->evalReal();
247        if (pLHS->unitFactor() == pRHS->unitFactor())
248            return lvalue + rvalue;
249        if (pLHS->unitFactor() < pRHS->unitFactor())
250            return lvalue + Unit::convRealToUnitFactor(rvalue, pRHS, pLHS);
251        else
252            return Unit::convRealToUnitFactor(lvalue, pLHS, pRHS) + rvalue;
253    }
254    
255    vmfloat Add::unitFactor() const {
256        const NumberExpr* pLHS = dynamic_cast<const NumberExpr*>(&*lhs);
257        const NumberExpr* pRHS = dynamic_cast<const NumberExpr*>(&*rhs);
258        return (pLHS->unitFactor() < pRHS->unitFactor()) ? pLHS->unitFactor() : pRHS->unitFactor();
259  }  }
260    
261  void Add::dump(int level) {  void Add::dump(int level) {
# Line 66  void Add::dump(int level) { Line 269  void Add::dump(int level) {
269      printf(")\n");      printf(")\n");
270  }  }
271    
272  int Sub::evalInt() {  Sub::Sub(NumberExprRef lhs, NumberExprRef rhs) :
273        VaritypeScalarBinaryOp(lhs, rhs),
274        Unit(
275            // lhs and rhs are forced to be same unit type at parse time, so either one is fine here
276            (lhs) ? lhs->unitType() : VM_NO_UNIT
277        )
278    {
279    }
280    
281    vmint Sub::evalInt() {
282      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
283      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
284      return (pLHS && pRHS) ? pLHS->evalInt() - pRHS->evalInt() : 0;      if (!pLHS || !pRHS) return 0;
285        // eval*() call is required before calling unitFactor(), since the latter does not evaluate expressions!
286        vmint lvalue = pLHS->evalInt();
287        vmint rvalue = pRHS->evalInt();
288        if (pLHS->unitFactor() == pRHS->unitFactor())
289            return lvalue - rvalue;
290        if (pLHS->unitFactor() < pRHS->unitFactor())
291            return lvalue - Unit::convIntToUnitFactor(rvalue, pRHS, pLHS);
292        else
293            return Unit::convIntToUnitFactor(lvalue, pLHS, pRHS) - rvalue;
294    }
295    
296    vmfloat Sub::evalReal() {
297        RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
298        RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);
299        if (!pLHS || !pRHS) return 0;
300        // eval*() call is required before calling unitFactor(), since the latter does not evaluate expressions!
301        vmfloat lvalue = pLHS->evalReal();
302        vmfloat rvalue = pRHS->evalReal();
303        if (pLHS->unitFactor() == pRHS->unitFactor())
304            return lvalue - rvalue;
305        if (pLHS->unitFactor() < pRHS->unitFactor())
306            return lvalue - Unit::convRealToUnitFactor(rvalue, pRHS, pLHS);
307        else
308            return Unit::convRealToUnitFactor(lvalue, pLHS, pRHS) - rvalue;
309    }
310    
311    vmfloat Sub::unitFactor() const {
312        const NumberExpr* pLHS = dynamic_cast<const NumberExpr*>(&*lhs);
313        const NumberExpr* pRHS = dynamic_cast<const NumberExpr*>(&*rhs);
314        return (pLHS->unitFactor() < pRHS->unitFactor()) ? pLHS->unitFactor() : pRHS->unitFactor();
315  }  }
316    
317  void Sub::dump(int level) {  void Sub::dump(int level) {
# Line 83  void Sub::dump(int level) { Line 325  void Sub::dump(int level) {
325      printf(")\n");      printf(")\n");
326  }  }
327    
328  int Mul::evalInt() {  Mul::Mul(NumberExprRef lhs, NumberExprRef rhs) :
329        VaritypeScalarBinaryOp(lhs, rhs),
330        Unit(
331            // currently the NKSP parser only allows a unit type on either side on multiplications
332            (lhs->unitType()) ? lhs->unitType() : rhs->unitType()
333        )
334    {
335    }
336    
337    vmint Mul::evalInt() {
338      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
339      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;
340      return (pLHS && pRHS) ? pLHS->evalInt() * pRHS->evalInt() : 0;      return (pLHS && pRHS) ? pLHS->evalInt() * pRHS->evalInt() : 0;
341  }  }
342    
343    vmfloat Mul::evalReal() {
344        RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
345        RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);;
346        return (pLHS && pRHS) ? pLHS->evalReal() * pRHS->evalReal() : 0;
347    }
348    
349  void Mul::dump(int level) {  void Mul::dump(int level) {
350      printIndents(level);      printIndents(level);
351      printf("Mul(\n");      printf("Mul(\n");
# Line 100  void Mul::dump(int level) { Line 357  void Mul::dump(int level) {
357      printf(")\n");      printf(")\n");
358  }  }
359    
360  int Div::evalInt() {  vmfloat Mul::unitFactor() const {
361        const NumberExpr* pLHS = dynamic_cast<const NumberExpr*>(&*lhs);
362        const NumberExpr* pRHS = dynamic_cast<const NumberExpr*>(&*rhs);
363        return pLHS->unitFactor() * pRHS->unitFactor();
364    }
365    
366    Div::Div(NumberExprRef lhs, NumberExprRef rhs) :
367        VaritypeScalarBinaryOp(lhs, rhs),
368        Unit(
369            // the NKSP parser only allows either A) a unit type on left side and none
370            // on right side or B) an identical unit type on both sides
371            (lhs->unitType() && rhs->unitType()) ? VM_NO_UNIT : lhs->unitType()
372        )
373    {
374    }
375    
376    vmint Div::evalInt() {
377      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
378      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
379      if (!pLHS || !pRHS) return 0;      if (!pLHS || !pRHS) return 0;
380      int l = pLHS->evalInt();      vmint l = pLHS->evalInt();
381      int r = pRHS->evalInt();      vmint r = pRHS->evalInt();
382      if (r == 0) return 0;      if (r == 0) return 0;
383      return l / r;      return l / r;
384  }  }
385    
386    vmfloat Div::evalReal() {
387        RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
388        RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);
389        if (!pLHS || !pRHS) return 0;
390        vmfloat l = pLHS->evalReal();
391        vmfloat r = pRHS->evalReal();
392        if (r == vmfloat(0)) return 0;
393        return l / r;
394    }
395    
396  void Div::dump(int level) {  void Div::dump(int level) {
397      printIndents(level);      printIndents(level);
398      printf("Div(\n");      printf("Div(\n");
# Line 121  void Div::dump(int level) { Line 404  void Div::dump(int level) {
404      printf(")\n");      printf(")\n");
405  }  }
406    
407  int Mod::evalInt() {  vmfloat Div::unitFactor() const {
408        const NumberExpr* pLHS = dynamic_cast<const NumberExpr*>(&*lhs);
409        const NumberExpr* pRHS = dynamic_cast<const NumberExpr*>(&*rhs);
410        return pLHS->unitFactor() / pRHS->unitFactor();
411    }
412    
413    vmint Mod::evalInt() {
414      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
415      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
416      return (pLHS && pRHS) ? pLHS->evalInt() % pRHS->evalInt() : 0;      return (pLHS && pRHS) ? pLHS->evalInt() % pRHS->evalInt() : 0;
417  }  }
418    
# Line 149  void Args::dump(int level) { Line 438  void Args::dump(int level) {
438  }  }
439    
440  bool Args::isPolyphonic() const {  bool Args::isPolyphonic() const {
441      for (int i = 0; i < args.size(); ++i)      for (vmint i = 0; i < args.size(); ++i)
442          if (args[i]->isPolyphonic())          if (args[i]->isPolyphonic())
443              return true;              return true;
444      return false;      return false;
# Line 177  void EventHandlers::dump(int level) { Line 466  void EventHandlers::dump(int level) {
466  }  }
467    
468  EventHandler* EventHandlers::eventHandlerByName(const String& name) const {  EventHandler* EventHandlers::eventHandlerByName(const String& name) const {
469      for (int i = 0; i < args.size(); ++i)      for (vmint i = 0; i < args.size(); ++i)
470          if (args.at(i)->eventHandlerName() == name)          if (args.at(i)->eventHandlerName() == name)
471              return const_cast<EventHandler*>(&*args.at(i));              return const_cast<EventHandler*>(&*args.at(i));
472      return NULL;      return NULL;
# Line 189  EventHandler* EventHandlers::eventHandle Line 478  EventHandler* EventHandlers::eventHandle
478  }  }
479    
480  bool EventHandlers::isPolyphonic() const {  bool EventHandlers::isPolyphonic() const {
481      for (int i = 0; i < args.size(); ++i)      for (vmint i = 0; i < args.size(); ++i)
482          if (args[i]->isPolyphonic())          if (args[i]->isPolyphonic())
483              return true;              return true;
484      return false;      return false;
# Line 241  Statement* Statements::statement(uint i) Line 530  Statement* Statements::statement(uint i)
530  }  }
531    
532  bool Statements::isPolyphonic() const {  bool Statements::isPolyphonic() const {
533      for (int i = 0; i < args.size(); ++i)      for (vmint i = 0; i < args.size(); ++i)
534          if (args[i]->isPolyphonic())          if (args[i]->isPolyphonic())
535              return true;              return true;
536      return false;      return false;
537  }  }
538    
539  DynamicVariableCall::DynamicVariableCall(const String& name, ParserContext* ctx, VMDynVar* v)  DynamicVariableCall::DynamicVariableCall(const String& name, ParserContext* ctx, VMDynVar* v) :
540      : Variable(ctx, 0, false), dynVar(v), varName(name)      Variable({
541            .ctx = ctx,
542            .elements = 0
543        }),
544        Unit(VM_NO_UNIT),
545        dynVar(v), varName(name)
546  {  {
547  }  }
548    
549  int DynamicVariableCall::evalInt() {  vmint DynamicVariableCall::evalInt() {
550      VMIntExpr* expr = dynamic_cast<VMIntExpr*>(dynVar);      VMIntExpr* expr = dynamic_cast<VMIntExpr*>(dynVar);
551      if (!expr) return 0;      if (!expr) return 0;
552      return expr->evalInt();      return expr->evalInt();
# Line 278  void DynamicVariableCall::dump(int level Line 572  void DynamicVariableCall::dump(int level
572      printf("Dynamic Variable '%s'\n", varName.c_str());      printf("Dynamic Variable '%s'\n", varName.c_str());
573  }  }
574    
575    FunctionCall::FunctionCall(const char* function, ArgsRef args, VMFunction* fn) :
576        Unit(
577            (fn) ? fn->returnUnitType(dynamic_cast<VMFnArgs*>(&*args)) : VM_NO_UNIT
578        ),
579        functionName(function), args(args), fn(fn),
580        result( (fn) ? fn->allocResult(dynamic_cast<VMFnArgs*>(&*args)) : NULL )
581    {
582    }
583    
584    FunctionCall::~FunctionCall() {
585        if (result) {
586            delete result;
587            result = NULL;
588        }
589    }
590    
591  void FunctionCall::dump(int level) {  void FunctionCall::dump(int level) {
592      printIndents(level);      printIndents(level);
593      printf("FunctionCall '%s' args={\n", functionName.c_str());      printf("FunctionCall '%s' args={\n", functionName.c_str());
# Line 288  void FunctionCall::dump(int level) { Line 598  void FunctionCall::dump(int level) {
598    
599  ExprType_t FunctionCall::exprType() const {  ExprType_t FunctionCall::exprType() const {
600      if (!fn) return EMPTY_EXPR;      if (!fn) return EMPTY_EXPR;
601      return fn->returnType();      FunctionCall* self = const_cast<FunctionCall*>(this);
602        return fn->returnType(dynamic_cast<VMFnArgs*>(&*self->args));
603    }
604    
605    vmfloat FunctionCall::unitFactor() const {
606        if (!fn || !result) return VM_NO_FACTOR;
607        VMExpr* expr = result->resultValue();
608        if (!expr) return VM_NO_FACTOR;
609        VMNumberExpr* scalar = expr->asNumber();
610        if (!scalar) return VM_NO_FACTOR;
611        return scalar->unitFactor();
612    }
613    
614    bool FunctionCall::isFinal() const {
615        if (!fn) return false;
616        FunctionCall* self = const_cast<FunctionCall*>(this);
617        return fn->returnsFinal(dynamic_cast<VMFnArgs*>(&*self->args));
618  }  }
619    
620  VMFnResult* FunctionCall::execVMFn() {  VMFnResult* FunctionCall::execVMFn() {
621      if (!fn) return NULL;      if (!fn) return NULL;
622    
623        // tell function where it shall dump its return value to
624        VMFnResult* oldRes = fn->boundResult();
625        fn->bindResult(result);
626    
627      // assuming here that all argument checks (amount and types) have been made      // assuming here that all argument checks (amount and types) have been made
628      // at parse time, to avoid time intensive checks on each function call      // at parse time, to avoid time intensive checks on each function call
629      return fn->exec(dynamic_cast<VMFnArgs*>(&*args));      VMFnResult* res = fn->exec(dynamic_cast<VMFnArgs*>(&*args));
630    
631        // restore previous result binding of some potential toplevel or concurrent
632        // caller, i.e. if exactly same function is called more than one time,
633        // concurrently in a term by other FunctionCall objects, e.g.:
634        // ~c := ceil( ceil(~a) + ~b)
635        fn->bindResult(oldRes);
636    
637        if (!res) return res;
638    
639        VMExpr* expr = res->resultValue();
640        if (!expr) return res;
641    
642        // For performance reasons we always only let 'FunctionCall' assign the unit
643        // type to the function's result expression, never by the function
644        // implementation itself, nor by other classes, because a FunctionCall
645        // object solely knows the unit type in O(1).
646        ExprType_t type = expr->exprType();
647        if (type == INT_EXPR) {
648            VMIntResult* intRes = dynamic_cast<VMIntResult*>(res);
649            intRes->unitBaseType = unitType();
650        } else if (type == REAL_EXPR) {
651            VMRealResult* realRes = dynamic_cast<VMRealResult*>(res);
652            realRes->unitBaseType = unitType();
653        }
654    
655        return res;
656  }  }
657    
658  StmtFlags_t FunctionCall::exec() {  StmtFlags_t FunctionCall::exec() {
# Line 305  StmtFlags_t FunctionCall::exec() { Line 662  StmtFlags_t FunctionCall::exec() {
662      return result->resultFlags();      return result->resultFlags();
663  }  }
664    
665  int FunctionCall::evalInt() {  vmint FunctionCall::evalInt() {
666      VMFnResult* result = execVMFn();      VMFnResult* result = execVMFn();
667      if (!result) return 0;      if (!result) return 0;
668      VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());      VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());
# Line 313  int FunctionCall::evalInt() { Line 670  int FunctionCall::evalInt() {
670      return intExpr->evalInt();      return intExpr->evalInt();
671  }  }
672    
673    vmfloat FunctionCall::evalReal() {
674        VMFnResult* result = execVMFn();
675        if (!result) return 0;
676        VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());
677        if (!realExpr) return 0;
678        return realExpr->evalReal();
679    }
680    
681    VMIntArrayExpr* FunctionCall::asIntArray() const {
682        //FIXME: asIntArray() not intended for evaluation semantics (for both
683        // performance reasons with arrays, but also to prevent undesired value
684        // mutation by implied (hidden) evaluation, as actually done here. We must
685        // force function evaluation here though, because we need it for function
686        // calls to be evaluated at all. This issue should be addressed cleanly by
687        // adjusting the API appropriately.
688        FunctionCall* rwSelf = const_cast<FunctionCall*>(this);
689        VMFnResult* result = rwSelf->execVMFn();
690    
691        if (!result) return 0;
692        VMIntArrayExpr* intArrExpr = dynamic_cast<VMIntArrayExpr*>(result->resultValue());
693        return intArrExpr;
694    }
695    
696    VMRealArrayExpr* FunctionCall::asRealArray() const {
697        //FIXME: asRealArray() not intended for evaluation semantics (for both
698        // performance reasons with arrays, but also to prevent undesired value
699        // mutation by implied (hidden) evaluation, as actually done here. We must
700        // force function evaluation here though, because we need it for function
701        // calls to be evaluated at all. This issue should be addressed cleanly by
702        // adjusting the API appropriately.
703        FunctionCall* rwSelf = const_cast<FunctionCall*>(this);
704        VMFnResult* result = rwSelf->execVMFn();
705    
706        if (!result) return 0;
707        VMRealArrayExpr* realArrExpr = dynamic_cast<VMRealArrayExpr*>(result->resultValue());
708        return realArrExpr;
709    }
710    
711  String FunctionCall::evalStr() {  String FunctionCall::evalStr() {
712      VMFnResult* result = execVMFn();      VMFnResult* result = execVMFn();
713      if (!result) return "";      if (!result) return "";
# Line 324  String FunctionCall::evalStr() { Line 719  String FunctionCall::evalStr() {
719  String FunctionCall::evalCastToStr() {  String FunctionCall::evalCastToStr() {
720      VMFnResult* result = execVMFn();      VMFnResult* result = execVMFn();
721      if (!result) return "";      if (!result) return "";
722      if (result->resultValue()->exprType() == STRING_EXPR) {      const ExprType_t resultType = result->resultValue()->exprType();
723        if (resultType == STRING_EXPR) {
724          VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());          VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());
725          return strExpr ? strExpr->evalStr() : "";          return strExpr ? strExpr->evalStr() : "";
726        } else if (resultType == REAL_EXPR) {
727            VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());
728            return realExpr ? ToString(realExpr->evalReal()) + _unitToStr(realExpr) : "";
729      } else {      } else {
730          VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());          VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());
731          return intExpr ? ToString(intExpr->evalInt()) : "";          return intExpr ? ToString(intExpr->evalInt()) + _unitToStr(intExpr) : "";
732      }      }
733  }  }
734    
735  IntVariable::IntVariable(ParserContext* ctx)  Variable::Variable(const VariableDecl& decl) :
736      : Variable(ctx, ctx ? ctx->globalIntVarCount++ : 0, false), polyphonic(false)      context(decl.ctx), memPos(decl.memPos), bConst(decl.isConst)
737  {  {
     //printf("globalIntVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);  
     assert(ctx);  
738  }  }
739    
740  inline static int postfixInc(int& object, int incBy) {  NumberVariable::NumberVariable(const VariableDecl& decl) :
741      const int i = object;      Variable(decl),
742        Unit(decl.unitType),
743        unitFactorMemPos(decl.unitFactorMemPos), polyphonic(decl.isPolyphonic),
744        finalVal(decl.isFinal)
745    {
746    }
747    
748    vmfloat NumberVariable::unitFactor() const {
749        if (isPolyphonic()) {
750            return context->execContext->polyphonicUnitFactorMemory[unitFactorMemPos];
751        }
752        return (*context->globalUnitFactorMemory)[unitFactorMemPos];
753    }
754    
755    inline static vmint postfixInc(vmint& object, vmint incBy) {
756        const vmint i = object;
757      object += incBy;      object += incBy;
758      return i;      return i;
759  }  }
760    
761  IntVariable::IntVariable(ParserContext* ctx, bool polyphonic, bool bConst, int size)  IntVariable::IntVariable(const VariableDecl& decl) :
762      : Variable(ctx, !ctx ? 0 : polyphonic ? postfixInc(ctx->polyphonicIntVarCount, size) : postfixInc(ctx->globalIntVarCount, size), bConst),      NumberVariable({
763        polyphonic(polyphonic)          .ctx = decl.ctx,
764  {          .isPolyphonic = decl.isPolyphonic,
765      //printf("InvVar size=%d parserCtx=0x%lx\n", size, (uint64_t)ctx);          .isConst = decl.isConst,
766      if (polyphonic) {          .elements = decl.elements,
767          //printf("polyIntVar memPOS=%d\n", memPos);          .memPos = (
768          assert(ctx);              (!decl.ctx) ? 0 :
769      }                  (decl.isPolyphonic) ?
770                        postfixInc(decl.ctx->polyphonicIntVarCount, decl.elements) :
771                        postfixInc(decl.ctx->globalIntVarCount, decl.elements)
772            ),
773            .unitFactorMemPos = (
774                (!decl.ctx) ? 0 :
775                    (decl.isPolyphonic) ?
776                        postfixInc(decl.ctx->polyphonicUnitFactorCount, decl.elements) :
777                        postfixInc(decl.ctx->globalUnitFactorCount, decl.elements)
778            ),
779            .unitType = decl.unitType,
780            .isFinal = decl.isFinal,
781        }),
782        Unit(decl.unitType)
783    {
784        //printf("IntVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);
785        assert(!decl.isPolyphonic || decl.ctx);
786  }  }
787    
788  void IntVariable::assign(Expression* expr) {  void IntVariable::assign(Expression* expr) {
789      IntExpr* intExpr = dynamic_cast<IntExpr*>(expr);      IntExpr* intExpr = dynamic_cast<IntExpr*>(expr);
790      if (intExpr) {      if (intExpr) {
791          if (polyphonic)          //NOTE: sequence matters! evalInt() must be called before getting unitFactor() !
792            if (isPolyphonic()) {
793              context->execContext->polyphonicIntMemory[memPos] = intExpr->evalInt();              context->execContext->polyphonicIntMemory[memPos] = intExpr->evalInt();
794          else              context->execContext->polyphonicUnitFactorMemory[unitFactorMemPos] = intExpr->unitFactor();
795            } else {
796              (*context->globalIntMemory)[memPos] = intExpr->evalInt();              (*context->globalIntMemory)[memPos] = intExpr->evalInt();
797                (*context->globalUnitFactorMemory)[unitFactorMemPos] = intExpr->unitFactor();
798            }
799      }      }
800  }  }
801    
802  int IntVariable::evalInt() {  vmint IntVariable::evalInt() {
803      //printf("IntVariable::eval pos=%d\n", memPos);      //printf("IntVariable::eval pos=%d\n", memPos);
804      if (polyphonic) {      if (isPolyphonic()) {
805          //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);
806          return context->execContext->polyphonicIntMemory[memPos];          return context->execContext->polyphonicIntMemory[memPos];
807      }      }
# Line 382  void IntVariable::dump(int level) { Line 814  void IntVariable::dump(int level) {
814      //printf("IntVariable memPos=%d\n", memPos);      //printf("IntVariable memPos=%d\n", memPos);
815  }  }
816    
817  //ConstIntVariable::ConstIntVariable(ParserContext* ctx, int value)  RealVariable::RealVariable(const VariableDecl& decl) :
818  ConstIntVariable::ConstIntVariable(int value)      NumberVariable({
819      : IntVariable(NULL,false,true), value(value)          .ctx = decl.ctx,
820            .isPolyphonic = decl.isPolyphonic,
821            .isConst = decl.isConst,
822            .elements = decl.elements,
823            .memPos = (
824                (!decl.ctx) ? 0 :
825                    (decl.isPolyphonic) ?
826                        postfixInc(decl.ctx->polyphonicRealVarCount, decl.elements) :
827                        postfixInc(decl.ctx->globalRealVarCount, decl.elements)
828            ),
829            .unitFactorMemPos = (
830                (!decl.ctx) ? 0 :
831                    (decl.isPolyphonic) ?
832                        postfixInc(decl.ctx->polyphonicUnitFactorCount, decl.elements) :
833                        postfixInc(decl.ctx->globalUnitFactorCount, decl.elements)
834            ),
835            .unitType = decl.unitType,
836            .isFinal = decl.isFinal,
837        }),
838        Unit(decl.unitType)
839    {
840        //printf("RealVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);
841        assert(!decl.isPolyphonic || decl.ctx);
842    }
843    
844    void RealVariable::assign(Expression* expr) {
845        RealExpr* realExpr = dynamic_cast<RealExpr*>(expr);
846        if (realExpr) {
847            //NOTE: sequence matters! evalReal() must be called before getting unitFactor() !
848            if (isPolyphonic()) {
849                context->execContext->polyphonicRealMemory[memPos] = realExpr->evalReal();
850                context->execContext->polyphonicUnitFactorMemory[unitFactorMemPos] = realExpr->unitFactor();
851            } else {
852                (*context->globalRealMemory)[memPos] = realExpr->evalReal();
853                (*context->globalUnitFactorMemory)[unitFactorMemPos] = realExpr->unitFactor();
854            }
855        }
856    }
857    
858    vmfloat RealVariable::evalReal() {
859        //printf("RealVariable::eval pos=%d\n", memPos);
860        if (isPolyphonic()) {
861            //printf("evalReal() poly memPos=%d execCtx=0x%lx\n", memPos, (uint64_t)context->execContext);
862            return context->execContext->polyphonicRealMemory[memPos];
863        }
864        return (*context->globalRealMemory)[memPos];
865    }
866    
867    void RealVariable::dump(int level) {
868        printIndents(level);
869        printf("RealVariable\n");
870        //printf("RealVariable memPos=%d\n", memPos);
871    }
872    
873    ConstIntVariable::ConstIntVariable(const IntVarDef& def) :
874        IntVariable({
875            .ctx = def.ctx,
876            .isPolyphonic = false,
877            .isConst = true,
878            .elements = 1,
879            .memPos = def.memPos,
880            .unitFactorMemPos = def.unitFactorMemPos,
881            .unitType = def.unitType,
882            .isFinal = def.isFinal,
883        }),
884        Unit(def.unitType),
885        value(def.value), unitPrefixFactor(def.unitFactor)
886  {  {
887  }  }
888    
# Line 399  void ConstIntVariable::assign(Expression Line 897  void ConstIntVariable::assign(Expression
897  */  */
898  }  }
899    
900  int ConstIntVariable::evalInt() {  vmint ConstIntVariable::evalInt() {
901      return value;      return value;
902  }  }
903    
904  void ConstIntVariable::dump(int level) {  void ConstIntVariable::dump(int level) {
905      printIndents(level);      printIndents(level);
906      printf("ConstIntVariable val=%d\n", value);      printf("ConstIntVariable val=%" PRId64 "\n", (int64_t)value);
907  }  }
908    
909  BuiltInIntVariable::BuiltInIntVariable(const String& name, VMIntRelPtr* ptr)  ConstRealVariable::ConstRealVariable(const RealVarDef& def) :
910      : IntVariable(NULL,false,false), name(name), ptr(ptr)      RealVariable({
911            .ctx = def.ctx,
912            .isPolyphonic = false,
913            .isConst = true,
914            .elements = 1,
915            .memPos = def.memPos,
916            .unitFactorMemPos = def.unitFactorMemPos,
917            .unitType = def.unitType,
918            .isFinal = def.isFinal,
919        }),
920        Unit(def.unitType),
921        value(def.value), unitPrefixFactor(def.unitFactor)
922    {
923    }
924    
925    void ConstRealVariable::assign(Expression* expr) {
926        // ignore assignment
927    }
928    
929    vmfloat ConstRealVariable::evalReal() {
930        return value;
931    }
932    
933    void ConstRealVariable::dump(int level) {
934        printIndents(level);
935        printf("ConstRealVariable val=%f\n", value);
936    }
937    
938    BuiltInIntVariable::BuiltInIntVariable(const String& name, VMIntPtr* ptr) :
939        IntVariable({
940            .ctx = NULL,
941            .isPolyphonic = false,
942            .isConst = false, // may or may not be modifyable though!
943            .elements = 0,
944            .memPos = 0,
945            .unitFactorMemPos = 0,
946            .unitType = VM_NO_UNIT,
947            .isFinal = false,
948        }),
949        Unit(VM_NO_UNIT),
950        name(name), ptr(ptr)
951  {  {
952  }  }
953    
# Line 419  void BuiltInIntVariable::assign(Expressi Line 957  void BuiltInIntVariable::assign(Expressi
957      ptr->assign(valueExpr->evalInt());      ptr->assign(valueExpr->evalInt());
958  }  }
959    
960  int BuiltInIntVariable::evalInt() {  vmint BuiltInIntVariable::evalInt() {
961      return ptr->evalInt();      return ptr->evalInt();
962  }  }
963    
# Line 428  void BuiltInIntVariable::dump(int level) Line 966  void BuiltInIntVariable::dump(int level)
966      printf("Built-in IntVar '%s'\n", name.c_str());      printf("Built-in IntVar '%s'\n", name.c_str());
967  }  }
968    
969  PolyphonicIntVariable::PolyphonicIntVariable(ParserContext* ctx)  PolyphonicIntVariable::PolyphonicIntVariable(const VariableDecl& decl) :
970      : IntVariable(ctx,true,false)      IntVariable({
971            .ctx = decl.ctx,
972            .isPolyphonic = true,
973            .isConst = decl.isConst,
974            .elements = 1,
975            .memPos = 0,
976            .unitFactorMemPos = 0,
977            .unitType = decl.unitType,
978            .isFinal = decl.isFinal,
979        }),
980        Unit(decl.unitType)
981  {  {
982  }  }
983    
# Line 438  void PolyphonicIntVariable::dump(int lev Line 986  void PolyphonicIntVariable::dump(int lev
986      printf("PolyphonicIntVariable\n");      printf("PolyphonicIntVariable\n");
987  }  }
988    
989  IntArrayVariable::IntArrayVariable(ParserContext* ctx, int size)  PolyphonicRealVariable::PolyphonicRealVariable(const VariableDecl& decl) :
990      : Variable(ctx, 0, false)      RealVariable({
991            .ctx = decl.ctx,
992            .isPolyphonic = true,
993            .isConst = decl.isConst,
994            .elements = 1,
995            .memPos = 0,
996            .unitFactorMemPos = 0,
997            .unitType = decl.unitType,
998            .isFinal = decl.isFinal,
999        }),
1000        Unit(decl.unitType)
1001  {  {
     values.resize(size);  
     memset(&values[0], 0, size * sizeof(int));  
1002  }  }
1003    
1004  IntArrayVariable::IntArrayVariable(ParserContext* ctx, int size, ArgsRef values)  void PolyphonicRealVariable::dump(int level) {
1005      : Variable(ctx, 0, false)      printIndents(level);
1006        printf("PolyphonicRealVariable\n");
1007    }
1008    
1009    IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size) :
1010        Variable({
1011            .ctx = ctx,
1012            .isPolyphonic = false,
1013            .isConst = false,
1014            .elements = 0,
1015            .memPos = 0,
1016            .unitFactorMemPos = 0,
1017            .unitType = VM_NO_UNIT,
1018            .isFinal = false,
1019        })
1020    {
1021        values.resize(size);
1022        memset(&values[0], 0, size * sizeof(vmint));
1023    
1024        unitFactors.resize(size);
1025        for (size_t i = 0; i < size; ++i)
1026            unitFactors[i] = VM_NO_FACTOR;
1027    }
1028    
1029    IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size,
1030                                       ArgsRef values, bool _bConst) :
1031        Variable({
1032            .ctx = ctx,
1033            .isPolyphonic = false,
1034            .isConst = _bConst,
1035            .elements = 0,
1036            .memPos = 0,
1037            .unitFactorMemPos = 0,
1038            .unitType = VM_NO_UNIT,
1039            .isFinal = false,
1040        })
1041  {  {
1042      this->values.resize(size);      this->values.resize(size);
1043      for (int i = 0; i < values->argsCount(); ++i) {      this->unitFactors.resize(size);
1044        for (vmint i = 0; i < values->argsCount(); ++i) {
1045          VMIntExpr* expr = dynamic_cast<VMIntExpr*>(values->arg(i));          VMIntExpr* expr = dynamic_cast<VMIntExpr*>(values->arg(i));
1046          if (expr) this->values[i] = expr->evalInt();          if (expr) {
1047                this->values[i] = expr->evalInt();
1048                this->unitFactors[i] = expr->unitFactor();
1049            } else {
1050                this->values[i] = 0;
1051                this->unitFactors[i] = VM_NO_FACTOR;
1052            }
1053        }
1054        for (vmint i = values->argsCount(); i < size; ++i) {
1055            this->values[i] = 0;
1056            this->unitFactors[i] = VM_NO_FACTOR;
1057      }      }
1058  }  }
1059    
1060  IntArrayVariable::IntArrayVariable(ParserContext* ctx, bool bConst)  IntArrayVariable::IntArrayVariable(ParserContext* ctx, bool bConst) :
1061      : Variable(ctx, 0, bConst)      Variable({
1062            .ctx = ctx,
1063            .isPolyphonic = false,
1064            .isConst = bConst,
1065            .elements = 0,
1066            .memPos = 0,
1067            .unitFactorMemPos = 0,
1068            .unitType = VM_NO_UNIT,
1069            .isFinal = false,
1070        })
1071  {  {
1072  }  }
1073    
1074  int IntArrayVariable::evalIntElement(uint i) {  vmint IntArrayVariable::evalIntElement(vmuint i) {
1075      if (i >= values.size()) return 0;      if (i >= values.size()) return 0;
1076      return values[i];      return values[i];
1077  }  }
1078    
1079  void IntArrayVariable::assignIntElement(uint i, int value) {  void IntArrayVariable::assignIntElement(vmuint i, vmint value) {
1080      if (i >= values.size()) return;      if (i >= values.size()) return;
1081      values[i] = value;      values[i] = value;
1082  }  }
1083    
1084    vmfloat IntArrayVariable::unitFactorOfElement(vmuint i) const {
1085        if (i >= unitFactors.size()) return VM_NO_FACTOR;
1086        return unitFactors[i];
1087    }
1088    
1089    void IntArrayVariable::assignElementUnitFactor(vmuint i, vmfloat factor) {
1090        if (i >= unitFactors.size()) return;
1091        unitFactors[i] = factor;
1092    }
1093    
1094  void IntArrayVariable::dump(int level) {  void IntArrayVariable::dump(int level) {
1095      printIndents(level);      printIndents(level);
1096      printf("IntArray(");      printf("IntArray(");
1097      for (int i = 0; i < values.size(); ++i) {      for (vmint i = 0; i < values.size(); ++i) {
1098          if (i % 12 == 0) {          if (i % 12 == 0) {
1099              printf("\n");              printf("\n");
1100              printIndents(level+1);              printIndents(level+1);
1101          }          }
1102          printf("%d, ", values[i]);          printf("%" PRId64 ", ", (int64_t)values[i]);
1103      }      }
1104      printIndents(level);      printIndents(level);
1105      printf(")\n");      printf(")\n");
1106  }  }
1107    
1108  BuiltInIntArrayVariable::BuiltInIntArrayVariable(const String& name, VMInt8Array* array)  RealArrayVariable::RealArrayVariable(ParserContext* ctx, vmint size) :
1109      : IntArrayVariable(NULL, false), name(name), array(array)      Variable({
1110            .ctx = ctx,
1111            .isPolyphonic = false,
1112            .isConst = false,
1113            .elements = 0,
1114            .memPos = 0,
1115            .unitFactorMemPos = 0,
1116            .unitType = VM_NO_UNIT,
1117            .isFinal = false,
1118        })
1119    {
1120        values.resize(size);
1121        memset(&values[0], 0, size * sizeof(vmfloat));
1122    
1123        unitFactors.resize(size);
1124        for (size_t i = 0; i < size; ++i)
1125            unitFactors[i] = VM_NO_FACTOR;
1126    }
1127    
1128    RealArrayVariable::RealArrayVariable(ParserContext* ctx, vmint size,
1129                                         ArgsRef values, bool _bConst) :
1130        Variable({
1131            .ctx = ctx,
1132            .isPolyphonic = false,
1133            .isConst = _bConst,
1134            .elements = 0,
1135            .memPos = 0,
1136            .unitFactorMemPos = 0,
1137            .unitType = VM_NO_UNIT,
1138            .isFinal = false,
1139        })
1140    {
1141        this->values.resize(size);
1142        this->unitFactors.resize(size);
1143        for (vmint i = 0; i < values->argsCount(); ++i) {
1144            VMRealExpr* expr = dynamic_cast<VMRealExpr*>(values->arg(i));
1145            if (expr) {
1146                this->values[i] = expr->evalReal();
1147                this->unitFactors[i] = expr->unitFactor();
1148            } else {
1149                this->values[i] = (vmfloat) 0;
1150                this->unitFactors[i] = VM_NO_FACTOR;
1151            }
1152        }
1153        for (vmint i = values->argsCount(); i < size; ++i) {
1154            this->values[i] = (vmfloat) 0;
1155            this->unitFactors[i] = VM_NO_FACTOR;
1156        }
1157    }
1158    
1159    RealArrayVariable::RealArrayVariable(ParserContext* ctx, bool bConst) :
1160        Variable({
1161            .ctx = ctx,
1162            .isPolyphonic = false,
1163            .isConst = bConst,
1164            .elements = 0,
1165            .memPos = 0,
1166            .unitFactorMemPos = 0,
1167            .unitType = VM_NO_UNIT,
1168            .isFinal = false,
1169        })
1170  {  {
1171  }  }
1172    
1173  int BuiltInIntArrayVariable::evalIntElement(uint i) {  vmfloat RealArrayVariable::evalRealElement(vmuint i) {
1174        if (i >= values.size()) return 0;
1175        return values[i];
1176    }
1177    
1178    void RealArrayVariable::assignRealElement(vmuint i, vmfloat value) {
1179        if (i >= values.size()) return;
1180        values[i] = value;
1181    }
1182    
1183    vmfloat RealArrayVariable::unitFactorOfElement(vmuint i) const {
1184        if (i >= unitFactors.size()) return VM_NO_FACTOR;
1185        return unitFactors[i];
1186    }
1187    
1188    void RealArrayVariable::assignElementUnitFactor(vmuint i, vmfloat factor) {
1189        if (i >= unitFactors.size()) return;
1190        unitFactors[i] = factor;
1191    }
1192    
1193    void RealArrayVariable::dump(int level) {
1194        printIndents(level);
1195        printf("RealArray(");
1196        for (vmint i = 0; i < values.size(); ++i) {
1197            if (i % 12 == 0) {
1198                printf("\n");
1199                printIndents(level+1);
1200            }
1201            printf("%f, ", values[i]);
1202        }
1203        printIndents(level);
1204        printf(")\n");
1205    }
1206    
1207    BuiltInIntArrayVariable::BuiltInIntArrayVariable(const String& name,
1208                                                     VMInt8Array* array) :
1209        IntArrayVariable(NULL, false),
1210        name(name), array(array)
1211    {
1212    }
1213    
1214    vmint BuiltInIntArrayVariable::evalIntElement(vmuint i) {
1215      return i >= array->size ? 0 : array->data[i];      return i >= array->size ? 0 : array->data[i];
1216  }  }
1217    
1218  void BuiltInIntArrayVariable::assignIntElement(uint i, int value) {  void BuiltInIntArrayVariable::assignIntElement(vmuint i, vmint value) {
1219      if (i >= array->size) return;      if (i >= array->size) return;
1220      array->data[i] = value;      array->data[i] = value;
1221  }  }
# Line 503  void BuiltInIntArrayVariable::dump(int l Line 1225  void BuiltInIntArrayVariable::dump(int l
1225      printf("Built-In Int Array Variable '%s'\n", name.c_str());      printf("Built-In Int Array Variable '%s'\n", name.c_str());
1226  }  }
1227    
1228  IntArrayElement::IntArrayElement(IntArrayVariableRef array, IntExprRef arrayIndex)  IntArrayElement::IntArrayElement(IntArrayExprRef array, IntExprRef arrayIndex) :
1229      : IntVariable(NULL, false, false, 0), array(array), index(arrayIndex)      IntVariable({
1230  {              .ctx = NULL,
1231            .isPolyphonic = (array) ? array->isPolyphonic() : false,
1232            .isConst = (array) ? array->isConstExpr() : false,
1233            .elements = 0,
1234            .memPos = 0,
1235            .unitFactorMemPos = 0,
1236            .unitType = VM_NO_UNIT,
1237            .isFinal = false,
1238        }),
1239        Unit(VM_NO_UNIT),
1240        array(array), index(arrayIndex), currentIndex(-1)
1241    {
1242  }  }
1243    
1244  void IntArrayElement::assign(Expression* expr) {  void IntArrayElement::assign(Expression* expr) {
1245      IntExpr* valueExpr = dynamic_cast<IntExpr*>(expr);      IntExpr* valueExpr = dynamic_cast<IntExpr*>(expr);
1246      if (!valueExpr) return;      if (!valueExpr) return;
1247      int value = valueExpr->evalInt();      vmint value = valueExpr->evalInt();
1248        vmfloat unitFactor = valueExpr->unitFactor();
1249    
1250      if (!index) return;      if (!index) return;
1251      int idx = index->evalInt();      vmint idx = currentIndex = index->evalInt();
1252      if (idx < 0 || idx >= array->arraySize()) return;      if (idx < 0 || idx >= array->arraySize()) return;
1253    
1254      array->assignIntElement(idx, value);      array->assignIntElement(idx, value);
1255        array->assignElementUnitFactor(idx, unitFactor);
1256  }  }
1257    
1258  int IntArrayElement::evalInt() {  vmint IntArrayElement::evalInt() {
1259      if (!index) return 0;      if (!index) return 0;
1260      int idx = index->evalInt();      vmint idx = currentIndex = index->evalInt();
1261      if (idx < 0 || idx >= array->arraySize()) return 0;      if (idx < 0 || idx >= array->arraySize()) return 0;
1262    
1263      return array->evalIntElement(idx);      return array->evalIntElement(idx);
1264  }  }
1265    
1266    vmfloat IntArrayElement::unitFactor() const {
1267        if (!index) return VM_NO_FACTOR;
1268        vmint idx = currentIndex;
1269        if (idx < 0 || idx >= array->arraySize()) return 0;
1270    
1271        return array->unitFactorOfElement(idx);
1272    }
1273    
1274  void IntArrayElement::dump(int level) {  void IntArrayElement::dump(int level) {
1275      printIndents(level);      printIndents(level);
1276      printf("IntArrayElement\n");      printf("IntArrayElement\n");
1277  }  }
1278    
1279  StringVariable::StringVariable(ParserContext* ctx)  RealArrayElement::RealArrayElement(RealArrayExprRef array, IntExprRef arrayIndex) :
1280      : Variable(ctx,ctx->globalStrVarCount++,false)      RealVariable({
1281            .ctx = NULL,
1282            .isPolyphonic = (array) ? array->isPolyphonic() : false,
1283            .isConst = (array) ? array->isConstExpr() : false,
1284            .elements = 0,
1285            .memPos = 0,
1286            .unitFactorMemPos = 0,
1287            .unitType = VM_NO_UNIT,
1288            .isFinal = false,
1289        }),
1290        Unit(VM_NO_UNIT),
1291        array(array), index(arrayIndex), currentIndex(-1)
1292    {
1293    }
1294    
1295    void RealArrayElement::assign(Expression* expr) {
1296        RealExpr* valueExpr = dynamic_cast<RealExpr*>(expr);
1297        if (!valueExpr) return;
1298        vmfloat value = valueExpr->evalReal();
1299        vmfloat unitFactor = valueExpr->unitFactor();
1300    
1301        if (!index) return;
1302        vmint idx = currentIndex = index->evalInt();
1303        if (idx < 0 || idx >= array->arraySize()) return;
1304    
1305        array->assignRealElement(idx, value);
1306        array->assignElementUnitFactor(idx, unitFactor);
1307    }
1308    
1309    vmfloat RealArrayElement::evalReal() {
1310        if (!index) return 0;
1311        vmint idx = currentIndex = index->evalInt();
1312        if (idx < 0 || idx >= array->arraySize()) return 0;
1313    
1314        return array->evalRealElement(idx);
1315    }
1316    
1317    vmfloat RealArrayElement::unitFactor() const {
1318        if (!index) return VM_NO_FACTOR;
1319        vmint idx = currentIndex;
1320        if (idx < 0 || idx >= array->arraySize()) return 0;
1321    
1322        return array->unitFactorOfElement(idx);
1323    }
1324    
1325    void RealArrayElement::dump(int level) {
1326        printIndents(level);
1327        printf("RealArrayElement\n");
1328    }
1329    
1330    StringVariable::StringVariable(ParserContext* ctx) :
1331        Variable({
1332            .ctx = ctx,
1333            .elements = 1,
1334            .memPos = ctx->globalStrVarCount++
1335        })
1336  {  {
1337  }  }
1338    
1339  StringVariable::StringVariable(ParserContext* ctx, bool bConst)  StringVariable::StringVariable(ParserContext* ctx, bool bConst) :
1340      : Variable(ctx,0,bConst)      Variable({
1341            .ctx = ctx,
1342            .isConst = bConst,
1343            .memPos = 0,
1344        })
1345  {  {
1346  }  }
1347    
# Line 555  String StringVariable::evalStr() { Line 1357  String StringVariable::evalStr() {
1357    
1358  void StringVariable::dump(int level) {  void StringVariable::dump(int level) {
1359      printIndents(level);      printIndents(level);
1360      printf("StringVariable memPos=%d\n", memPos);      printf("StringVariable memPos=%" PRId64 "\n", (int64_t)memPos);
1361  }  }
1362    
1363  ConstStringVariable::ConstStringVariable(ParserContext* ctx, String _value)  ConstStringVariable::ConstStringVariable(ParserContext* ctx, String _value)
# Line 578  void ConstStringVariable::dump(int level Line 1380  void ConstStringVariable::dump(int level
1380      printf("ConstStringVariable val='%s'\n", value.c_str());      printf("ConstStringVariable val='%s'\n", value.c_str());
1381  }  }
1382    
1383    bool NumberBinaryOp::isFinal() const {
1384        NumberExprRef l = (NumberExprRef) lhs;
1385        NumberExprRef r = (NumberExprRef) rhs;
1386        return l->isFinal() || r->isFinal();
1387    }
1388    
1389    ExprType_t VaritypeScalarBinaryOp::exprType() const {
1390        return (lhs->exprType() == REAL_EXPR || rhs->exprType() == REAL_EXPR) ? REAL_EXPR : INT_EXPR;
1391    }
1392    
1393    String VaritypeScalarBinaryOp::evalCastToStr() {
1394        return (exprType() == REAL_EXPR) ?
1395            RealExpr::evalCastToStr() : IntExpr::evalCastToStr();
1396    }
1397    
1398  void If::dump(int level) {  void If::dump(int level) {
1399      printIndents(level);      printIndents(level);
1400      if (ifStatements && elseStatements)      if (ifStatements && elseStatements)
# Line 588  void If::dump(int level) { Line 1405  void If::dump(int level) {
1405          printf("if [INVALID]\n");          printf("if [INVALID]\n");
1406  }  }
1407    
1408  int If::evalBranch() {  vmint If::evalBranch() {
1409      if (condition->evalInt()) return 0;      if (condition->evalInt()) return 0;
1410      if (elseStatements) return 1;      if (elseStatements) return 1;
1411      return -1;      return -1;
1412  }  }
1413    
1414  Statements* If::branch(uint i) const {  Statements* If::branch(vmuint i) const {
1415      if (i == 0) return (Statements*) &*ifStatements;      if (i == 0) return (Statements*) &*ifStatements;
1416      if (i == 1) return (elseStatements) ? (Statements*) &*elseStatements : NULL;      if (i == 1) return (elseStatements) ? (Statements*) &*elseStatements : NULL;
1417      return NULL;      return NULL;
# Line 610  void SelectCase::dump(int level) { Line 1427  void SelectCase::dump(int level) {
1427      printIndents(level);      printIndents(level);
1428      if (select)      if (select)
1429          if (select->isConstExpr())          if (select->isConstExpr())
1430              printf("Case select %d\n", select->evalInt());              printf("Case select %" PRId64 "\n", (int64_t)select->evalInt());
1431          else          else
1432              printf("Case select [runtime expr]\n");              printf("Case select [runtime expr]\n");
1433      else      else
1434          printf("Case select NULL\n");          printf("Case select NULL\n");
1435      for (int i = 0; i < branches.size(); ++i) {      for (vmint i = 0; i < branches.size(); ++i) {
1436          printIndents(level+1);          printIndents(level+1);
1437          CaseBranch& branch = branches[i];          CaseBranch& branch = branches[i];
1438          if (branch.from && branch.to)          if (branch.from && branch.to)
1439              if (branch.from->isConstExpr() && branch.to->isConstExpr())              if (branch.from->isConstExpr() && branch.to->isConstExpr())
1440                  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());
1441              else if (branch.from->isConstExpr() && !branch.to->isConstExpr())              else if (branch.from->isConstExpr() && !branch.to->isConstExpr())
1442                  printf("case %d to [runtime expr]\n", branch.from->evalInt());                  printf("case %" PRId64 " to [runtime expr]\n", (int64_t)branch.from->evalInt());
1443              else if (!branch.from->isConstExpr() && branch.to->isConstExpr())              else if (!branch.from->isConstExpr() && branch.to->isConstExpr())
1444                  printf("case [runtime expr] to %d\n", branch.to->evalInt());                  printf("case [runtime expr] to %" PRId64 "\n", (int64_t)branch.to->evalInt());
1445              else              else
1446                  printf("case [runtime expr] to [runtime expr]\n");                  printf("case [runtime expr] to [runtime expr]\n");
1447          else if (branch.from)          else if (branch.from)
1448              if (branch.from->isConstExpr())              if (branch.from->isConstExpr())
1449                  printf("case %d\n", branch.from->evalInt());                  printf("case %" PRId64 "\n", (int64_t)branch.from->evalInt());
1450              else              else
1451                  printf("case [runtime expr]\n");                  printf("case [runtime expr]\n");
1452          else          else
# Line 637  void SelectCase::dump(int level) { Line 1454  void SelectCase::dump(int level) {
1454      }      }
1455  }  }
1456    
1457  int SelectCase::evalBranch() {  vmint SelectCase::evalBranch() {
1458      int value = select->evalInt();      vmint value = select->evalInt();
1459      for (int i = 0; i < branches.size(); ++i) {      for (vmint i = 0; i < branches.size(); ++i) {
1460          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" ...
1461              if (branches.at(i).from->evalInt() <= value &&              if (branches.at(i).from->evalInt() <= value &&
1462                  branches.at(i).to->evalInt() >= value) return i;                  branches.at(i).to->evalInt() >= value) return i;
# Line 650  int SelectCase::evalBranch() { Line 1467  int SelectCase::evalBranch() {
1467      return -1;      return -1;
1468  }  }
1469    
1470  Statements* SelectCase::branch(uint i) const {  Statements* SelectCase::branch(vmuint i) const {
1471      if (i < branches.size())      if (i < branches.size())
1472          return const_cast<Statements*>( &*branches[i].statements );          return const_cast<Statements*>( &*branches[i].statements );
1473      return NULL;      return NULL;
# Line 658  Statements* SelectCase::branch(uint i) c Line 1475  Statements* SelectCase::branch(uint i) c
1475    
1476  bool SelectCase::isPolyphonic() const {  bool SelectCase::isPolyphonic() const {
1477      if (select->isPolyphonic()) return true;      if (select->isPolyphonic()) return true;
1478      for (int i = 0; i < branches.size(); ++i)      for (vmint i = 0; i < branches.size(); ++i)
1479          if (branches[i].statements->isPolyphonic())          if (branches[i].statements->isPolyphonic())
1480              return true;              return true;
1481      return false;      return false;
1482  }  }
1483    
 // 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);  
 // }  
   
1484  void While::dump(int level) {  void While::dump(int level) {
1485      printIndents(level);      printIndents(level);
1486      if (m_condition)      if (m_condition)
1487          if (m_condition->isConstExpr())          if (m_condition->isConstExpr())
1488              printf("while (%d) {\n", m_condition->evalInt());              printf("while (%" PRId64 ") {\n", (int64_t)m_condition->evalInt());
1489          else          else
1490              printf("while ([runtime expr]) {\n");              printf("while ([runtime expr]) {\n");
1491      else      else
# Line 706  bool While::evalLoopStartCondition() { Line 1504  bool While::evalLoopStartCondition() {
1504      return m_condition->evalInt();      return m_condition->evalInt();
1505  }  }
1506    
1507    void SyncBlock::dump(int level) {
1508        printIndents(level);
1509        printf("sync {\n");
1510        m_statements->dump(level+1);
1511        printIndents(level);
1512        printf("}\n");
1513    }
1514    
1515    Statements* SyncBlock::statements() const {
1516        return (m_statements) ? const_cast<Statements*>( &*m_statements ) : NULL;
1517    }
1518    
1519    String Neg::evalCastToStr() {
1520        return expr->evalCastToStr();
1521    }
1522    
1523  void Neg::dump(int level) {  void Neg::dump(int level) {
1524      printIndents(level);      printIndents(level);
1525      printf("Negative Expr\n");      printf("Negative Expr\n");
# Line 739  bool ConcatString::isConstExpr() const { Line 1553  bool ConcatString::isConstExpr() const {
1553      return lhs->isConstExpr() && rhs->isConstExpr();      return lhs->isConstExpr() && rhs->isConstExpr();
1554  }  }
1555    
1556  int Relation::evalInt() {  Relation::Relation(ExpressionRef lhs, Type type, ExpressionRef rhs) :
1557        Unit(VM_NO_UNIT),
1558        lhs(lhs), rhs(rhs), type(type)
1559    {
1560    }
1561    
1562    // Equal / unequal comparison of real numbers in NKSP scripts:
1563    //
1564    // Unlike system level languages like C/C++ we are less conservative about
1565    // comparing floating point numbers for 'equalness' or 'unequalness' in NKSP
1566    // scripts. Due to the musical context of the NKSP language we automatically
1567    // take the (to be) expected floating point tolerances into account when
1568    // comparing two floating point numbers with each other, however only for '='
1569    // and '#' operators. The '<=' and '>=' still use conservative low level
1570    // floating point comparison for not breaking their transitivity feature.
1571    
1572    template<typename T_LHS, typename T_RHS>
1573    struct RelComparer {
1574        static inline bool isEqual(T_LHS a, T_RHS b) { // for int comparison ('3 = 3')
1575            return a == b;
1576        }
1577        static inline bool isUnequal(T_LHS a, T_RHS b) { // for int comparison ('3 # 3')
1578            return a != b;
1579        }
1580    };
1581    
1582    template<>
1583    struct RelComparer<float,float> {
1584        static inline bool isEqual(float a, float b) { // for real number comparison ('3.1 = 3.1')
1585            return RTMath::fEqual32(a, b);
1586        }
1587        static inline bool isUnequal(float a, float b) { // for real number comparison ('3.1 # 3.1')
1588            return !RTMath::fEqual32(a, b);
1589        }
1590    };
1591    
1592    template<>
1593    struct RelComparer<double,double> {
1594        static inline bool isEqual(double a, double b) { // for future purpose
1595            return RTMath::fEqual64(a, b);
1596        }
1597        static inline bool isUnqqual(double a, double b) { // for future purpose
1598            return !RTMath::fEqual64(a, b);
1599        }
1600    };
1601    
1602    template<class T_LHS, class T_RHS>
1603    inline vmint _evalRelation(Relation::Type type, T_LHS lhs, T_RHS rhs) {
1604      switch (type) {      switch (type) {
1605          case LESS_THAN:          case Relation::LESS_THAN:
1606              return lhs->evalInt() < rhs->evalInt();              return lhs < rhs;
1607          case GREATER_THAN:          case Relation::GREATER_THAN:
1608              return lhs->evalInt() > rhs->evalInt();              return lhs > rhs;
1609          case LESS_OR_EQUAL:          case Relation::LESS_OR_EQUAL:
1610              return lhs->evalInt() <= rhs->evalInt();              return lhs <= rhs;
1611          case GREATER_OR_EQUAL:          case Relation::GREATER_OR_EQUAL:
1612              return lhs->evalInt() >= rhs->evalInt();              return lhs >= rhs;
1613          case EQUAL:          case Relation::EQUAL:
1614              if (lhs->exprType() == STRING_EXPR || rhs->exprType() == STRING_EXPR)              return RelComparer<typeof(lhs),typeof(rhs)>::isEqual(lhs, rhs);
1615            case Relation::NOT_EQUAL:
1616                return RelComparer<typeof(lhs),typeof(rhs)>::isUnequal(lhs, rhs);
1617        }
1618        return 0;
1619    }
1620    
1621    template<class T_LVALUE, class T_RVALUE, class T_LEXPR, class T_REXPR>
1622    inline vmint _evalRealRelation(Relation::Type type,
1623                                   T_LVALUE lvalue, T_RVALUE rvalue,
1624                                   T_LEXPR* pLHS, T_REXPR* pRHS)
1625    {
1626        if (pLHS->unitFactor() == pRHS->unitFactor())
1627            return _evalRelation(type, lvalue, rvalue);
1628        if (pLHS->unitFactor() < pRHS->unitFactor())
1629            return _evalRelation(type, lvalue, Unit::convRealToUnitFactor(rvalue, pRHS, pLHS));
1630        else
1631            return _evalRelation(type, Unit::convRealToUnitFactor(lvalue, pLHS, pRHS), rvalue);
1632    }
1633    
1634    template<class T_LEXPR, class T_REXPR>
1635    inline vmint _evalIntRelation(Relation::Type type,
1636                                  vmint lvalue, vmint rvalue,
1637                                  T_LEXPR* pLHS, T_REXPR* pRHS)
1638    {
1639        if (pLHS->unitFactor() == pRHS->unitFactor())
1640            return _evalRelation(type, lvalue, rvalue);
1641        if (pLHS->unitFactor() < pRHS->unitFactor())
1642            return _evalRelation(type, lvalue, Unit::convIntToUnitFactor(rvalue, pRHS, pLHS));
1643        else
1644            return _evalRelation(type, Unit::convIntToUnitFactor(lvalue, pLHS, pRHS), rvalue);
1645    }
1646    
1647    vmint Relation::evalInt() {
1648        const ExprType_t lType = lhs->exprType();
1649        const ExprType_t rType = rhs->exprType();
1650        if (lType == STRING_EXPR || rType == STRING_EXPR) {
1651            switch (type) {
1652                case EQUAL:
1653                  return lhs->evalCastToStr() == rhs->evalCastToStr();                  return lhs->evalCastToStr() == rhs->evalCastToStr();
1654              else              case NOT_EQUAL:
                 return lhs->evalInt() == rhs->evalInt();  
         case NOT_EQUAL:  
             if (lhs->exprType() == STRING_EXPR || rhs->exprType() == STRING_EXPR)  
1655                  return lhs->evalCastToStr() != rhs->evalCastToStr();                  return lhs->evalCastToStr() != rhs->evalCastToStr();
1656              else              default:
1657                  return lhs->evalInt() != rhs->evalInt();                  return 0;
1658            }
1659        } else if (lType == REAL_EXPR && rType == REAL_EXPR) {
1660            vmfloat lvalue = lhs->asReal()->evalReal();
1661            vmfloat rvalue = rhs->asReal()->evalReal();
1662            return _evalRealRelation(
1663                type, lvalue, rvalue, lhs->asReal(), rhs->asReal()
1664            );
1665        } else if (lType == REAL_EXPR && rType == INT_EXPR) {
1666            vmfloat lvalue = lhs->asReal()->evalReal();
1667            vmint rvalue = rhs->asInt()->evalInt();
1668            return _evalRealRelation(
1669                type, lvalue, rvalue, lhs->asReal(), rhs->asInt()
1670            );
1671        } else if (lType == INT_EXPR && rType == REAL_EXPR) {
1672            vmint lvalue = lhs->asInt()->evalInt();
1673            vmfloat rvalue = rhs->asReal()->evalReal();
1674            return _evalRealRelation(
1675                type, lvalue, rvalue, lhs->asInt(), rhs->asReal()
1676            );
1677        } else {
1678            vmint lvalue = lhs->asInt()->evalInt();
1679            vmint rvalue = rhs->asInt()->evalInt();
1680            return _evalIntRelation(
1681                type, lvalue, rvalue, lhs->asInt(), rhs->asInt()
1682            );
1683      }      }
     return 0;  
1684  }  }
1685    
1686  void Relation::dump(int level) {  void Relation::dump(int level) {
# Line 797  bool Relation::isConstExpr() const { Line 1717  bool Relation::isConstExpr() const {
1717      return lhs->isConstExpr() && rhs->isConstExpr();      return lhs->isConstExpr() && rhs->isConstExpr();
1718  }  }
1719    
1720  int Or::evalInt() {  vmint Or::evalInt() {
1721      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1722      if (pLHS->evalInt()) return 1;      if (pLHS->evalInt()) return 1;
1723      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
1724      return (pRHS->evalInt()) ? 1 : 0;      return (pRHS->evalInt()) ? 1 : 0;
1725  }  }
1726    
# Line 815  void Or::dump(int level) { Line 1735  void Or::dump(int level) {
1735      printf(")\n");      printf(")\n");
1736  }  }
1737    
1738  int BitwiseOr::evalInt() {  vmint BitwiseOr::evalInt() {
1739      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1740      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
1741      return pLHS->evalInt() | pRHS->evalInt();      return pLHS->evalInt() | pRHS->evalInt();
# Line 832  void BitwiseOr::dump(int level) { Line 1752  void BitwiseOr::dump(int level) {
1752      printf(")\n");      printf(")\n");
1753  }  }
1754    
1755  int And::evalInt() {  vmint And::evalInt() {
1756      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1757      if (!pLHS->evalInt()) return 0;      if (!pLHS->evalInt()) return 0;
1758      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
# Line 850  void And::dump(int level) { Line 1770  void And::dump(int level) {
1770      printf(")\n");      printf(")\n");
1771  }  }
1772    
1773  int BitwiseAnd::evalInt() {  vmint BitwiseAnd::evalInt() {
1774      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);      IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1775      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);      IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
1776      return pLHS->evalInt() & pRHS->evalInt();      return pLHS->evalInt() & pRHS->evalInt();
# Line 883  void BitwiseNot::dump(int level) { Line 1803  void BitwiseNot::dump(int level) {
1803      printf(")\n");      printf(")\n");
1804  }  }
1805    
1806    String Final::evalCastToStr() {
1807        if (exprType() == REAL_EXPR)
1808            return ToString(evalReal());
1809        else
1810            return ToString(evalInt());
1811    }
1812    
1813    void Final::dump(int level) {
1814        printIndents(level);
1815        printf("Final(\n");
1816        expr->dump(level+1);
1817        printIndents(level);
1818        printf(")\n");
1819    }
1820    
1821  StatementsRef ParserContext::userFunctionByName(const String& name) {  StatementsRef ParserContext::userFunctionByName(const String& name) {
1822      if (!userFnTable.count(name)) {      if (!userFnTable.count(name)) {
1823          return StatementsRef();          return StatementsRef();
# Line 911  IntVariableRef ParserContext::globalIntV Line 1846  IntVariableRef ParserContext::globalIntV
1846      return globalVar(name);      return globalVar(name);
1847  }  }
1848    
1849    RealVariableRef ParserContext::globalRealVar(const String& name) {
1850        return globalVar(name);
1851    }
1852    
1853  StringVariableRef ParserContext::globalStrVar(const String& name) {  StringVariableRef ParserContext::globalStrVar(const String& name) {
1854      return globalVar(name);      return globalVar(name);
1855  }  }
# Line 921  ParserContext::~ParserContext() { Line 1860  ParserContext::~ParserContext() {
1860          delete globalIntMemory;          delete globalIntMemory;
1861          globalIntMemory = NULL;          globalIntMemory = NULL;
1862      }      }
1863        if (globalRealMemory) {
1864            delete globalRealMemory;
1865            globalRealMemory = NULL;
1866        }
1867  }  }
1868    
1869  void ParserContext::addErr(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt) {  void ParserContext::addErr(int firstLine, int lastLine, int firstColumn,
1870                               int lastColumn, int firstByte, int lengthBytes,
1871                               const char* txt)
1872    {
1873      ParserIssue e;      ParserIssue e;
1874      e.type = PARSER_ERROR;      e.type = PARSER_ERROR;
1875      e.txt = txt;      e.txt = txt;
# Line 931  void ParserContext::addErr(int firstLine Line 1877  void ParserContext::addErr(int firstLine
1877      e.lastLine = lastLine;      e.lastLine = lastLine;
1878      e.firstColumn = firstColumn;      e.firstColumn = firstColumn;
1879      e.lastColumn = lastColumn;      e.lastColumn = lastColumn;
1880        e.firstByte = firstByte;
1881        e.lengthBytes = lengthBytes;
1882      vErrors.push_back(e);      vErrors.push_back(e);
1883      vIssues.push_back(e);      vIssues.push_back(e);
1884  }  }
1885    
1886  void ParserContext::addWrn(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt) {  void ParserContext::addWrn(int firstLine, int lastLine, int firstColumn,
1887                               int lastColumn, int firstByte, int lengthBytes,
1888                               const char* txt)
1889    {
1890      ParserIssue w;      ParserIssue w;
1891      w.type = PARSER_WARNING;      w.type = PARSER_WARNING;
1892      w.txt = txt;      w.txt = txt;
# Line 943  void ParserContext::addWrn(int firstLine Line 1894  void ParserContext::addWrn(int firstLine
1894      w.lastLine = lastLine;      w.lastLine = lastLine;
1895      w.firstColumn = firstColumn;      w.firstColumn = firstColumn;
1896      w.lastColumn = lastColumn;      w.lastColumn = lastColumn;
1897        w.firstByte = firstByte;
1898        w.lengthBytes = lengthBytes;
1899      vWarnings.push_back(w);      vWarnings.push_back(w);
1900      vIssues.push_back(w);      vIssues.push_back(w);
1901  }  }
1902    
1903    void ParserContext::addPreprocessorComment(int firstLine, int lastLine,
1904                                               int firstColumn, int lastColumn,
1905                                               int firstByte, int lengthBytes)
1906    {
1907        CodeBlock block;
1908        block.firstLine = firstLine;
1909        block.lastLine = lastLine;
1910        block.firstColumn = firstColumn;
1911        block.lastColumn = lastColumn;
1912        block.firstByte = firstByte;
1913        block.lengthBytes = lengthBytes;
1914        vPreprocessorComments.push_back(block);
1915    }
1916    
1917  bool ParserContext::setPreprocessorCondition(const char* name) {  bool ParserContext::setPreprocessorCondition(const char* name) {
1918      if (builtinPreprocessorConditions.count(name)) return false;      if (builtinPreprocessorConditions.count(name)) return false;
1919      if (userPreprocessorConditions.count(name)) return false;      if (userPreprocessorConditions.count(name)) return false;
# Line 978  std::vector<ParserIssue> ParserContext:: Line 1945  std::vector<ParserIssue> ParserContext::
1945      return vWarnings;      return vWarnings;
1946  }  }
1947    
1948    std::vector<CodeBlock> ParserContext::preprocessorComments() const {
1949        return vPreprocessorComments;
1950    }
1951    
1952  VMEventHandler* ParserContext::eventHandler(uint index) {  VMEventHandler* ParserContext::eventHandler(uint index) {
1953      if (!handlers) return NULL;      if (!handlers) return NULL;
1954      return handlers->eventHandler(index);      return handlers->eventHandler(index);
# Line 988  VMEventHandler* ParserContext::eventHand Line 1959  VMEventHandler* ParserContext::eventHand
1959      return handlers->eventHandlerByName(name);      return handlers->eventHandlerByName(name);
1960  }  }
1961    
1962  void ParserContext::registerBuiltInConstIntVariables(const std::map<String,int>& vars) {  void ParserContext::registerBuiltInConstIntVariables(const std::map<String,vmint>& vars) {
1963      for (std::map<String,int>::const_iterator it = vars.begin();      for (std::map<String,vmint>::const_iterator it = vars.begin();
1964           it != vars.end(); ++it)           it != vars.end(); ++it)
1965      {      {
1966          ConstIntVariableRef ref = new ConstIntVariable(it->second);          ConstIntVariableRef ref = new ConstIntVariable({
1967                .value = it->second
1968            });
1969          vartable[it->first] = ref;          vartable[it->first] = ref;
1970      }      }
1971  }  }
1972    
1973  void ParserContext::registerBuiltInIntVariables(const std::map<String,VMIntRelPtr*>& vars) {  void ParserContext::registerBuiltInConstRealVariables(const std::map<String,vmfloat>& vars) {
1974      for (std::map<String,VMIntRelPtr*>::const_iterator it = vars.begin();      for (std::map<String,vmfloat>::const_iterator it = vars.begin();
1975             it != vars.end(); ++it)
1976        {
1977            ConstRealVariableRef ref = new ConstRealVariable({
1978                .value = it->second
1979            });
1980            vartable[it->first] = ref;
1981        }
1982    }
1983    
1984    void ParserContext::registerBuiltInIntVariables(const std::map<String,VMIntPtr*>& vars) {
1985        for (std::map<String,VMIntPtr*>::const_iterator it = vars.begin();
1986           it != vars.end(); ++it)           it != vars.end(); ++it)
1987      {      {
1988          BuiltInIntVariableRef ref = new BuiltInIntVariable(it->first, it->second);          BuiltInIntVariableRef ref = new BuiltInIntVariable(it->first, it->second);
# Line 1024  void ParserContext::registerBuiltInDynVa Line 2008  void ParserContext::registerBuiltInDynVa
2008      }      }
2009  }  }
2010    
2011    ExecContext::ExecContext() :
2012        status(VM_EXEC_NOT_RUNNING), flags(STMT_SUCCESS), stackFrame(-1),
2013        suspendMicroseconds(0), instructionsCount(0)
2014    {
2015        exitRes.value = NULL;
2016    }
2017    
2018    void ExecContext::forkTo(VMExecContext* ectx) const {
2019        ExecContext* child = dynamic_cast<ExecContext*>(ectx);
2020    
2021        child->polyphonicIntMemory.copyFlatFrom(polyphonicIntMemory);
2022        child->polyphonicRealMemory.copyFlatFrom(polyphonicRealMemory);
2023        child->status = VM_EXEC_SUSPENDED;
2024        child->flags = STMT_SUCCESS;
2025        child->stack.copyFlatFrom(stack);
2026        child->stackFrame = stackFrame;
2027        child->suspendMicroseconds = 0;
2028        child->instructionsCount = 0;
2029    }
2030    
2031  } // namespace LinuxSampler  } // namespace LinuxSampler

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

  ViewVC Help
Powered by ViewVC