/[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 3585 - (show annotations) (download)
Fri Aug 30 17:51:24 2019 UTC (4 years, 6 months ago) by schoenebeck
File size: 56337 byte(s)
NKSP: Cleanup regarding multiple data types for built-in function args.

* NKSP VM API cleanup: Get rid of legacy method
  VMFunction::argType(vmint iArg) which was already superseded by its new
  replacement VMFunction::acceptsArgType(vmint iArg, ExprType_t type).

* NKSP parser: if wrong argument type was passed to a built-in function and
  that built-in function accepts more than one data type for the argument,
  then show all supported data types as parser error message.

* Bumped version (2.1.1.svn10).

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

  ViewVC Help
Powered by ViewVC