/[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 3792 - (show annotations) (download)
Mon Jun 15 15:26:10 2020 UTC (3 years, 10 months ago) by schoenebeck
File size: 60399 byte(s)
* NKSP language: emit warning if an array variable was declared with bigger
  array size than amount of initial values been assigned, and initialize the
  missing array elements with zero in this case.

* Bumped version (2.1.1.svn60).

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

  ViewVC Help
Powered by ViewVC