/[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 3595 - (hide annotations) (download)
Tue Sep 3 11:06:33 2019 UTC (4 years, 7 months ago) by schoenebeck
File size: 56698 byte(s)
* Fixed compiler errors with GCC 8.x.
* Bumped version (2.1.1.svn16).

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

  ViewVC Help
Powered by ViewVC