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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3581 - (hide annotations) (download)
Fri Aug 30 11:40:25 2019 UTC (6 months, 4 weeks ago) by schoenebeck
File size: 55453 byte(s)
NKSP: Allow more wider support of standard measuring units & 'final'ness.

* Raised compiler requirement to be C++14 compliant (due to severe
  restrictions regarding C-style aggregate initializer lists in C++11
  which are now massively used throughout the code base).

* NKSP VM API: Allow units and 'final'ness to be returned as result from
  built-in functions (added methods VMFunction::returnUnitType() and
  VMFunction::returnsFinal() for that purpose which must be implemented by
  built-in function implementations).

* NKSP language: Allow metric unit prefixes of numeric scalar and array
  variables to be changed freely at runtime (unlike unit types like Hz etc.
  which are still sticky parse-time features of variables which cannot be
  changed at runtime for the intentional sake of determinism).

* NKSP language: 'final' values are prohibited for array variables for now
  (attempt causes a parsers error).

* NKSP language: expressions with unit types (e.g. Hz) are prohibited for
  conditions of runtime control structures like if(), while(), select()
  (attempt causes a parser error).

* NKSP VM API: Allow built-in functions to perform their own, individual
  parse time checks of arguments going to be passed to the function at
  runtime (added method VMFunction::checkArgs() for that purpose).

* NKSP language: raise parser warning if only one operand of binary
  operators (like logical 'or' comparison) contain a 'final' value (because
  it would always yield in a 'final' result in such cases).

