/[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 3729 - (hide annotations) (download)
Fri Jan 31 10:57:53 2020 UTC (4 years, 2 months ago) by schoenebeck
File size: 58415 byte(s)
NKSP parser: track code locations also by raw byte position and length.

* NKSP VM API: Added member variables 'firstByte' and 'lengthBytes' to
  struct 'CodeBlock'.

* NKSP Editor API: Added methods firstByte() and lengthBytes() to
  class 'VMSourceToken'.

* NKSP VM language parser: track all positions also by raw byte offset
  and length (along to the already existing tracking by line/column).

* NKSP editor syntax highlighting scanner: track all positions also by
  raw byte offset and length (along to the already existing tracking by
  line/column).

* Bumped version (2.1.1.svn45).

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

  ViewVC Help
Powered by ViewVC