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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3846 - (show annotations) (download)
Wed Jan 6 14:01:11 2021 UTC (3 years, 3 months ago) by schoenebeck
File size: 61905 byte(s)
* ScriptVM: Fixed crash when handling array results of built-in
  functions (e.g. "num_elements(by_marks($MARK_1)").

* Bumped version (2.1.1.svn69).

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

  ViewVC Help
Powered by ViewVC