* NKSP language: Allow comparison (=, #, <, >, <=, >=) of values with
  different metric unit prefixes, which will behave as expected (e.g.
  result of expression '1000us < 2ms' is true).

* NKSP language: Allow adding values with different metric unit prefixes
  (e.g. result of expression '100Hz + 5kHz' is '5100Hz').

* NKSP language: Allow subtracting values with different metric unit
  prefixes (e.g. result of expression '1ms - 20us' is '980us').

* NKSP language: Allow multiplying with any metric unit prefixes
  (e.g. result of expression '2k * 3ms' is '6s'), however multiplications
  with unit types on both sides (e.g. '2s * 2s') is still prohibited since
  we don't have any considerable practical use for a term like '4s^2'
  (hence any attempt multiplying two unit types still causes parser error).

* NKSP language: Allow dividing by any metric unit prefixes and allow
  division of same unit type on both sides (e.g. expression '8kHz / 1000Hz'
  yields in unit free result '8'). So this is now a way to cast units away
  e.g. for passing the result to other expressions, certain function calls
  or variables which are not accepting any units (or that specific unit).

* NKSP language: integer arrays and real number arrays can now be converted
  to strings (e.g. for dumping their content with message() calls for
  script debugging purposes).

* NKSP language: expressions and variables with units are now correctly
  casted to strings (e.g. with message() calls).

* NKSP language: comparing real numbers for equalness (e.g. '~foo = 3.1') or
  unequalness (e.g. '~foo # 3.1') is now less strict and takes the expected
  floating point tolerances into account.

* NKSP VM API: Added methods VMScalarNumberExpr::evalCastInt() and
  VMScalarNumberExpr::evalCastReal().

* NKSP VM API: Added base class 'VMNumberArrayExpr' for classes
  'VMIntArrayExpr' and 'VMRealArrayExpr'.

* NKSP VM API: replaced all unitPrefix() (parse time) methods by
  unitFactor() (runtime) methods.

* Built-in function "exit()" supports now returning units and 'final'ness
  exclusively for test cases.

* The following built-in functions support now units as well: "abs()",
  "random()", "inc()", "dec()", "in_range()", "min()", "max()",
  "real_to_int()", "int()", "int_to_real()" and "real()".

* Built-in functions "array_equal()", "search()" and "sort()" support now
  real number arrays (correctly) as well.

* Added individual parse time checks of arguments to be passed to built-in
  functions "random()", "inc()", "dec()", "in_range()", "min()", "max()",
  "array_equal()" and "search()" specific for their individual purposes.

* Test cases: Added massive amount of NKSP test cases for standard
  measuring units and 'final' operator usage cases.

* Test cases: Added NKSP test cases for (floating point tolerance aware)
  real number equalness / unequalness comparison.

* Bumped version (2.1.1.svn8).

1 schoenebeck 2581 /*
2 schoenebeck 3551 * Copyright (c) 2014 - 2019 Christian Schoenebeck and Andreas Persson
3 schoenebeck 2581 *
4     * http://www.linuxsampler.org
5     *
6     * This file is part of LinuxSampler and released under the same terms.
7     * See README file for details.
8     */
9    
10     #include <cstdio>
11     #include <string.h>
12     #include "tree.h"
13     #include "../common/global_private.h"
14 schoenebeck 3581 #include "../common/RTMath.h"
15 schoenebeck 2588 #include <assert.h>
16 schoenebeck 2581
17     namespace LinuxSampler {
18    
19     bool isNoOperation(StatementRef statement) {
20 schoenebeck 3311 return statement->statementType() == STMT_NOOP;
21 schoenebeck 2581 }
22    
23     Node::Node() {
24     }
25    
26     Node::~Node() {
27     }
28    
29     void Node::printIndents(int n) {
30     for (int i = 0; i < n; ++i) printf(" ");
31     fflush(stdout);
32     }
33    
34 schoenebeck 3581 vmint Unit::convIntToUnitFactor(vmint iValue, VMUnit* srcUnit, VMUnit* dstUnit) {
35     vmfloat f = (vmfloat) iValue;
36     vmfloat factor = srcUnit->unitFactor() / dstUnit->unitFactor();
37     if (sizeof(vmfloat) == sizeof(float))
38     return llroundf(f * factor);
39     else
40     return llround(f * factor);
41     }
42    
43     vmint Unit::convIntToUnitFactor(vmint iValue, vmfloat srcFactor, vmfloat dstFactor) {
44     vmfloat f = (vmfloat) iValue;
45     vmfloat factor = srcFactor / dstFactor;
46     if (sizeof(vmfloat) == sizeof(float))
47     return llroundf(f * factor);
48     else
49     return llround(f * factor);
50     }
51    
52     vmfloat Unit::convRealToUnitFactor(vmfloat fValue, VMUnit* srcUnit, VMUnit* dstUnit) {
53     vmfloat factor = srcUnit->unitFactor() / dstUnit->unitFactor();
54     return fValue * factor;
55     }
56    
57     vmfloat Unit::convRealToUnitFactor(vmfloat fValue, vmfloat srcFactor, vmfloat dstFactor) {
58     vmfloat factor = srcFactor / dstFactor;
59     return fValue * factor;
60     }
61    
62     vmint IntExpr::evalIntToUnitFactor(vmfloat unitFactor) {
63     vmfloat f = (vmfloat) evalInt();
64     vmfloat factor = this->unitFactor() / unitFactor;
65     if (sizeof(vmfloat) == sizeof(float))
66     return llroundf(f * factor);
67     else
68     return llround(f * factor);
69     }
70    
71     static String _unitFactorToShortStr(vmfloat unitFactor) {
72     const long int tens = lround( log10(unitFactor) );
73     switch (tens) {
74     case 3: return "k"; // kilo = 10^3
75     case 2: return "h"; // hecto = 10^2
76     case 1: return "da"; // deca = 10
77     case 0: return "" ; // -- = 1
78     case -1: return "d"; // deci = 10^-1
79     case -2: return "c"; // centi = 10^-2 (this is also used for tuning "cents")
80     case -3: return "m"; // milli = 10^-3
81     case -4: return "md"; // milli deci = 10^-4
82     case -5: return "mc"; // milli centi = 10^-5 (this is also used for tuning "cents")
83     case -6: return "u"; // micro = 10^-6
84     default: return "*10^" + ToString(tens);
85     }
86     }
87    
88     static String _unitToStr(Unit* unit) {
89     const StdUnit_t type = unit->unitType();
90     String sType;
91     switch (type) {
92     case VM_NO_UNIT: break;
93     case VM_SECOND: sType = "s"; break;
94     case VM_HERTZ: sType = "Hz"; break;
95     case VM_BEL: sType = "B"; break;
96     }
97    
98     String prefix = _unitFactorToShortStr( unit->unitFactor() );
99    
100     return prefix + sType;
101     }
102    
103 schoenebeck 2581 String IntExpr::evalCastToStr() {
104 schoenebeck 3581 return ToString(evalInt()) + _unitToStr(this);
105 schoenebeck 2581 }
106    
107 schoenebeck 3581 vmfloat RealExpr::evalRealToUnitFactor(vmfloat unitFactor) {
108     vmfloat f = evalReal();
109     vmfloat factor = this->unitFactor() / unitFactor;
110     return f * factor;
111     }
112    
113 schoenebeck 3573 String RealExpr::evalCastToStr() {
114 schoenebeck 3581 return ToString(evalReal()) + _unitToStr(this);
115 schoenebeck 3573 }
116    
117 schoenebeck 3293 String IntArrayExpr::evalCastToStr() {
118 schoenebeck 3056 String s = "{";
119 schoenebeck 3557 for (vmint i = 0; i < arraySize(); ++i) {
120     vmint val = evalIntElement(i);
121 schoenebeck 3581 vmfloat factor = unitFactorOfElement(i);
122 schoenebeck 3056 if (i) s += ",";
123 schoenebeck 3581 s += ToString(val) + _unitFactorToShortStr(factor);
124 schoenebeck 3056 }
125     s += "}";
126     return s;
127 schoenebeck 3293 }
128 schoenebeck 3056
129 schoenebeck 3573 String RealArrayExpr::evalCastToStr() {
130     String s = "{";
131     for (vmint i = 0; i < arraySize(); ++i) {
132     vmfloat val = evalRealElement(i);
133 schoenebeck 3581 vmfloat factor = unitFactorOfElement(i);
134 schoenebeck 3573 if (i) s += ",";
135 schoenebeck 3581 s += ToString(val) + _unitFactorToShortStr(factor);
136 schoenebeck 3573 }
137     s += "}";
138     return s;
139     }
140    
141 schoenebeck 3581 IntLiteral::IntLiteral(const IntLitDef& def) :
142     IntExpr(), Unit(def.unitType),
143     value(def.value), unitPrefixFactor(def.unitFactor),
144     finalVal(def.isFinal)
145     {
146 schoenebeck 3561 }
147    
148 schoenebeck 3557 vmint IntLiteral::evalInt() {
149 schoenebeck 2581 return value;
150     }
151    
152     void IntLiteral::dump(int level) {
153     printIndents(level);
154 schoenebeck 3557 printf("IntLiteral %lld\n", value);
155 schoenebeck 2581 }
156    
157 schoenebeck 3581 RealLiteral::RealLiteral(const RealLitDef& def) :
158     RealExpr(), Unit(def.unitType),
159     value(def.value), unitPrefixFactor(def.unitFactor),
160     finalVal(def.isFinal)
161     {
162     }
163    
164 schoenebeck 3573 vmfloat RealLiteral::evalReal() {
165     return value;
166     }
167    
168     void RealLiteral::dump(int level) {
169     printIndents(level);
170     printf("RealLiteral %f\n", value);
171     }
172    
173 schoenebeck 2581 void StringLiteral::dump(int level) {
174     printIndents(level);
175     printf("StringLiteral: '%s'\n", value.c_str());
176     }
177    
178 schoenebeck 3581 Add::Add(ScalarNumberExprRef lhs, ScalarNumberExprRef rhs) :
179     VaritypeScalarBinaryOp(lhs, rhs),
180     Unit(
181     // lhs and rhs are forced to be same unit type at parse time, so either one is fine here
182     (lhs) ? lhs->unitType() : VM_NO_UNIT
183     )
184     {
185     }
186    
187 schoenebeck 3557 vmint Add::evalInt() {
188 schoenebeck 2581 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
189 schoenebeck 3581 IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
190     if (!pLHS || !pRHS) return 0;
191     // eval*() call is required before calling unitFactor(), since the latter does not evaluate expressions!
192     vmint lvalue = pLHS->evalInt();
193     vmint rvalue = pRHS->evalInt();
194     if (pLHS->unitFactor() == pRHS->unitFactor())
195     return lvalue + rvalue;
196     if (pLHS->unitFactor() < pRHS->unitFactor())
197     return lvalue + Unit::convIntToUnitFactor(rvalue, pRHS, pLHS);
198     else
199     return Unit::convIntToUnitFactor(lvalue, pLHS, pRHS) + rvalue;
200 schoenebeck 2581 }
201    
202 schoenebeck 3573 vmfloat Add::evalReal() {
203     RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
204 schoenebeck 3581 RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);
205     if (!pLHS || !pRHS) return 0;
206     // eval*() call is required before calling unitFactor(), since the latter does not evaluate expressions!
207     vmfloat lvalue = pLHS->evalReal();
208     vmfloat rvalue = pRHS->evalReal();
209     if (pLHS->unitFactor() == pRHS->unitFactor())
210     return lvalue + rvalue;
211     if (pLHS->unitFactor() < pRHS->unitFactor())
212     return lvalue + Unit::convRealToUnitFactor(rvalue, pRHS, pLHS);
213     else
214     return Unit::convRealToUnitFactor(lvalue, pLHS, pRHS) + rvalue;
215 schoenebeck 3573 }
216    
217 schoenebeck 3581 vmfloat Add::unitFactor() const {
218     const ScalarNumberExpr* pLHS = dynamic_cast<const ScalarNumberExpr*>(&*lhs);
219     const ScalarNumberExpr* pRHS = dynamic_cast<const ScalarNumberExpr*>(&*rhs);
220     return (pLHS->unitFactor() < pRHS->unitFactor()) ? pLHS->unitFactor() : pRHS->unitFactor();
221     }
222    
223 schoenebeck 2581 void Add::dump(int level) {
224     printIndents(level);
225     printf("Add(\n");
226     lhs->dump(level+1);
227     printIndents(level);
228     printf(",\n");
229     rhs->dump(level+1);
230     printIndents(level);
231     printf(")\n");
232     }
233    
234 schoenebeck 3581 Sub::Sub(ScalarNumberExprRef lhs, ScalarNumberExprRef rhs) :
235     VaritypeScalarBinaryOp(lhs, rhs),
236     Unit(
237     // lhs and rhs are forced to be same unit type at parse time, so either one is fine here
238     (lhs) ? lhs->unitType() : VM_NO_UNIT
239     )
240     {
241     }
242    
243 schoenebeck 3557 vmint Sub::evalInt() {
244 schoenebeck 2581 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
245 schoenebeck 3581 IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
246     if (!pLHS || !pRHS) return 0;
247     // eval*() call is required before calling unitFactor(), since the latter does not evaluate expressions!
248     vmint lvalue = pLHS->evalInt();
249     vmint rvalue = pRHS->evalInt();
250     if (pLHS->unitFactor() == pRHS->unitFactor())
251     return lvalue - rvalue;
252     if (pLHS->unitFactor() < pRHS->unitFactor())
253     return lvalue - Unit::convIntToUnitFactor(rvalue, pRHS, pLHS);
254     else
255     return Unit::convIntToUnitFactor(lvalue, pLHS, pRHS) - rvalue;
256 schoenebeck 2581 }
257    
258 schoenebeck 3573 vmfloat Sub::evalReal() {
259     RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
260 schoenebeck 3581 RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);
261     if (!pLHS || !pRHS) return 0;
262     // eval*() call is required before calling unitFactor(), since the latter does not evaluate expressions!
263     vmfloat lvalue = pLHS->evalReal();
264     vmfloat rvalue = pRHS->evalReal();
265     if (pLHS->unitFactor() == pRHS->unitFactor())
266     return lvalue - rvalue;
267     if (pLHS->unitFactor() < pRHS->unitFactor())
268     return lvalue - Unit::convRealToUnitFactor(rvalue, pRHS, pLHS);
269     else
270     return Unit::convRealToUnitFactor(lvalue, pLHS, pRHS) - rvalue;
271 schoenebeck 3573 }
272    
273 schoenebeck 3581 vmfloat Sub::unitFactor() const {
274     const ScalarNumberExpr* pLHS = dynamic_cast<const ScalarNumberExpr*>(&*lhs);
275     const ScalarNumberExpr* pRHS = dynamic_cast<const ScalarNumberExpr*>(&*rhs);
276     return (pLHS->unitFactor() < pRHS->unitFactor()) ? pLHS->unitFactor() : pRHS->unitFactor();
277     }
278    
279 schoenebeck 2581 void Sub::dump(int level) {
280     printIndents(level);
281     printf("Sub(\n");
282     lhs->dump(level+1);
283     printIndents(level);
284     printf(",\n");
285     rhs->dump(level+1);
286     printIndents(level);
287     printf(")\n");
288     }
289    
290 schoenebeck 3581 Mul::Mul(ScalarNumberExprRef lhs, ScalarNumberExprRef rhs) :
291     VaritypeScalarBinaryOp(lhs, rhs),
292     Unit(
293     // currently the NKSP parser only allows a unit type on either side on multiplications
294     (lhs->unitType()) ? lhs->unitType() : rhs->unitType()
295     )
296     {
297     }
298    
299 schoenebeck 3557 vmint Mul::evalInt() {
300 schoenebeck 2581 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
301     IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;
302     return (pLHS && pRHS) ? pLHS->evalInt() * pRHS->evalInt() : 0;
303     }
304    
305 schoenebeck 3573 vmfloat Mul::evalReal() {
306     RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
307     RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);;
308     return (pLHS && pRHS) ? pLHS->evalReal() * pRHS->evalReal() : 0;
309     }
310    
311 schoenebeck 2581 void Mul::dump(int level) {
312     printIndents(level);
313     printf("Mul(\n");
314     lhs->dump(level+1);
315     printIndents(level);
316     printf(",\n");
317     rhs->dump(level+1);
318     printIndents(level);
319     printf(")\n");
320     }
321    
322 schoenebeck 3581 vmfloat Mul::unitFactor() const {
323 schoenebeck 3573 const ScalarNumberExpr* pLHS = dynamic_cast<const ScalarNumberExpr*>(&*lhs);
324     const ScalarNumberExpr* pRHS = dynamic_cast<const ScalarNumberExpr*>(&*rhs);
325 schoenebeck 3581 return pLHS->unitFactor() * pRHS->unitFactor();
326 schoenebeck 3561 }
327    
328 schoenebeck 3581 Div::Div(ScalarNumberExprRef lhs, ScalarNumberExprRef rhs) :
329     VaritypeScalarBinaryOp(lhs, rhs),
330     Unit(
331     // the NKSP parser only allows either A) a unit type on left side and none
332     // on right side or B) an identical unit type on both sides
333     (lhs->unitType() && rhs->unitType()) ? VM_NO_UNIT : lhs->unitType()
334     )
335     {
336 schoenebeck 3561 }
337    
338 schoenebeck 3557 vmint Div::evalInt() {
339 schoenebeck 2581 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
340 schoenebeck 2945 IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
341     if (!pLHS || !pRHS) return 0;
342 schoenebeck 3557 vmint l = pLHS->evalInt();
343     vmint r = pRHS->evalInt();
344 schoenebeck 2945 if (r == 0) return 0;
345     return l / r;
346 schoenebeck 2581 }
347    
348 schoenebeck 3573 vmfloat Div::evalReal() {
349     RealExpr* pLHS = dynamic_cast<RealExpr*>(&*lhs);
350 schoenebeck 3581 RealExpr* pRHS = dynamic_cast<RealExpr*>(&*rhs);
351 schoenebeck 3573 if (!pLHS || !pRHS) return 0;
352     vmfloat l = pLHS->evalReal();
353     vmfloat r = pRHS->evalReal();
354     if (r == vmfloat(0)) return 0;
355     return l / r;
356     }
357    
358 schoenebeck 2581 void Div::dump(int level) {
359     printIndents(level);
360     printf("Div(\n");
361     lhs->dump(level+1);
362     printIndents(level);
363     printf(",\n");
364     rhs->dump(level+1);
365     printIndents(level);
366     printf(")\n");
367     }
368    
369 schoenebeck 3581 vmfloat Div::unitFactor() const {
370 schoenebeck 3573 const ScalarNumberExpr* pLHS = dynamic_cast<const ScalarNumberExpr*>(&*lhs);
371     const ScalarNumberExpr* pRHS = dynamic_cast<const ScalarNumberExpr*>(&*rhs);
372 schoenebeck 3581 return pLHS->unitFactor() / pRHS->unitFactor();
373 schoenebeck 3561 }
374    
375 schoenebeck 3557 vmint Mod::evalInt() {
376 schoenebeck 2581 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
377 schoenebeck 3581 IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
378 schoenebeck 2581 return (pLHS && pRHS) ? pLHS->evalInt() % pRHS->evalInt() : 0;
379     }
380    
381     void Mod::dump(int level) {
382     printIndents(level);
383     printf("Mod(\n");
384     lhs->dump(level+1);
385     printIndents(level);
386     printf(",\n");
387     rhs->dump(level+1);
388     printIndents(level);
389     printf(")\n");
390     }
391    
392     void Args::dump(int level) {
393     printIndents(level);
394     printf("Args(\n");
395     for (std::vector<ExpressionRef>::iterator it = args.begin() ; it != args.end() ; ++it) {
396     (*it)->dump(level+1);
397     }
398     printIndents(level);
399     printf(")\n");
400     }
401    
402 schoenebeck 2645 bool Args::isPolyphonic() const {
403 schoenebeck 3557 for (vmint i = 0; i < args.size(); ++i)
404 schoenebeck 2645 if (args[i]->isPolyphonic())
405     return true;
406     return false;
407     }
408    
409 schoenebeck 2581 EventHandlers::EventHandlers() {
410     //printf("EventHandlers::Constructor 0x%lx\n", (long long)this);
411     }
412    
413     EventHandlers::~EventHandlers() {
414     }
415    
416     void EventHandlers::add(EventHandlerRef arg) {
417     args.push_back(arg);
418     }
419    
420     void EventHandlers::dump(int level) {
421     printIndents(level);
422     printf("EventHandlers {\n");
423     for (std::vector<EventHandlerRef>::iterator it = args.begin() ; it != args.end() ; ++it) {
424     (*it)->dump(level+1);
425     }
426     printIndents(level);
427     printf("}\n");
428     }
429    
430     EventHandler* EventHandlers::eventHandlerByName(const String& name) const {
431 schoenebeck 3557 for (vmint i = 0; i < args.size(); ++i)
432 schoenebeck 2581 if (args.at(i)->eventHandlerName() == name)
433     return const_cast<EventHandler*>(&*args.at(i));
434     return NULL;
435     }
436    
437     EventHandler* EventHandlers::eventHandler(uint index) const {
438     if (index >= args.size()) return NULL;
439     return const_cast<EventHandler*>(&*args.at(index));
440     }
441    
442 schoenebeck 2645 bool EventHandlers::isPolyphonic() const {
443 schoenebeck 3557 for (vmint i = 0; i < args.size(); ++i)
444 schoenebeck 2645 if (args[i]->isPolyphonic())
445     return true;
446     return false;
447     }
448    
449 schoenebeck 2581 Assignment::Assignment(VariableRef variable, ExpressionRef value)
450     : variable(variable), value(value)
451     {
452     }
453    
454     void Assignment::dump(int level) {
455     printIndents(level);
456     printf("Assignment\n");
457     }
458    
459     StmtFlags_t Assignment::exec() {
460     if (!variable)
461     return StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
462     variable->assign(&*value);
463     return STMT_SUCCESS;
464     }
465    
466 schoenebeck 2645 EventHandler::EventHandler(StatementsRef statements) {
467     this->statements = statements;
468     usingPolyphonics = statements->isPolyphonic();
469     }
470    
471 schoenebeck 2581 void EventHandler::dump(int level) {
472     printIndents(level);
473     printf("EventHandler {\n");
474     statements->dump(level+1);
475     printIndents(level);
476     printf("}\n");
477     }
478    
479     void Statements::dump(int level) {
480     printIndents(level);
481     printf("Statements {\n");
482     for (std::vector<StatementRef>::iterator it = args.begin() ; it != args.end() ; ++it) {
483     (*it)->dump(level+1);
484     }
485     printIndents(level);
486     printf("}\n");
487     }
488    
489     Statement* Statements::statement(uint i) {
490     if (i >= args.size()) return NULL;
491     return &*args.at(i);
492     }
493    
494 schoenebeck 2645 bool Statements::isPolyphonic() const {
495 schoenebeck 3557 for (vmint i = 0; i < args.size(); ++i)
496 schoenebeck 2645 if (args[i]->isPolyphonic())
497     return true;
498     return false;
499     }
500    
501 schoenebeck 3581 DynamicVariableCall::DynamicVariableCall(const String& name, ParserContext* ctx, VMDynVar* v) :
502     Variable({
503     .ctx = ctx,
504     .elements = 0
505     }),
506     Unit(VM_NO_UNIT),
507     dynVar(v), varName(name)
508 schoenebeck 2942 {
509     }
510    
511 schoenebeck 3557 vmint DynamicVariableCall::evalInt() {
512 schoenebeck 2942 VMIntExpr* expr = dynamic_cast<VMIntExpr*>(dynVar);
513     if (!expr) return 0;
514     return expr->evalInt();
515     }
516    
517     String DynamicVariableCall::evalStr() {
518     VMStringExpr* expr = dynamic_cast<VMStringExpr*>(dynVar);
519     if (!expr) return "";
520     return expr->evalStr();
521     }
522    
523     String DynamicVariableCall::evalCastToStr() {
524     if (dynVar->exprType() == STRING_EXPR) {
525     return evalStr();
526     } else {
527     VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(dynVar);
528     return intExpr ? ToString(intExpr->evalInt()) : "";
529     }
530     }
531    
532     void DynamicVariableCall::dump(int level) {
533     printIndents(level);
534     printf("Dynamic Variable '%s'\n", varName.c_str());
535     }
536    
537 schoenebeck 3581 FunctionCall::FunctionCall(const char* function, ArgsRef args, VMFunction* fn) :
538     Unit(
539     (fn) ? fn->returnUnitType(dynamic_cast<VMFnArgs*>(&*args)) : VM_NO_UNIT
540     ),
541     functionName(function), args(args), fn(fn), result(NULL)
542     {
543     }
544    
545 schoenebeck 2581 void FunctionCall::dump(int level) {
546     printIndents(level);
547     printf("FunctionCall '%s' args={\n", functionName.c_str());
548     args->dump(level+1);
549     printIndents(level);
550     printf("}\n");
551     }
552    
553     ExprType_t FunctionCall::exprType() const {
554     if (!fn) return EMPTY_EXPR;
555 schoenebeck 3577 FunctionCall* self = const_cast<FunctionCall*>(this);
556     return fn->returnType(dynamic_cast<VMFnArgs*>(&*self->args));
557 schoenebeck 2581 }
558    
559 schoenebeck 3581 vmfloat FunctionCall::unitFactor() const {
560     if (!fn || !result) return VM_NO_FACTOR;
561     VMExpr* expr = result->resultValue();
562     if (!expr) return VM_NO_FACTOR;
563     VMScalarNumberExpr* scalar = expr->asScalarNumberExpr();
564     if (!scalar) return VM_NO_FACTOR;
565     return scalar->unitFactor();
566     }
567    
568     bool FunctionCall::isFinal() const {
569     if (!fn) return false;
570     FunctionCall* self = const_cast<FunctionCall*>(this);
571     return fn->returnsFinal(dynamic_cast<VMFnArgs*>(&*self->args));
572     }
573    
574 schoenebeck 2581 VMFnResult* FunctionCall::execVMFn() {
575     if (!fn) return NULL;
576     // assuming here that all argument checks (amount and types) have been made
577     // at parse time, to avoid time intensive checks on each function call
578     return fn->exec(dynamic_cast<VMFnArgs*>(&*args));
579     }
580    
581     StmtFlags_t FunctionCall::exec() {
582 schoenebeck 3581 result = execVMFn();
583 schoenebeck 2581 if (!result)
584     return StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
585     return result->resultFlags();
586     }
587    
588 schoenebeck 3557 vmint FunctionCall::evalInt() {
589 schoenebeck 3581 result = execVMFn();
590 schoenebeck 2581 if (!result) return 0;
591     VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());
592     if (!intExpr) return 0;
593     return intExpr->evalInt();
594     }
595    
596 schoenebeck 3573 vmfloat FunctionCall::evalReal() {
597 schoenebeck 3581 result = execVMFn();
598 schoenebeck 3573 if (!result) return 0;
599     VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());
600     if (!realExpr) return 0;
601     return realExpr->evalReal();
602     }
603    
604 schoenebeck 3056 VMIntArrayExpr* FunctionCall::asIntArray() const {
605     if (!result) return 0;
606     VMIntArrayExpr* intArrExpr = dynamic_cast<VMIntArrayExpr*>(result->resultValue());
607     return intArrExpr;
608     }
609    
610 schoenebeck 3573 VMRealArrayExpr* FunctionCall::asRealArray() const {
611     if (!result) return 0;
612     VMRealArrayExpr* realArrExpr = dynamic_cast<VMRealArrayExpr*>(result->resultValue());
613     return realArrExpr;
614     }
615    
616 schoenebeck 2581 String FunctionCall::evalStr() {
617 schoenebeck 3581 result = execVMFn();
618 schoenebeck 2581 if (!result) return "";
619     VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());
620     if (!strExpr) return "";
621     return strExpr->evalStr();
622     }
623    
624     String FunctionCall::evalCastToStr() {
625 schoenebeck 3581 result = execVMFn();
626 schoenebeck 2581 if (!result) return "";
627 schoenebeck 3573 const ExprType_t resultType = result->resultValue()->exprType();
628     if (resultType == STRING_EXPR) {
629 schoenebeck 2581 VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());
630     return strExpr ? strExpr->evalStr() : "";
631 schoenebeck 3573 } else if (resultType == REAL_EXPR) {
632     VMRealExpr* realExpr = dynamic_cast<VMRealExpr*>(result->resultValue());
633     return realExpr ? ToString(realExpr->evalReal()) : "";
634 schoenebeck 2581 } else {
635     VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());
636     return intExpr ? ToString(intExpr->evalInt()) : "";
637     }
638     }
639    
640 schoenebeck 3581 Variable::Variable(const VariableDecl& decl) :
641     context(decl.ctx), memPos(decl.memPos), bConst(decl.isConst)
642 schoenebeck 2581 {
643 schoenebeck 3573 }
644    
645 schoenebeck 3581 ScalarNumberVariable::ScalarNumberVariable(const VariableDecl& decl) :
646     Variable(decl),
647     Unit(decl.unitType),
648     unitFactorMemPos(decl.unitFactorMemPos), polyphonic(decl.isPolyphonic),
649     finalVal(decl.isFinal)
650 schoenebeck 3573 {
651 schoenebeck 2581 }
652    
653 schoenebeck 3581 vmfloat ScalarNumberVariable::unitFactor() const {
654     if (isPolyphonic()) {
655     return context->execContext->polyphonicUnitFactorMemory[unitFactorMemPos];
656     }
657     return (*context->globalUnitFactorMemory)[unitFactorMemPos];
658     }
659    
660 schoenebeck 3557 inline static vmint postfixInc(vmint& object, vmint incBy) {
661     const vmint i = object;
662 schoenebeck 2588 object += incBy;
663     return i;
664     }
665    
666 schoenebeck 3581 IntVariable::IntVariable(const VariableDecl& decl) :
667     ScalarNumberVariable({
668     .ctx = decl.ctx,
669     .isPolyphonic = decl.isPolyphonic,
670     .isConst = decl.isConst,
671     .isFinal = decl.isFinal,
672     .elements = decl.elements,
673     .memPos = (
674     (!decl.ctx) ? 0 :
675     (decl.isPolyphonic) ?
676     postfixInc(decl.ctx->polyphonicIntVarCount, decl.elements) :
677     postfixInc(decl.ctx->globalIntVarCount, decl.elements)
678     ),
679     .unitFactorMemPos = (
680     (!decl.ctx) ? 0 :
681     (decl.isPolyphonic) ?
682     postfixInc(decl.ctx->polyphonicUnitFactorCount, decl.elements) :
683     postfixInc(decl.ctx->globalUnitFactorCount, decl.elements)
684     ),
685     .unitType = decl.unitType
686     }),
687     Unit(decl.unitType)
688 schoenebeck 2581 {
689 schoenebeck 3581 //printf("IntVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);
690     assert(!decl.isPolyphonic || decl.ctx);
691 schoenebeck 2581 }
692    
693     void IntVariable::assign(Expression* expr) {
694     IntExpr* intExpr = dynamic_cast<IntExpr*>(expr);
695 schoenebeck 3034 if (intExpr) {
696 schoenebeck 3581 //NOTE: sequence matters! evalInt() must be called before getting unitFactor() !
697     if (isPolyphonic()) {
698 schoenebeck 2581 context->execContext->polyphonicIntMemory[memPos] = intExpr->evalInt();
699 schoenebeck 3581 context->execContext->polyphonicUnitFactorMemory[unitFactorMemPos] = intExpr->unitFactor();
700     } else {
701 schoenebeck 2581 (*context->globalIntMemory)[memPos] = intExpr->evalInt();
702 schoenebeck 3581 (*context->globalUnitFactorMemory)[unitFactorMemPos] = intExpr->unitFactor();
703     }
704 schoenebeck 3034 }
705 schoenebeck 2581 }
706    
707 schoenebeck 3557 vmint IntVariable::evalInt() {
708 schoenebeck 2581 //printf("IntVariable::eval pos=%d\n", memPos);
709 schoenebeck 3573 if (isPolyphonic()) {
710 schoenebeck 2588 //printf("evalInt() poly memPos=%d execCtx=0x%lx\n", memPos, (uint64_t)context->execContext);
711 schoenebeck 2581 return context->execContext->polyphonicIntMemory[memPos];
712 schoenebeck 2588 }
713 schoenebeck 2581 return (*context->globalIntMemory)[memPos];
714     }
715    
716     void IntVariable::dump(int level) {
717     printIndents(level);
718 schoenebeck 2945 printf("IntVariable\n");
719 schoenebeck 2588 //printf("IntVariable memPos=%d\n", memPos);
720 schoenebeck 2581 }
721    
722 schoenebeck 3581 RealVariable::RealVariable(const VariableDecl& decl) :
723     ScalarNumberVariable({
724     .ctx = decl.ctx,
725     .isPolyphonic = decl.isPolyphonic,
726     .isConst = decl.isConst,
727     .isFinal = decl.isFinal,
728     .elements = decl.elements,
729     .memPos = (
730     (!decl.ctx) ? 0 :
731     (decl.isPolyphonic) ?
732     postfixInc(decl.ctx->polyphonicRealVarCount, decl.elements) :
733     postfixInc(decl.ctx->globalRealVarCount, decl.elements)
734     ),
735     .unitFactorMemPos = (
736     (!decl.ctx) ? 0 :
737     (decl.isPolyphonic) ?
738     postfixInc(decl.ctx->polyphonicUnitFactorCount, decl.elements) :
739     postfixInc(decl.ctx->globalUnitFactorCount, decl.elements)
740     ),
741     .unitType = decl.unitType
742     }),
743     Unit(decl.unitType)
744 schoenebeck 3573 {
745 schoenebeck 3581 //printf("RealVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);
746     assert(!decl.isPolyphonic || decl.ctx);
747 schoenebeck 3573 }
748    
749     void RealVariable::assign(Expression* expr) {
750     RealExpr* realExpr = dynamic_cast<RealExpr*>(expr);
751     if (realExpr) {
752 schoenebeck 3581 //NOTE: sequence matters! evalReal() must be called before getting unitFactor() !
753     if (isPolyphonic()) {
754 schoenebeck 3573 context->execContext->polyphonicRealMemory[memPos] = realExpr->evalReal();
755 schoenebeck 3581 context->execContext->polyphonicUnitFactorMemory[unitFactorMemPos] = realExpr->unitFactor();
756     } else {
757 schoenebeck 3573 (*context->globalRealMemory)[memPos] = realExpr->evalReal();
758 schoenebeck 3581 (*context->globalUnitFactorMemory)[unitFactorMemPos] = realExpr->unitFactor();
759     }
760 schoenebeck 3573 }
761     }
762    
763     vmfloat RealVariable::evalReal() {
764     //printf("RealVariable::eval pos=%d\n", memPos);
765     if (isPolyphonic()) {
766     //printf("evalReal() poly memPos=%d execCtx=0x%lx\n", memPos, (uint64_t)context->execContext);
767     return context->execContext->polyphonicRealMemory[memPos];
768     }
769     return (*context->globalRealMemory)[memPos];
770     }
771    
772     void RealVariable::dump(int level) {
773     printIndents(level);
774     printf("RealVariable\n");
775     //printf("RealVariable memPos=%d\n", memPos);
776     }
777    
778 schoenebeck 3581 ConstIntVariable::ConstIntVariable(const IntVarDef& def) :
779     IntVariable({
780     .ctx = def.ctx,
781     .isPolyphonic = false,
782     .isConst = true,
783     .isFinal = def.isFinal,
784     .elements = 1,
785     .memPos = def.memPos,
786     .unitFactorMemPos = def.unitFactorMemPos,
787     .unitType = def.unitType
788     }),
789     Unit(def.unitType),
790     value(def.value), unitPrefixFactor(def.unitFactor)
791 schoenebeck 2581 {
792     }
793    
794     void ConstIntVariable::assign(Expression* expr) {
795     // ignore assignment
796     /*
797     printf("ConstIntVariable::assign()\n");
798     IntExpr* intExpr = dynamic_cast<IntExpr*>(expr);
799     if (intExpr) {
800     value = intExpr->evalInt();
801     }
802     */
803     }
804    
805 schoenebeck 3557 vmint ConstIntVariable::evalInt() {
806 schoenebeck 2581 return value;
807     }
808    
809     void ConstIntVariable::dump(int level) {
810     printIndents(level);
811 schoenebeck 3557 printf("ConstIntVariable val=%lld\n", value);
812 schoenebeck 2581 }
813    
814 schoenebeck 3581 ConstRealVariable::ConstRealVariable(const RealVarDef& def) :
815     RealVariable({
816     .ctx = def.ctx,
817     .isPolyphonic = false,
818     .isConst = true,
819     .isFinal = def.isFinal,
820     .elements = 1,
821     .memPos = def.memPos,
822     .unitFactorMemPos = def.unitFactorMemPos,
823     .unitType = def.unitType
824     }),
825     Unit(def.unitType),
826     value(def.value), unitPrefixFactor(def.unitFactor)
827 schoenebeck 3573 {
828     }
829    
830     void ConstRealVariable::assign(Expression* expr) {
831     // ignore assignment
832     }
833    
834     vmfloat ConstRealVariable::evalReal() {
835     return value;
836     }
837    
838     void ConstRealVariable::dump(int level) {
839     printIndents(level);
840     printf("ConstRealVariable val=%f\n", value);
841     }
842    
843 schoenebeck 3581 BuiltInIntVariable::BuiltInIntVariable(const String& name, VMIntPtr* ptr) :
844     IntVariable({
845     .ctx = NULL,
846     .isPolyphonic = false,
847     .isConst = false, // may or may not be modifyable though!
848     .isFinal = false,
849     .elements = 0,
850     .memPos = 0,
851     .unitFactorMemPos = 0,
852     .unitType = VM_NO_UNIT
853     }),
854     Unit(VM_NO_UNIT),
855     name(name), ptr(ptr)
856 schoenebeck 2594 {
857     }
858    
859     void BuiltInIntVariable::assign(Expression* expr) {
860     IntExpr* valueExpr = dynamic_cast<IntExpr*>(expr);
861     if (!valueExpr) return;
862     ptr->assign(valueExpr->evalInt());
863     }
864    
865 schoenebeck 3557 vmint BuiltInIntVariable::evalInt() {
866 schoenebeck 2594 return ptr->evalInt();
867     }
868    
869     void BuiltInIntVariable::dump(int level) {
870     printIndents(level);
871     printf("Built-in IntVar '%s'\n", name.c_str());
872     }
873    
874 schoenebeck 3581 PolyphonicIntVariable::PolyphonicIntVariable(const VariableDecl& decl) :
875     IntVariable({
876     .ctx = decl.ctx,
877     .isPolyphonic = true,
878     .isConst = decl.isConst,
879     .isFinal = decl.isFinal,
880     .elements = 1,
881     .memPos = 0,
882     .unitFactorMemPos = 0,
883     .unitType = decl.unitType
884     }),
885     Unit(decl.unitType)
886 schoenebeck 2581 {
887     }
888    
889     void PolyphonicIntVariable::dump(int level) {
890     printIndents(level);
891     printf("PolyphonicIntVariable\n");
892     }
893    
894 schoenebeck 3581 PolyphonicRealVariable::PolyphonicRealVariable(const VariableDecl& decl) :
895     RealVariable({
896     .ctx = decl.ctx,
897     .isPolyphonic = true,
898     .isConst = decl.isConst,
899     .isFinal = decl.isFinal,
900     .elements = 1,
901     .memPos = 0,
902     .unitFactorMemPos = 0,
903     .unitType = decl.unitType
904     }),
905     Unit(decl.unitType)
906 schoenebeck 3573 {
907     }
908    
909     void PolyphonicRealVariable::dump(int level) {
910     printIndents(level);
911     printf("PolyphonicRealVariable\n");
912     }
913    
914 schoenebeck 3581 IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size) :
915     Variable({
916     .ctx = ctx,
917     .isPolyphonic = false,
918     .isConst = false,
919     .isFinal = false,
920     .elements = 0,
921     .memPos = 0,
922     .unitFactorMemPos = 0,
923     .unitType = VM_NO_UNIT
924     })
925 schoenebeck 2581 {
926     values.resize(size);
927 schoenebeck 3557 memset(&values[0], 0, size * sizeof(vmint));
928 schoenebeck 3581
929     unitFactors.resize(size);
930     for (size_t i = 0; i < size; ++i)
931     unitFactors[i] = VM_NO_FACTOR;
932 schoenebeck 2581 }
933    
934 schoenebeck 3581 IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size,
935     ArgsRef values, bool _bConst) :
936     Variable({
937     .ctx = ctx,
938     .isPolyphonic = false,
939     .isConst = _bConst,
940     .isFinal = false,
941     .elements = 0,
942     .memPos = 0,
943     .unitFactorMemPos = 0,
944     .unitType = VM_NO_UNIT
945     })
946 schoenebeck 2581 {
947     this->values.resize(size);
948 schoenebeck 3581 this->unitFactors.resize(size);
949 schoenebeck 3557 for (vmint i = 0; i < values->argsCount(); ++i) {
950 schoenebeck 2581 VMIntExpr* expr = dynamic_cast<VMIntExpr*>(values->arg(i));
951 schoenebeck 3581 if (expr) {
952     this->values[i] = expr->evalInt();
953     this->unitFactors[i] = expr->unitFactor();
954     }
955 schoenebeck 2581 }
956     }
957    
958 schoenebeck 3581 IntArrayVariable::IntArrayVariable(ParserContext* ctx, bool bConst) :
959     Variable({
960     .ctx = ctx,
961     .isPolyphonic = false,
962     .isConst = bConst,
963     .isFinal = false,
964     .elements = 0,
965     .memPos = 0,
966     .unitFactorMemPos = 0,
967     .unitType = VM_NO_UNIT
968     })
969 schoenebeck 2594 {
970     }
971    
972 schoenebeck 3557 vmint IntArrayVariable::evalIntElement(vmuint i) {
973 schoenebeck 2581 if (i >= values.size()) return 0;
974     return values[i];
975     }
976    
977 schoenebeck 3557 void IntArrayVariable::assignIntElement(vmuint i, vmint value) {
978 schoenebeck 2581 if (i >= values.size()) return;
979     values[i] = value;
980     }
981    
982 schoenebeck 3581 vmfloat IntArrayVariable::unitFactorOfElement(vmuint i) const {
983     if (i >= unitFactors.size()) return VM_NO_FACTOR;
984     return unitFactors[i];
985     }
986    
987     void IntArrayVariable::assignElementUnitFactor(vmuint i, vmfloat factor) {
988     if (i >= unitFactors.size()) return;
989     unitFactors[i] = factor;
990     }
991    
992 schoenebeck 2581 void IntArrayVariable::dump(int level) {
993     printIndents(level);
994     printf("IntArray(");
995 schoenebeck 3557 for (vmint i = 0; i < values.size(); ++i) {
996 schoenebeck 2581 if (i % 12 == 0) {
997     printf("\n");
998     printIndents(level+1);
999     }
1000 schoenebeck 3557 printf("%lld, ", values[i]);
1001 schoenebeck 2581 }
1002     printIndents(level);
1003     printf(")\n");
1004     }
1005    
1006 schoenebeck 3581 RealArrayVariable::RealArrayVariable(ParserContext* ctx, vmint size) :
1007     Variable({
1008     .ctx = ctx,
1009     .isPolyphonic = false,
1010     .isConst = false,
1011     .isFinal = false,
1012     .elements = 0,
1013     .memPos = 0,
1014     .unitFactorMemPos = 0,
1015     .unitType = VM_NO_UNIT
1016     })
1017 schoenebeck 3573 {
1018     values.resize(size);
1019     memset(&values[0], 0, size * sizeof(vmfloat));
1020 schoenebeck 3581
1021     unitFactors.resize(size);
1022     for (size_t i = 0; i < size; ++i)
1023     unitFactors[i] = VM_NO_FACTOR;
1024 schoenebeck 3573 }
1025    
1026 schoenebeck 3581 RealArrayVariable::RealArrayVariable(ParserContext* ctx, vmint size,
1027     ArgsRef values, bool _bConst) :
1028     Variable({
1029     .ctx = ctx,
1030     .isPolyphonic = false,
1031     .isConst = _bConst,
1032     .isFinal = false,
1033     .elements = 0,
1034     .memPos = 0,
1035     .unitFactorMemPos = 0,
1036     .unitType = VM_NO_UNIT
1037     })
1038 schoenebeck 3573 {
1039     this->values.resize(size);
1040 schoenebeck 3581 this->unitFactors.resize(size);
1041 schoenebeck 3573 for (vmint i = 0; i < values->argsCount(); ++i) {
1042     VMRealExpr* expr = dynamic_cast<VMRealExpr*>(values->arg(i));
1043 schoenebeck 3581 if (expr) {
1044     this->values[i] = expr->evalReal();
1045     this->unitFactors[i] = expr->unitFactor();
1046     }
1047 schoenebeck 3573 }
1048     }
1049    
1050 schoenebeck 3581 RealArrayVariable::RealArrayVariable(ParserContext* ctx, bool bConst) :
1051     Variable({
1052     .ctx = ctx,
1053     .isPolyphonic = false,
1054     .isConst = bConst,
1055     .isFinal = false,
1056     .elements = 0,
1057     .memPos = 0,
1058     .unitFactorMemPos = 0,
1059     .unitType = VM_NO_UNIT
1060     })
1061 schoenebeck 3573 {
1062     }
1063    
1064     vmfloat RealArrayVariable::evalRealElement(vmuint i) {
1065     if (i >= values.size()) return 0;
1066     return values[i];
1067     }
1068    
1069     void RealArrayVariable::assignRealElement(vmuint i, vmfloat value) {
1070     if (i >= values.size()) return;
1071     values[i] = value;
1072     }
1073    
1074 schoenebeck 3581 vmfloat RealArrayVariable::unitFactorOfElement(vmuint i) const {
1075     if (i >= unitFactors.size()) return VM_NO_FACTOR;
1076     return unitFactors[i];
1077     }
1078    
1079     void RealArrayVariable::assignElementUnitFactor(vmuint i, vmfloat factor) {
1080     if (i >= unitFactors.size()) return;
1081     unitFactors[i] = factor;
1082     }
1083    
1084 schoenebeck 3573 void RealArrayVariable::dump(int level) {
1085     printIndents(level);
1086     printf("RealArray(");
1087     for (vmint i = 0; i < values.size(); ++i) {
1088     if (i % 12 == 0) {
1089     printf("\n");
1090     printIndents(level+1);
1091     }
1092     printf("%f, ", values[i]);
1093     }
1094     printIndents(level);
1095     printf(")\n");
1096     }
1097    
1098 schoenebeck 3581 BuiltInIntArrayVariable::BuiltInIntArrayVariable(const String& name,
1099     VMInt8Array* array) :
1100     IntArrayVariable(NULL, false),
1101     name(name), array(array)
1102 schoenebeck 2594 {
1103     }
1104    
1105 schoenebeck 3557 vmint BuiltInIntArrayVariable::evalIntElement(vmuint i) {
1106 schoenebeck 2594 return i >= array->size ? 0 : array->data[i];
1107     }
1108    
1109 schoenebeck 3557 void BuiltInIntArrayVariable::assignIntElement(vmuint i, vmint value) {
1110 schoenebeck 2594 if (i >= array->size) return;
1111     array->data[i] = value;
1112     }
1113    
1114     void BuiltInIntArrayVariable::dump(int level) {
1115     printIndents(level);
1116     printf("Built-In Int Array Variable '%s'\n", name.c_str());
1117     }
1118    
1119 schoenebeck 3581 IntArrayElement::IntArrayElement(IntArrayExprRef array, IntExprRef arrayIndex) :
1120     IntVariable({
1121     .ctx = NULL,
1122     .isPolyphonic = (array) ? array->isPolyphonic() : false,
1123     .isConst = (array) ? array->isConstExpr() : false,
1124     .isFinal = false,
1125     .elements = 0,
1126     .memPos = 0,
1127     .unitFactorMemPos = 0,
1128     .unitType = VM_NO_UNIT
1129     }),
1130     Unit(VM_NO_UNIT),
1131     array(array), index(arrayIndex), currentIndex(-1)
1132 schoenebeck 2581 {
1133     }
1134    
1135     void IntArrayElement::assign(Expression* expr) {
1136     IntExpr* valueExpr = dynamic_cast<IntExpr*>(expr);
1137     if (!valueExpr) return;
1138 schoenebeck 3557 vmint value = valueExpr->evalInt();
1139 schoenebeck 3581 vmfloat unitFactor = valueExpr->unitFactor();
1140 schoenebeck 2581
1141     if (!index) return;
1142 schoenebeck 3581 vmint idx = currentIndex = index->evalInt();
1143 schoenebeck 2581 if (idx < 0 || idx >= array->arraySize()) return;
1144    
1145     array->assignIntElement(idx, value);
1146 schoenebeck 3581 array->assignElementUnitFactor(idx, unitFactor);
1147 schoenebeck 2581 }
1148    
1149 schoenebeck 3557 vmint IntArrayElement::evalInt() {
1150 schoenebeck 2581 if (!index) return 0;
1151 schoenebeck 3581 vmint idx = currentIndex = index->evalInt();
1152 schoenebeck 2581 if (idx < 0 || idx >= array->arraySize()) return 0;
1153    
1154     return array->evalIntElement(idx);
1155     }
1156    
1157 schoenebeck 3581 vmfloat IntArrayElement::unitFactor() const {
1158     if (!index) return VM_NO_FACTOR;
1159     vmint idx = currentIndex;
1160     if (idx < 0 || idx >= array->arraySize()) return 0;
1161    
1162     return array->unitFactorOfElement(idx);
1163     }
1164    
1165 schoenebeck 2581 void IntArrayElement::dump(int level) {
1166     printIndents(level);
1167     printf("IntArrayElement\n");
1168     }
1169    
1170 schoenebeck 3581 RealArrayElement::RealArrayElement(RealArrayExprRef array, IntExprRef arrayIndex) :
1171     RealVariable({
1172     .ctx = NULL,
1173     .isPolyphonic = (array) ? array->isPolyphonic() : false,
1174     .isConst = (array) ? array->isConstExpr() : false,
1175     .isFinal = false,
1176     .elements = 0,
1177     .memPos = 0,
1178     .unitFactorMemPos = 0,
1179     .unitType = VM_NO_UNIT
1180     }),
1181     Unit(VM_NO_UNIT),
1182     array(array), index(arrayIndex), currentIndex(-1)
1183 schoenebeck 3573 {
1184     }
1185    
1186     void RealArrayElement::assign(Expression* expr) {
1187     RealExpr* valueExpr = dynamic_cast<RealExpr*>(expr);
1188     if (!valueExpr) return;
1189     vmfloat value = valueExpr->evalReal();
1190 schoenebeck 3581 vmfloat unitFactor = valueExpr->unitFactor();
1191 schoenebeck 3573
1192     if (!index) return;
1193 schoenebeck 3581 vmint idx = currentIndex = index->evalInt();
1194 schoenebeck 3573 if (idx < 0 || idx >= array->arraySize()) return;
1195    
1196     array->assignRealElement(idx, value);
1197 schoenebeck 3581 array->assignElementUnitFactor(idx, unitFactor);
1198 schoenebeck 3573 }
1199    
1200     vmfloat RealArrayElement::evalReal() {
1201     if (!index) return 0;
1202 schoenebeck 3581 vmint idx = currentIndex = index->evalInt();
1203 schoenebeck 3573 if (idx < 0 || idx >= array->arraySize()) return 0;
1204    
1205     return array->evalRealElement(idx);
1206     }
1207    
1208 schoenebeck 3581 vmfloat RealArrayElement::unitFactor() const {
1209     if (!index) return VM_NO_FACTOR;
1210     vmint idx = currentIndex;
1211     if (idx < 0 || idx >= array->arraySize()) return 0;
1212    
1213     return array->unitFactorOfElement(idx);
1214     }
1215    
1216 schoenebeck 3573 void RealArrayElement::dump(int level) {
1217     printIndents(level);
1218     printf("RealArrayElement\n");
1219     }
1220    
1221 schoenebeck 3581 StringVariable::StringVariable(ParserContext* ctx) :
1222     Variable({
1223     .ctx = ctx,
1224     .elements = 1,
1225     .memPos = ctx->globalStrVarCount++
1226     })
1227 schoenebeck 2581 {
1228     }
1229    
1230 schoenebeck 3581 StringVariable::StringVariable(ParserContext* ctx, bool bConst) :
1231     Variable({
1232     .ctx = ctx,
1233     .memPos = 0,
1234     .isConst = bConst
1235     })
1236 schoenebeck 2581 {
1237     }
1238    
1239     void StringVariable::assign(Expression* expr) {
1240     StringExpr* strExpr = dynamic_cast<StringExpr*>(expr);
1241     (*context->globalStrMemory)[memPos] = strExpr->evalStr();
1242     }
1243    
1244     String StringVariable::evalStr() {
1245     //printf("StringVariable::eval pos=%d\n", memPos);
1246     return (*context->globalStrMemory)[memPos];
1247     }
1248    
1249     void StringVariable::dump(int level) {
1250     printIndents(level);
1251 schoenebeck 3557 printf("StringVariable memPos=%lld\n", memPos);
1252 schoenebeck 2581 }
1253    
1254     ConstStringVariable::ConstStringVariable(ParserContext* ctx, String _value)
1255     : StringVariable(ctx,true), value(_value)
1256     {
1257     }
1258    
1259     void ConstStringVariable::assign(Expression* expr) {
1260     // ignore assignment
1261     // StringExpr* strExpr = dynamic_cast<StringExpr*>(expr);
1262     // if (strExpr) value = strExpr->evalStr();
1263     }
1264    
1265     String ConstStringVariable::evalStr() {
1266     return value;
1267     }
1268    
1269     void ConstStringVariable::dump(int level) {
1270     printIndents(level);
1271     printf("ConstStringVariable val='%s'\n", value.c_str());
1272     }
1273    
1274 schoenebeck 3573 bool ScalarNumberBinaryOp::isFinal() const {
1275     ScalarNumberExprRef l = (ScalarNumberExprRef) lhs;
1276     ScalarNumberExprRef r = (ScalarNumberExprRef) rhs;
1277 schoenebeck 3561 return l->isFinal() || r->isFinal();
1278     }
1279    
1280 schoenebeck 3573 ExprType_t VaritypeScalarBinaryOp::exprType() const {
1281     return (lhs->exprType() == REAL_EXPR || rhs->exprType() == REAL_EXPR) ? REAL_EXPR : INT_EXPR;
1282     }
1283    
1284     String VaritypeScalarBinaryOp::evalCastToStr() {
1285     return (exprType() == REAL_EXPR) ?
1286     RealExpr::evalCastToStr() : IntExpr::evalCastToStr();
1287     }
1288    
1289 schoenebeck 2581 void If::dump(int level) {
1290     printIndents(level);
1291     if (ifStatements && elseStatements)
1292     printf("if cond stmts1 else stmts2 end if\n");
1293     else if (ifStatements)
1294     printf("if cond statements end if\n");
1295     else
1296     printf("if [INVALID]\n");
1297     }
1298    
1299 schoenebeck 3557 vmint If::evalBranch() {
1300 schoenebeck 2581 if (condition->evalInt()) return 0;
1301     if (elseStatements) return 1;
1302     return -1;
1303     }
1304    
1305 schoenebeck 3557 Statements* If::branch(vmuint i) const {
1306 schoenebeck 2581 if (i == 0) return (Statements*) &*ifStatements;
1307     if (i == 1) return (elseStatements) ? (Statements*) &*elseStatements : NULL;
1308     return NULL;
1309     }
1310    
1311 schoenebeck 2645 bool If::isPolyphonic() const {
1312     if (condition->isPolyphonic() || ifStatements->isPolyphonic())
1313     return true;
1314     return elseStatements ? elseStatements->isPolyphonic() : false;
1315     }
1316    
1317 schoenebeck 2581 void SelectCase::dump(int level) {
1318     printIndents(level);
1319     if (select)
1320     if (select->isConstExpr())
1321 schoenebeck 3557 printf("Case select %lld\n", select->evalInt());
1322 schoenebeck 2581 else
1323     printf("Case select [runtime expr]\n");
1324     else
1325     printf("Case select NULL\n");
1326 schoenebeck 3557 for (vmint i = 0; i < branches.size(); ++i) {
1327 schoenebeck 2581 printIndents(level+1);
1328     CaseBranch& branch = branches[i];
1329     if (branch.from && branch.to)
1330     if (branch.from->isConstExpr() && branch.to->isConstExpr())
1331 schoenebeck 3557 printf("case %lld to %lld\n", branch.from->evalInt(), branch.to->evalInt());
1332 schoenebeck 2581 else if (branch.from->isConstExpr() && !branch.to->isConstExpr())
1333 schoenebeck 3557 printf("case %lld to [runtime expr]\n", branch.from->evalInt());
1334 schoenebeck 2581 else if (!branch.from->isConstExpr() && branch.to->isConstExpr())
1335 schoenebeck 3557 printf("case [runtime expr] to %lld\n", branch.to->evalInt());
1336 schoenebeck 2581 else
1337     printf("case [runtime expr] to [runtime expr]\n");
1338     else if (branch.from)
1339     if (branch.from->isConstExpr())
1340 schoenebeck 3557 printf("case %lld\n", branch.from->evalInt());
1341 schoenebeck 2581 else
1342     printf("case [runtime expr]\n");
1343     else
1344     printf("case NULL\n");
1345     }
1346     }
1347    
1348 schoenebeck 3557 vmint SelectCase::evalBranch() {
1349     vmint value = select->evalInt();
1350     for (vmint i = 0; i < branches.size(); ++i) {
1351 schoenebeck 2581 if (branches.at(i).from && branches.at(i).to) { // i.e. "case 4 to 7" ...
1352     if (branches.at(i).from->evalInt() <= value &&
1353     branches.at(i).to->evalInt() >= value) return i;
1354     } else { // i.e. "case 5" ...
1355     if (branches.at(i).from->evalInt() == value) return i;
1356     }
1357     }
1358     return -1;
1359     }
1360    
1361 schoenebeck 3557 Statements* SelectCase::branch(vmuint i) const {
1362 schoenebeck 2581 if (i < branches.size())
1363     return const_cast<Statements*>( &*branches[i].statements );
1364     return NULL;
1365     }
1366    
1367 schoenebeck 2645 bool SelectCase::isPolyphonic() const {
1368     if (select->isPolyphonic()) return true;
1369 schoenebeck 3557 for (vmint i = 0; i < branches.size(); ++i)
1370 schoenebeck 2645 if (branches[i].statements->isPolyphonic())
1371     return true;
1372     return false;
1373     }
1374    
1375 schoenebeck 2581 void While::dump(int level) {
1376     printIndents(level);
1377     if (m_condition)
1378     if (m_condition->isConstExpr())
1379 schoenebeck 3557 printf("while (%lld) {\n", m_condition->evalInt());
1380 schoenebeck 2581 else
1381     printf("while ([runtime expr]) {\n");
1382     else
1383     printf("while ([INVALID]) {\n");
1384     m_statements->dump(level+1);
1385     printIndents(level);
1386     printf("}\n");
1387     }
1388    
1389     Statements* While::statements() const {
1390     return (m_statements) ? const_cast<Statements*>( &*m_statements ) : NULL;
1391     }
1392    
1393     bool While::evalLoopStartCondition() {
1394     if (!m_condition) return false;
1395     return m_condition->evalInt();
1396     }
1397    
1398 schoenebeck 3260 void SyncBlock::dump(int level) {
1399     printIndents(level);
1400     printf("sync {\n");
1401     m_statements->dump(level+1);
1402     printIndents(level);
1403     printf("}\n");
1404     }
1405    
1406     Statements* SyncBlock::statements() const {
1407     return (m_statements) ? const_cast<Statements*>( &*m_statements ) : NULL;
1408     }
1409    
1410 schoenebeck 3576 String Neg::evalCastToStr() {
1411     return expr->evalCastToStr();
1412     }
1413    
1414 schoenebeck 2581 void Neg::dump(int level) {
1415     printIndents(level);
1416     printf("Negative Expr\n");
1417     }
1418    
1419     String ConcatString::evalStr() {
1420 schoenebeck 2945 // temporaries required here to enforce the associative left (to right) order
1421 schoenebeck 2948 // ( required for GCC and Visual Studio, see:
1422     // http://stackoverflow.com/questions/25842902/why-stdstring-concatenation-operator-works-like-right-associative-one
1423     // Personally I am not convinced that this is "not a bug" of the
1424     // compiler/STL implementation and the allegedly underlying "function call"
1425     // nature causing this is IMO no profound reason that the C++ language's
1426     // "+" operator's left associativity is ignored. -- Christian, 2016-07-14 )
1427 schoenebeck 2945 String l = lhs->evalCastToStr();
1428     String r = rhs->evalCastToStr();
1429     return l + r;
1430 schoenebeck 2581 }
1431    
1432     void ConcatString::dump(int level) {
1433     printIndents(level);
1434     printf("ConcatString(\n");
1435     lhs->dump(level+1);
1436     printIndents(level);
1437     printf(",\n");
1438     rhs->dump(level+1);
1439     printIndents(level);
1440     printf(")");
1441     }
1442    
1443     bool ConcatString::isConstExpr() const {
1444     return lhs->isConstExpr() && rhs->isConstExpr();
1445     }
1446    
1447 schoenebeck 3581 Relation::Relation(ExpressionRef lhs, Type type, ExpressionRef rhs) :
1448     Unit(VM_NO_UNIT),
1449     lhs(lhs), rhs(rhs), type(type)
1450     {
1451     }
1452    
1453     // Equal / unequal comparison of real numbers in NKSP scripts:
1454     //
1455     // Unlike system level languages like C/C++ we are less conservative about
1456     // comparing floating point numbers for 'equalness' or 'unequalness' in NKSP
1457     // scripts. Due to the musical context of the NKSP language we automatically
1458     // take the (to be) expected floating point tolerances into account when
1459     // comparing two floating point numbers with each other, however only for '='
1460     // and '#' operators. The '<=' and '>=' still use conservative low level
1461     // floating point comparison for not breaking their transitivity feature.
1462    
1463     template<typename T_LHS, typename T_RHS>
1464     struct RelComparer {
1465     static inline bool isEqual(T_LHS a, T_RHS b) { // for int comparison ('3 = 3')
1466     return a == b;
1467     }
1468     static inline bool isUnequal(T_LHS a, T_RHS b) { // for int comparison ('3 # 3')
1469     return a != b;
1470     }
1471     };
1472    
1473     template<>
1474     struct RelComparer<float,float> {
1475     static inline bool isEqual(float a, float b) { // for real number comparison ('3.1 = 3.1')
1476     return RTMath::fEqual32(a, b);
1477     }
1478     static inline bool isUnequal(float a, float b) { // for real number comparison ('3.1 # 3.1')
1479     return !RTMath::fEqual32(a, b);
1480     }
1481     };
1482    
1483     template<>
1484     struct RelComparer<double,double> {
1485     static inline bool isEqual(double a, double b) { // for future purpose
1486     return RTMath::fEqual64(a, b);
1487     }
1488     static inline bool isUnqqual(double a, double b) { // for future purpose
1489     return !RTMath::fEqual64(a, b);
1490     }
1491     };
1492    
1493 schoenebeck 3573 template<class T_LHS, class T_RHS>
1494 schoenebeck 3581 inline vmint _evalRelation(Relation::Type type, T_LHS lhs, T_RHS rhs) {
1495 schoenebeck 3573 switch (type) {
1496     case Relation::LESS_THAN:
1497     return lhs < rhs;
1498     case Relation::GREATER_THAN:
1499     return lhs > rhs;
1500     case Relation::LESS_OR_EQUAL:
1501     return lhs <= rhs;
1502     case Relation::GREATER_OR_EQUAL:
1503     return lhs >= rhs;
1504     case Relation::EQUAL:
1505 schoenebeck 3581 return RelComparer<typeof(lhs),typeof(rhs)>::isEqual(lhs, rhs);
1506 schoenebeck 3573 case Relation::NOT_EQUAL:
1507 schoenebeck 3581 return RelComparer<typeof(lhs),typeof(rhs)>::isUnequal(lhs, rhs);
1508 schoenebeck 3573 }
1509     return 0;
1510     }
1511    
1512 schoenebeck 3581 template<class T_LVALUE, class T_RVALUE, class T_LEXPR, class T_REXPR>
1513     inline vmint _evalRealRelation(Relation::Type type,
1514     T_LVALUE lvalue, T_RVALUE rvalue,
1515     T_LEXPR* pLHS, T_REXPR* pRHS)
1516     {
1517     if (pLHS->unitFactor() == pRHS->unitFactor())
1518     return _evalRelation(type, lvalue, rvalue);
1519     if (pLHS->unitFactor() < pRHS->unitFactor())
1520     return _evalRelation(type, lvalue, Unit::convRealToUnitFactor(rvalue, pRHS, pLHS));
1521     else
1522     return _evalRelation(type, Unit::convRealToUnitFactor(lvalue, pLHS, pRHS), rvalue);
1523     }
1524    
1525     template<class T_LEXPR, class T_REXPR>
1526     inline vmint _evalIntRelation(Relation::Type type,
1527     vmint lvalue, vmint rvalue,
1528     T_LEXPR* pLHS, T_REXPR* pRHS)
1529     {
1530     if (pLHS->unitFactor() == pRHS->unitFactor())
1531     return _evalRelation(type, lvalue, rvalue);
1532     if (pLHS->unitFactor() < pRHS->unitFactor())
1533     return _evalRelation(type, lvalue, Unit::convIntToUnitFactor(rvalue, pRHS, pLHS));
1534     else
1535     return _evalRelation(type, Unit::convIntToUnitFactor(lvalue, pLHS, pRHS), rvalue);
1536     }
1537    
1538 schoenebeck 3557 vmint Relation::evalInt() {
1539 schoenebeck 3573 const ExprType_t lType = lhs->exprType();
1540     const ExprType_t rType = rhs->exprType();
1541     if (lType == STRING_EXPR || rType == STRING_EXPR) {
1542     switch (type) {
1543     case EQUAL:
1544 schoenebeck 2581 return lhs->evalCastToStr() == rhs->evalCastToStr();
1545 schoenebeck 3573 case NOT_EQUAL:
1546 schoenebeck 2581 return lhs->evalCastToStr() != rhs->evalCastToStr();
1547 schoenebeck 3573 default:
1548     return 0;
1549     }
1550     } else if (lType == REAL_EXPR && rType == REAL_EXPR) {
1551 schoenebeck 3581 vmfloat lvalue = lhs->asReal()->evalReal();
1552     vmfloat rvalue = rhs->asReal()->evalReal();
1553     return _evalRealRelation(
1554     type, lvalue, rvalue, lhs->asReal(), rhs->asReal()
1555 schoenebeck 3573 );
1556     } else if (lType == REAL_EXPR && rType == INT_EXPR) {
1557 schoenebeck 3581 vmfloat lvalue = lhs->asReal()->evalReal();
1558     vmint rvalue = rhs->asInt()->evalInt();
1559     return _evalRealRelation(
1560     type, lvalue, rvalue, lhs->asReal(), rhs->asInt()
1561 schoenebeck 3573 );
1562     } else if (lType == INT_EXPR && rType == REAL_EXPR) {
1563 schoenebeck 3581 vmint lvalue = lhs->asInt()->evalInt();
1564     vmfloat rvalue = rhs->asReal()->evalReal();
1565     return _evalRealRelation(
1566     type, lvalue, rvalue, lhs->asInt(), rhs->asReal()
1567 schoenebeck 3573 );
1568     } else {
1569 schoenebeck 3581 vmint lvalue = lhs->asInt()->evalInt();
1570     vmint rvalue = rhs->asInt()->evalInt();
1571     return _evalIntRelation(
1572     type, lvalue, rvalue, lhs->asInt(), rhs->asInt()
1573 schoenebeck 3573 );
1574 schoenebeck 2581 }
1575     }
1576    
1577     void Relation::dump(int level) {
1578     printIndents(level);
1579     printf("Relation(\n");
1580     lhs->dump(level+1);
1581     printIndents(level);
1582     switch (type) {
1583     case LESS_THAN:
1584     printf("LESS_THAN\n");
1585     break;
1586     case GREATER_THAN:
1587     printf("GREATER_THAN\n");
1588     break;
1589     case LESS_OR_EQUAL:
1590     printf("LESS_OR_EQUAL\n");
1591     break;
1592     case GREATER_OR_EQUAL:
1593     printf("GREATER_OR_EQUAL\n");
1594     break;
1595     case EQUAL:
1596     printf("EQUAL\n");
1597     break;
1598     case NOT_EQUAL:
1599     printf("NOT_EQUAL\n");
1600     break;
1601     }
1602     rhs->dump(level+1);
1603     printIndents(level);
1604     printf(")\n");
1605     }
1606    
1607     bool Relation::isConstExpr() const {
1608     return lhs->isConstExpr() && rhs->isConstExpr();
1609     }
1610    
1611 schoenebeck 3557 vmint Or::evalInt() {
1612 schoenebeck 2581 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1613 schoenebeck 2611 if (pLHS->evalInt()) return 1;
1614 schoenebeck 3581 IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
1615 schoenebeck 2611 return (pRHS->evalInt()) ? 1 : 0;
1616 schoenebeck 2581 }
1617    
1618     void Or::dump(int level) {
1619     printIndents(level);
1620     printf("Or(\n");
1621     lhs->dump(level+1);
1622     printIndents(level);
1623     printf(",\n");
1624     rhs->dump(level+1);
1625     printIndents(level);
1626     printf(")\n");
1627     }
1628    
1629 schoenebeck 3557 vmint BitwiseOr::evalInt() {
1630 schoenebeck 2935 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1631     IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
1632     return pLHS->evalInt() | pRHS->evalInt();
1633     }
1634    
1635     void BitwiseOr::dump(int level) {
1636     printIndents(level);
1637     printf("BitwiseOr(\n");
1638     lhs->dump(level+1);
1639     printIndents(level);
1640     printf(",\n");
1641     rhs->dump(level+1);
1642     printIndents(level);
1643     printf(")\n");
1644     }
1645    
1646 schoenebeck 3557 vmint And::evalInt() {
1647 schoenebeck 2581 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1648 schoenebeck 2611 if (!pLHS->evalInt()) return 0;
1649     IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
1650     return (pRHS->evalInt()) ? 1 : 0;
1651 schoenebeck 2581 }
1652    
1653     void And::dump(int level) {
1654     printIndents(level);
1655     printf("And(\n");
1656     lhs->dump(level+1);
1657     printIndents(level);
1658     printf(",\n");
1659     rhs->dump(level+1);
1660     printIndents(level);
1661     printf(")\n");
1662     }
1663    
1664 schoenebeck 3557 vmint BitwiseAnd::evalInt() {
1665 schoenebeck 2935 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
1666     IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
1667     return pLHS->evalInt() & pRHS->evalInt();
1668     }
1669    
1670     void BitwiseAnd::dump(int level) {
1671     printIndents(level);
1672     printf("BitwiseAnd(\n");
1673     lhs->dump(level+1);
1674     printIndents(level);
1675     printf(",\n");
1676     rhs->dump(level+1);
1677     printIndents(level);
1678     printf(")\n");
1679     }
1680    
1681 schoenebeck 2581 void Not::dump(int level) {
1682     printIndents(level);
1683     printf("Not(\n");
1684     expr->dump(level+1);
1685     printIndents(level);
1686     printf(")\n");
1687     }
1688    
1689 schoenebeck 2935 void BitwiseNot::dump(int level) {
1690     printIndents(level);
1691     printf("BitwiseNot(\n");
1692     expr->dump(level+1);
1693     printIndents(level);
1694     printf(")\n");
1695     }
1696    
1697 schoenebeck 3573 String Final::evalCastToStr() {
1698     if (exprType() == REAL_EXPR)
1699     return ToString(evalReal());
1700     else
1701     return ToString(evalInt());
1702     }
1703    
1704 schoenebeck 3561 void Final::dump(int level) {
1705     printIndents(level);
1706     printf("Final(\n");
1707     expr->dump(level+1);
1708     printIndents(level);
1709     printf(")\n");
1710     }
1711    
1712 schoenebeck 2951 StatementsRef ParserContext::userFunctionByName(const String& name) {
1713     if (!userFnTable.count(name)) {
1714     return StatementsRef();
1715     }
1716     return userFnTable.find(name)->second;
1717     }
1718    
1719 schoenebeck 2581 VariableRef ParserContext::variableByName(const String& name) {
1720     if (!vartable.count(name)) {
1721     return VariableRef();
1722     }
1723     return vartable.find(name)->second;
1724     }
1725    
1726     VariableRef ParserContext::globalVar(const String& name) {
1727     if (!vartable.count(name)) {
1728     //printf("No global var '%s'\n", name.c_str());
1729     //for (std::map<String,VariableRef>::const_iterator it = vartable.begin(); it != vartable.end(); ++it)
1730     // printf("-> var '%s'\n", it->first.c_str());
1731     return VariableRef();
1732     }
1733     return vartable.find(name)->second;
1734     }
1735    
1736     IntVariableRef ParserContext::globalIntVar(const String& name) {
1737     return globalVar(name);
1738     }
1739    
1740 schoenebeck 3573 RealVariableRef ParserContext::globalRealVar(const String& name) {
1741     return globalVar(name);
1742     }
1743    
1744 schoenebeck 2581 StringVariableRef ParserContext::globalStrVar(const String& name) {
1745     return globalVar(name);
1746     }
1747    
1748 schoenebeck 2588 ParserContext::~ParserContext() {
1749     destroyScanner();
1750     if (globalIntMemory) {
1751     delete globalIntMemory;
1752     globalIntMemory = NULL;
1753     }
1754 schoenebeck 3573 if (globalRealMemory) {
1755     delete globalRealMemory;
1756     globalRealMemory = NULL;
1757     }
1758 schoenebeck 2588 }
1759    
1760 schoenebeck 2889 void ParserContext::addErr(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt) {
1761 schoenebeck 2581 ParserIssue e;
1762     e.type = PARSER_ERROR;
1763     e.txt = txt;
1764 schoenebeck 2889 e.firstLine = firstLine;
1765     e.lastLine = lastLine;
1766     e.firstColumn = firstColumn;
1767     e.lastColumn = lastColumn;
1768 schoenebeck 2588 vErrors.push_back(e);
1769     vIssues.push_back(e);
1770 schoenebeck 2581 }
1771    
1772 schoenebeck 2889 void ParserContext::addWrn(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt) {
1773 schoenebeck 2581 ParserIssue w;
1774     w.type = PARSER_WARNING;
1775     w.txt = txt;
1776 schoenebeck 2889 w.firstLine = firstLine;
1777     w.lastLine = lastLine;
1778     w.firstColumn = firstColumn;
1779     w.lastColumn = lastColumn;
1780 schoenebeck 2588 vWarnings.push_back(w);
1781     vIssues.push_back(w);
1782 schoenebeck 2581 }
1783    
1784 schoenebeck 3285 void ParserContext::addPreprocessorComment(int firstLine, int lastLine, int firstColumn, int lastColumn) {
1785     CodeBlock block;
1786     block.firstLine = firstLine;
1787     block.lastLine = lastLine;
1788     block.firstColumn = firstColumn;
1789     block.lastColumn = lastColumn;
1790     vPreprocessorComments.push_back(block);
1791     }
1792    
1793 schoenebeck 2581 bool ParserContext::setPreprocessorCondition(const char* name) {
1794     if (builtinPreprocessorConditions.count(name)) return false;
1795     if (userPreprocessorConditions.count(name)) return false;
1796     userPreprocessorConditions.insert(name);
1797     return true;
1798     }
1799    
1800     bool ParserContext::resetPreprocessorCondition(const char* name) {
1801     if (builtinPreprocessorConditions.count(name)) return false;
1802     if (!userPreprocessorConditions.count(name)) return false;
1803     userPreprocessorConditions.erase(name);
1804     return true;
1805     }
1806    
1807     bool ParserContext::isPreprocessorConditionSet(const char* name) {
1808     if (builtinPreprocessorConditions.count(name)) return true;
1809     return userPreprocessorConditions.count(name);
1810     }
1811    
1812 schoenebeck 2588 std::vector<ParserIssue> ParserContext::issues() const {
1813     return vIssues;
1814     }
1815    
1816     std::vector<ParserIssue> ParserContext::errors() const {
1817     return vErrors;
1818     }
1819    
1820     std::vector<ParserIssue> ParserContext::warnings() const {
1821     return vWarnings;
1822     }
1823    
1824 schoenebeck 3285 std::vector<CodeBlock> ParserContext::preprocessorComments() const {
1825     return vPreprocessorComments;
1826     }
1827    
1828 schoenebeck 2588 VMEventHandler* ParserContext::eventHandler(uint index) {
1829     if (!handlers) return NULL;
1830     return handlers->eventHandler(index);
1831     }
1832    
1833     VMEventHandler* ParserContext::eventHandlerByName(const String& name) {
1834     if (!handlers) return NULL;
1835     return handlers->eventHandlerByName(name);
1836     }
1837    
1838 schoenebeck 3557 void ParserContext::registerBuiltInConstIntVariables(const std::map<String,vmint>& vars) {
1839     for (std::map<String,vmint>::const_iterator it = vars.begin();
1840 schoenebeck 2594 it != vars.end(); ++it)
1841     {
1842 schoenebeck 3581 ConstIntVariableRef ref = new ConstIntVariable({
1843     .value = it->second
1844     });
1845 schoenebeck 2594 vartable[it->first] = ref;
1846     }
1847     }
1848    
1849 schoenebeck 3557 void ParserContext::registerBuiltInIntVariables(const std::map<String,VMIntPtr*>& vars) {
1850     for (std::map<String,VMIntPtr*>::const_iterator it = vars.begin();
1851 schoenebeck 2594 it != vars.end(); ++it)
1852     {
1853     BuiltInIntVariableRef ref = new BuiltInIntVariable(it->first, it->second);
1854     vartable[it->first] = ref;
1855     }
1856     }
1857    
1858     void ParserContext::registerBuiltInIntArrayVariables(const std::map<String,VMInt8Array*>& vars) {
1859     for (std::map<String,VMInt8Array*>::const_iterator it = vars.begin();
1860     it != vars.end(); ++it)
1861     {
1862     BuiltInIntArrayVariableRef ref = new BuiltInIntArrayVariable(it->first, it->second);
1863     vartable[it->first] = ref;
1864     }
1865     }
1866    
1867 schoenebeck 2942 void ParserContext::registerBuiltInDynVariables(const std::map<String,VMDynVar*>& vars) {
1868     for (std::map<String,VMDynVar*>::const_iterator it = vars.begin();
1869     it != vars.end(); ++it)
1870     {
1871     DynamicVariableCallRef ref = new DynamicVariableCall(it->first, this, it->second);
1872     vartable[it->first] = ref;
1873     }
1874     }
1875    
1876 schoenebeck 3551 ExecContext::ExecContext() :
1877     status(VM_EXEC_NOT_RUNNING), flags(STMT_SUCCESS), stackFrame(-1),
1878     suspendMicroseconds(0), instructionsCount(0)
1879     {
1880     exitRes.value = NULL;
1881     }
1882    
1883 schoenebeck 3293 void ExecContext::forkTo(VMExecContext* ectx) const {
1884     ExecContext* child = dynamic_cast<ExecContext*>(ectx);
1885    
1886     child->polyphonicIntMemory.copyFlatFrom(polyphonicIntMemory);
1887 schoenebeck 3573 child->polyphonicRealMemory.copyFlatFrom(polyphonicRealMemory);
1888 schoenebeck 3293 child->status = VM_EXEC_SUSPENDED;
1889     child->flags = STMT_SUCCESS;
1890     child->stack.copyFlatFrom(stack);
1891     child->stackFrame = stackFrame;
1892     child->suspendMicroseconds = 0;
1893     child->instructionsCount = 0;
1894     }
1895    
1896 schoenebeck 2581 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC