/[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 3845 - (show annotations) (download)
Tue Jan 5 20:42:32 2021 UTC (3 years, 3 months ago) by schoenebeck
File size: 61189 byte(s)
* ScriptVM: Fixed incorrect polyphonic data transfer from wrong "note"
  handler to "release" handler; which also fixes no "release" handler
  being executed sometimes, and due to the latter it also fixes potential
  crashes as some polyphonic script events were never released and the
  engine hence was running out of free script events.

* Bumped version (2.1.1.svn68).

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

  ViewVC Help
Powered by ViewVC