/[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 3561 - (show annotations) (download)
Fri Aug 23 11:44:00 2019 UTC (4 years, 8 months ago) by schoenebeck
File size: 32914 byte(s)
NKSP: Added standard units support for numbers and final "!" operator:

* NKSP strictness: Variable names, function names and preprocessor condition
  names must start with a regular character (a-z or A-Z); starting them with
  a digit or underscore is no longer allowed.

* NKSP parser fix: equal comparison operator "=" and not equal comparison
  operator "#" must only accept integer operands.

* NKSP language: Implemented support for standard units like Hertz, seconds,
  Bel including support for metric unit prefixes; so one can now e.g.
  conveniently use numbers in scripts like "5us" meaning "5 microseconds",
  or e.g. "12kHz" meaning "12 kilo Hertz", or e.g. "-14mdB" meaning
  "minus 14 Millidecibel", or e.g. "28c" meaning "28 cents" (for tuning).

* NKSP language: Introduced "final" operator "!" which is specifically
  intended for synthesis parameter values to denote that the synthesis
  parameter value is intended to be the "final" value for that synthesis
  parameter that should explicitly be used by the engine and thus causing
  the sampler engine to ignore all other modulation sources for the same
  synthesis parameter (like e.g. LFO, EG); by simply prefixing a value,
  variable or formula with this new "!" operator the expression is marked as
  being "final".

* Bumped version (2.1.1.svn4).

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 <assert.h>
15
16 namespace LinuxSampler {
17
18 bool isNoOperation(StatementRef statement) {
19 return statement->statementType() == STMT_NOOP;
20 }
21
22 Node::Node() {
23 }
24
25 Node::~Node() {
26 }
27
28 void Node::printIndents(int n) {
29 for (int i = 0; i < n; ++i) printf(" ");
30 fflush(stdout);
31 }
32
33 String IntExpr::evalCastToStr() {
34 return ToString(evalInt());
35 }
36
37 String IntArrayExpr::evalCastToStr() {
38 String s = "{";
39 for (vmint i = 0; i < arraySize(); ++i) {
40 vmint val = evalIntElement(i);
41 if (i) s += ",";
42 s += ToString(val);
43 }
44 s += "}";
45 return s;
46 }
47
48 MetricPrefix_t Unit::unitPrefix(vmuint i) const {
49 if (i >= prefix.size()) return VM_NO_PREFIX;
50 return prefix[i];
51 }
52
53 void Unit::setUnit(const std::vector<MetricPrefix_t>& prefix, StdUnit_t type) {
54 this->prefix.resize( prefix.size() );
55 for (vmuint i = 0; i < prefix.size(); ++i)
56 this->prefix[i] = prefix[i];
57
58 unit = type;
59 }
60
61 void Unit::setUnit(const MetricPrefix_t* prefixes, StdUnit_t type) {
62 unit = type;
63 prefix.clear();
64 for (int i = 0; i < 2 && prefixes[i]; ++i)
65 prefix.add(prefixes[i]);
66 }
67
68 void Unit::copyUnitFrom(const IntExprRef& src) {
69 unit = src->unitType();
70 prefix.clear();
71 for (int i = 0; true; ++i) {
72 MetricPrefix_t p = src->unitPrefix(i);
73 if (!p) return;
74 prefix.add(p);
75 }
76 }
77
78 vmint IntLiteral::evalInt() {
79 return value;
80 }
81
82 void IntLiteral::dump(int level) {
83 printIndents(level);
84 printf("IntLiteral %lld\n", value);
85 }
86
87 void StringLiteral::dump(int level) {
88 printIndents(level);
89 printf("StringLiteral: '%s'\n", value.c_str());
90 }
91
92 vmint Add::evalInt() {
93 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
94 IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;
95 return (pLHS && pRHS) ? pLHS->evalInt() + pRHS->evalInt() : 0;
96 }
97
98 void Add::dump(int level) {
99 printIndents(level);
100 printf("Add(\n");
101 lhs->dump(level+1);
102 printIndents(level);
103 printf(",\n");
104 rhs->dump(level+1);
105 printIndents(level);
106 printf(")\n");
107 }
108
109 vmint Sub::evalInt() {
110 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
111 IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;
112 return (pLHS && pRHS) ? pLHS->evalInt() - pRHS->evalInt() : 0;
113 }
114
115 void Sub::dump(int level) {
116 printIndents(level);
117 printf("Sub(\n");
118 lhs->dump(level+1);
119 printIndents(level);
120 printf(",\n");
121 rhs->dump(level+1);
122 printIndents(level);
123 printf(")\n");
124 }
125
126 vmint Mul::evalInt() {
127 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
128 IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;
129 return (pLHS && pRHS) ? pLHS->evalInt() * pRHS->evalInt() : 0;
130 }
131
132 void Mul::dump(int level) {
133 printIndents(level);
134 printf("Mul(\n");
135 lhs->dump(level+1);
136 printIndents(level);
137 printf(",\n");
138 rhs->dump(level+1);
139 printIndents(level);
140 printf(")\n");
141 }
142
143 MetricPrefix_t Mul::unitPrefix(vmuint i) const {
144 const IntExpr* pLHS = dynamic_cast<const IntExpr*>(&*lhs);
145 const IntExpr* pRHS = dynamic_cast<const IntExpr*>(&*rhs);
146 // currently the NKSP parser only allows a unit prefix on either side
147 return (pLHS->unitPrefix(0)) ? pLHS->unitPrefix(i) : pRHS->unitPrefix(i);
148 }
149
150 StdUnit_t Mul::unitType() const {
151 const IntExpr* pLHS = dynamic_cast<const IntExpr*>(&*lhs);
152 const IntExpr* pRHS = dynamic_cast<const IntExpr*>(&*rhs);
153 // currently the NKSP parser only allows a unit type on either side
154 return (pLHS->unitType()) ? pLHS->unitType() : pRHS->unitType();
155 }
156
157 vmint Div::evalInt() {
158 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
159 IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
160 if (!pLHS || !pRHS) return 0;
161 vmint l = pLHS->evalInt();
162 vmint r = pRHS->evalInt();
163 if (r == 0) return 0;
164 return l / r;
165 }
166
167 void Div::dump(int level) {
168 printIndents(level);
169 printf("Div(\n");
170 lhs->dump(level+1);
171 printIndents(level);
172 printf(",\n");
173 rhs->dump(level+1);
174 printIndents(level);
175 printf(")\n");
176 }
177
178 MetricPrefix_t Div::unitPrefix(vmuint i) const {
179 const IntExpr* pLHS = dynamic_cast<const IntExpr*>(&*lhs);
180 const IntExpr* pRHS = dynamic_cast<const IntExpr*>(&*rhs);
181 // currently the NKSP parser only allows either A) a unit prefix on left
182 // side and none on right side or B) an identical unit prefix on both sides
183 return (pLHS->unitPrefix(0) && pRHS->unitPrefix(0)) ? VM_NO_PREFIX : pLHS->unitPrefix(i);
184 }
185
186 StdUnit_t Div::unitType() const {
187 const IntExpr* pLHS = dynamic_cast<const IntExpr*>(&*lhs);
188 const IntExpr* pRHS = dynamic_cast<const IntExpr*>(&*rhs);
189 // the NKSP parser only allows either A) a unit type on left side and none
190 // on right side or B) an identical unit type on both sides
191 return (pLHS->unitType() && pRHS->unitType()) ? VM_NO_UNIT : pLHS->unitType();
192 }
193
194 vmint Mod::evalInt() {
195 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
196 IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;
197 return (pLHS && pRHS) ? pLHS->evalInt() % pRHS->evalInt() : 0;
198 }
199
200 void Mod::dump(int level) {
201 printIndents(level);
202 printf("Mod(\n");
203 lhs->dump(level+1);
204 printIndents(level);
205 printf(",\n");
206 rhs->dump(level+1);
207 printIndents(level);
208 printf(")\n");
209 }
210
211 void Args::dump(int level) {
212 printIndents(level);
213 printf("Args(\n");
214 for (std::vector<ExpressionRef>::iterator it = args.begin() ; it != args.end() ; ++it) {
215 (*it)->dump(level+1);
216 }
217 printIndents(level);
218 printf(")\n");
219 }
220
221 bool Args::isPolyphonic() const {
222 for (vmint i = 0; i < args.size(); ++i)
223 if (args[i]->isPolyphonic())
224 return true;
225 return false;
226 }
227
228 EventHandlers::EventHandlers() {
229 //printf("EventHandlers::Constructor 0x%lx\n", (long long)this);
230 }
231
232 EventHandlers::~EventHandlers() {
233 }
234
235 void EventHandlers::add(EventHandlerRef arg) {
236 args.push_back(arg);
237 }
238
239 void EventHandlers::dump(int level) {
240 printIndents(level);
241 printf("EventHandlers {\n");
242 for (std::vector<EventHandlerRef>::iterator it = args.begin() ; it != args.end() ; ++it) {
243 (*it)->dump(level+1);
244 }
245 printIndents(level);
246 printf("}\n");
247 }
248
249 EventHandler* EventHandlers::eventHandlerByName(const String& name) const {
250 for (vmint i = 0; i < args.size(); ++i)
251 if (args.at(i)->eventHandlerName() == name)
252 return const_cast<EventHandler*>(&*args.at(i));
253 return NULL;
254 }
255
256 EventHandler* EventHandlers::eventHandler(uint index) const {
257 if (index >= args.size()) return NULL;
258 return const_cast<EventHandler*>(&*args.at(index));
259 }
260
261 bool EventHandlers::isPolyphonic() const {
262 for (vmint i = 0; i < args.size(); ++i)
263 if (args[i]->isPolyphonic())
264 return true;
265 return false;
266 }
267
268 Assignment::Assignment(VariableRef variable, ExpressionRef value)
269 : variable(variable), value(value)
270 {
271 }
272
273 void Assignment::dump(int level) {
274 printIndents(level);
275 printf("Assignment\n");
276 }
277
278 StmtFlags_t Assignment::exec() {
279 if (!variable)
280 return StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
281 variable->assign(&*value);
282 return STMT_SUCCESS;
283 }
284
285 EventHandler::EventHandler(StatementsRef statements) {
286 this->statements = statements;
287 usingPolyphonics = statements->isPolyphonic();
288 }
289
290 void EventHandler::dump(int level) {
291 printIndents(level);
292 printf("EventHandler {\n");
293 statements->dump(level+1);
294 printIndents(level);
295 printf("}\n");
296 }
297
298 void Statements::dump(int level) {
299 printIndents(level);
300 printf("Statements {\n");
301 for (std::vector<StatementRef>::iterator it = args.begin() ; it != args.end() ; ++it) {
302 (*it)->dump(level+1);
303 }
304 printIndents(level);
305 printf("}\n");
306 }
307
308 Statement* Statements::statement(uint i) {
309 if (i >= args.size()) return NULL;
310 return &*args.at(i);
311 }
312
313 bool Statements::isPolyphonic() const {
314 for (vmint i = 0; i < args.size(); ++i)
315 if (args[i]->isPolyphonic())
316 return true;
317 return false;
318 }
319
320 DynamicVariableCall::DynamicVariableCall(const String& name, ParserContext* ctx, VMDynVar* v)
321 : Variable(ctx, 0, false), dynVar(v), varName(name)
322 {
323 }
324
325 vmint DynamicVariableCall::evalInt() {
326 VMIntExpr* expr = dynamic_cast<VMIntExpr*>(dynVar);
327 if (!expr) return 0;
328 return expr->evalInt();
329 }
330
331 String DynamicVariableCall::evalStr() {
332 VMStringExpr* expr = dynamic_cast<VMStringExpr*>(dynVar);
333 if (!expr) return "";
334 return expr->evalStr();
335 }
336
337 String DynamicVariableCall::evalCastToStr() {
338 if (dynVar->exprType() == STRING_EXPR) {
339 return evalStr();
340 } else {
341 VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(dynVar);
342 return intExpr ? ToString(intExpr->evalInt()) : "";
343 }
344 }
345
346 void DynamicVariableCall::dump(int level) {
347 printIndents(level);
348 printf("Dynamic Variable '%s'\n", varName.c_str());
349 }
350
351 void FunctionCall::dump(int level) {
352 printIndents(level);
353 printf("FunctionCall '%s' args={\n", functionName.c_str());
354 args->dump(level+1);
355 printIndents(level);
356 printf("}\n");
357 }
358
359 ExprType_t FunctionCall::exprType() const {
360 if (!fn) return EMPTY_EXPR;
361 return fn->returnType();
362 }
363
364 VMFnResult* FunctionCall::execVMFn() {
365 if (!fn) return NULL;
366 // assuming here that all argument checks (amount and types) have been made
367 // at parse time, to avoid time intensive checks on each function call
368 return fn->exec(dynamic_cast<VMFnArgs*>(&*args));
369 }
370
371 StmtFlags_t FunctionCall::exec() {
372 VMFnResult* result = execVMFn();
373 if (!result)
374 return StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED);
375 return result->resultFlags();
376 }
377
378 vmint FunctionCall::evalInt() {
379 VMFnResult* result = execVMFn();
380 if (!result) return 0;
381 VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());
382 if (!intExpr) return 0;
383 return intExpr->evalInt();
384 }
385
386 VMIntArrayExpr* FunctionCall::asIntArray() const {
387 VMFnResult* result = const_cast<FunctionCall*>(this)->execVMFn();
388 if (!result) return 0;
389 VMIntArrayExpr* intArrExpr = dynamic_cast<VMIntArrayExpr*>(result->resultValue());
390 return intArrExpr;
391 }
392
393 String FunctionCall::evalStr() {
394 VMFnResult* result = execVMFn();
395 if (!result) return "";
396 VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());
397 if (!strExpr) return "";
398 return strExpr->evalStr();
399 }
400
401 String FunctionCall::evalCastToStr() {
402 VMFnResult* result = execVMFn();
403 if (!result) return "";
404 if (result->resultValue()->exprType() == STRING_EXPR) {
405 VMStringExpr* strExpr = dynamic_cast<VMStringExpr*>(result->resultValue());
406 return strExpr ? strExpr->evalStr() : "";
407 } else {
408 VMIntExpr* intExpr = dynamic_cast<VMIntExpr*>(result->resultValue());
409 return intExpr ? ToString(intExpr->evalInt()) : "";
410 }
411 }
412
413 IntVariable::IntVariable(ParserContext* ctx)
414 : Variable(ctx, ctx ? ctx->globalIntVarCount++ : 0, false),
415 Unit(),
416 polyphonic(false), finalVal(false)
417 {
418 //printf("globalIntVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);
419 assert(ctx);
420 }
421
422 inline static vmint postfixInc(vmint& object, vmint incBy) {
423 const vmint i = object;
424 object += incBy;
425 return i;
426 }
427
428 IntVariable::IntVariable(ParserContext* ctx, bool polyphonic, bool bConst, vmint size)
429 : Variable(ctx, !ctx ? 0 : polyphonic ? postfixInc(ctx->polyphonicIntVarCount, size) : postfixInc(ctx->globalIntVarCount, size), bConst),
430 Unit(),
431 polyphonic(polyphonic), finalVal(false)
432 {
433 //printf("InvVar size=%d parserCtx=0x%lx\n", size, (uint64_t)ctx);
434 if (polyphonic) {
435 //printf("polyIntVar memPOS=%d\n", memPos);
436 assert(ctx);
437 }
438 }
439
440 void IntVariable::assign(Expression* expr) {
441 IntExpr* intExpr = dynamic_cast<IntExpr*>(expr);
442 if (intExpr) {
443 if (polyphonic)
444 context->execContext->polyphonicIntMemory[memPos] = intExpr->evalInt();
445 else
446 (*context->globalIntMemory)[memPos] = intExpr->evalInt();
447 }
448 }
449
450 vmint IntVariable::evalInt() {
451 //printf("IntVariable::eval pos=%d\n", memPos);
452 if (polyphonic) {
453 //printf("evalInt() poly memPos=%d execCtx=0x%lx\n", memPos, (uint64_t)context->execContext);
454 return context->execContext->polyphonicIntMemory[memPos];
455 }
456 return (*context->globalIntMemory)[memPos];
457 }
458
459 void IntVariable::dump(int level) {
460 printIndents(level);
461 printf("IntVariable\n");
462 //printf("IntVariable memPos=%d\n", memPos);
463 }
464
465 //ConstIntVariable::ConstIntVariable(ParserContext* ctx, int value)
466 ConstIntVariable::ConstIntVariable(vmint value)
467 : IntVariable(NULL,false,true), value(value)
468 {
469 }
470
471 void ConstIntVariable::assign(Expression* expr) {
472 // ignore assignment
473 /*
474 printf("ConstIntVariable::assign()\n");
475 IntExpr* intExpr = dynamic_cast<IntExpr*>(expr);
476 if (intExpr) {
477 value = intExpr->evalInt();
478 }
479 */
480 }
481
482 vmint ConstIntVariable::evalInt() {
483 return value;
484 }
485
486 void ConstIntVariable::dump(int level) {
487 printIndents(level);
488 printf("ConstIntVariable val=%lld\n", value);
489 }
490
491 BuiltInIntVariable::BuiltInIntVariable(const String& name, VMIntPtr* ptr)
492 : IntVariable(NULL,false,false), name(name), ptr(ptr)
493 {
494 }
495
496 void BuiltInIntVariable::assign(Expression* expr) {
497 IntExpr* valueExpr = dynamic_cast<IntExpr*>(expr);
498 if (!valueExpr) return;
499 ptr->assign(valueExpr->evalInt());
500 }
501
502 vmint BuiltInIntVariable::evalInt() {
503 return ptr->evalInt();
504 }
505
506 void BuiltInIntVariable::dump(int level) {
507 printIndents(level);
508 printf("Built-in IntVar '%s'\n", name.c_str());
509 }
510
511 PolyphonicIntVariable::PolyphonicIntVariable(ParserContext* ctx)
512 : IntVariable(ctx,true,false)
513 {
514 }
515
516 void PolyphonicIntVariable::dump(int level) {
517 printIndents(level);
518 printf("PolyphonicIntVariable\n");
519 }
520
521 IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size)
522 : Variable(ctx, 0, false)
523 {
524 values.resize(size);
525 memset(&values[0], 0, size * sizeof(vmint));
526 }
527
528 IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size, ArgsRef values, bool _bConst)
529 : Variable(ctx, 0, _bConst)
530 {
531 this->values.resize(size);
532 for (vmint i = 0; i < values->argsCount(); ++i) {
533 VMIntExpr* expr = dynamic_cast<VMIntExpr*>(values->arg(i));
534 if (expr) this->values[i] = expr->evalInt();
535 }
536 }
537
538 IntArrayVariable::IntArrayVariable(ParserContext* ctx, bool bConst)
539 : Variable(ctx, 0, bConst)
540 {
541 }
542
543 vmint IntArrayVariable::evalIntElement(vmuint i) {
544 if (i >= values.size()) return 0;
545 return values[i];
546 }
547
548 void IntArrayVariable::assignIntElement(vmuint i, vmint value) {
549 if (i >= values.size()) return;
550 values[i] = value;
551 }
552
553 void IntArrayVariable::dump(int level) {
554 printIndents(level);
555 printf("IntArray(");
556 for (vmint i = 0; i < values.size(); ++i) {
557 if (i % 12 == 0) {
558 printf("\n");
559 printIndents(level+1);
560 }
561 printf("%lld, ", values[i]);
562 }
563 printIndents(level);
564 printf(")\n");
565 }
566
567 BuiltInIntArrayVariable::BuiltInIntArrayVariable(const String& name, VMInt8Array* array)
568 : IntArrayVariable(NULL, false), name(name), array(array)
569 {
570 }
571
572 vmint BuiltInIntArrayVariable::evalIntElement(vmuint i) {
573 return i >= array->size ? 0 : array->data[i];
574 }
575
576 void BuiltInIntArrayVariable::assignIntElement(vmuint i, vmint value) {
577 if (i >= array->size) return;
578 array->data[i] = value;
579 }
580
581 void BuiltInIntArrayVariable::dump(int level) {
582 printIndents(level);
583 printf("Built-In Int Array Variable '%s'\n", name.c_str());
584 }
585
586 IntArrayElement::IntArrayElement(IntArrayExprRef array, IntExprRef arrayIndex)
587 : IntVariable(NULL, false, false, 0), array(array), index(arrayIndex)
588 {
589 }
590
591 void IntArrayElement::assign(Expression* expr) {
592 IntExpr* valueExpr = dynamic_cast<IntExpr*>(expr);
593 if (!valueExpr) return;
594 vmint value = valueExpr->evalInt();
595
596 if (!index) return;
597 vmint idx = index->evalInt();
598 if (idx < 0 || idx >= array->arraySize()) return;
599
600 array->assignIntElement(idx, value);
601 }
602
603 vmint IntArrayElement::evalInt() {
604 if (!index) return 0;
605 vmint idx = index->evalInt();
606 if (idx < 0 || idx >= array->arraySize()) return 0;
607
608 return array->evalIntElement(idx);
609 }
610
611 void IntArrayElement::dump(int level) {
612 printIndents(level);
613 printf("IntArrayElement\n");
614 }
615
616 StringVariable::StringVariable(ParserContext* ctx)
617 : Variable(ctx,ctx->globalStrVarCount++,false)
618 {
619 }
620
621 StringVariable::StringVariable(ParserContext* ctx, bool bConst)
622 : Variable(ctx,0,bConst)
623 {
624 }
625
626 void StringVariable::assign(Expression* expr) {
627 StringExpr* strExpr = dynamic_cast<StringExpr*>(expr);
628 (*context->globalStrMemory)[memPos] = strExpr->evalStr();
629 }
630
631 String StringVariable::evalStr() {
632 //printf("StringVariable::eval pos=%d\n", memPos);
633 return (*context->globalStrMemory)[memPos];
634 }
635
636 void StringVariable::dump(int level) {
637 printIndents(level);
638 printf("StringVariable memPos=%lld\n", memPos);
639 }
640
641 ConstStringVariable::ConstStringVariable(ParserContext* ctx, String _value)
642 : StringVariable(ctx,true), value(_value)
643 {
644 }
645
646 void ConstStringVariable::assign(Expression* expr) {
647 // ignore assignment
648 // StringExpr* strExpr = dynamic_cast<StringExpr*>(expr);
649 // if (strExpr) value = strExpr->evalStr();
650 }
651
652 String ConstStringVariable::evalStr() {
653 return value;
654 }
655
656 void ConstStringVariable::dump(int level) {
657 printIndents(level);
658 printf("ConstStringVariable val='%s'\n", value.c_str());
659 }
660
661 MetricPrefix_t IntBinaryOp::unitPrefix(vmuint i) const {
662 IntExprRef l = (IntExprRef) lhs;
663 IntExprRef r = (IntExprRef) rhs;
664 return (r->unitFactor() < l->unitFactor()) ? r->unitPrefix(i) : l->unitPrefix(i);
665 }
666
667 StdUnit_t IntBinaryOp::unitType() const {
668 IntExprRef l = (IntExprRef) lhs;
669 IntExprRef r = (IntExprRef) rhs;
670 return (l->unitType()) ? l->unitType() : r->unitType();
671 }
672
673 bool IntBinaryOp::isFinal() const {
674 IntExprRef l = (IntExprRef) lhs;
675 IntExprRef r = (IntExprRef) rhs;
676 return l->isFinal() || r->isFinal();
677 }
678
679 void If::dump(int level) {
680 printIndents(level);
681 if (ifStatements && elseStatements)
682 printf("if cond stmts1 else stmts2 end if\n");
683 else if (ifStatements)
684 printf("if cond statements end if\n");
685 else
686 printf("if [INVALID]\n");
687 }
688
689 vmint If::evalBranch() {
690 if (condition->evalInt()) return 0;
691 if (elseStatements) return 1;
692 return -1;
693 }
694
695 Statements* If::branch(vmuint i) const {
696 if (i == 0) return (Statements*) &*ifStatements;
697 if (i == 1) return (elseStatements) ? (Statements*) &*elseStatements : NULL;
698 return NULL;
699 }
700
701 bool If::isPolyphonic() const {
702 if (condition->isPolyphonic() || ifStatements->isPolyphonic())
703 return true;
704 return elseStatements ? elseStatements->isPolyphonic() : false;
705 }
706
707 void SelectCase::dump(int level) {
708 printIndents(level);
709 if (select)
710 if (select->isConstExpr())
711 printf("Case select %lld\n", select->evalInt());
712 else
713 printf("Case select [runtime expr]\n");
714 else
715 printf("Case select NULL\n");
716 for (vmint i = 0; i < branches.size(); ++i) {
717 printIndents(level+1);
718 CaseBranch& branch = branches[i];
719 if (branch.from && branch.to)
720 if (branch.from->isConstExpr() && branch.to->isConstExpr())
721 printf("case %lld to %lld\n", branch.from->evalInt(), branch.to->evalInt());
722 else if (branch.from->isConstExpr() && !branch.to->isConstExpr())
723 printf("case %lld to [runtime expr]\n", branch.from->evalInt());
724 else if (!branch.from->isConstExpr() && branch.to->isConstExpr())
725 printf("case [runtime expr] to %lld\n", branch.to->evalInt());
726 else
727 printf("case [runtime expr] to [runtime expr]\n");
728 else if (branch.from)
729 if (branch.from->isConstExpr())
730 printf("case %lld\n", branch.from->evalInt());
731 else
732 printf("case [runtime expr]\n");
733 else
734 printf("case NULL\n");
735 }
736 }
737
738 vmint SelectCase::evalBranch() {
739 vmint value = select->evalInt();
740 for (vmint i = 0; i < branches.size(); ++i) {
741 if (branches.at(i).from && branches.at(i).to) { // i.e. "case 4 to 7" ...
742 if (branches.at(i).from->evalInt() <= value &&
743 branches.at(i).to->evalInt() >= value) return i;
744 } else { // i.e. "case 5" ...
745 if (branches.at(i).from->evalInt() == value) return i;
746 }
747 }
748 return -1;
749 }
750
751 Statements* SelectCase::branch(vmuint i) const {
752 if (i < branches.size())
753 return const_cast<Statements*>( &*branches[i].statements );
754 return NULL;
755 }
756
757 bool SelectCase::isPolyphonic() const {
758 if (select->isPolyphonic()) return true;
759 for (vmint i = 0; i < branches.size(); ++i)
760 if (branches[i].statements->isPolyphonic())
761 return true;
762 return false;
763 }
764
765 // void Case::addBranch(IntExprRef condition, StatementsRef statements) {
766 // CaseBranchRef b = new CaseBranchRef;
767 // b->from = condition;
768 // b->statements = statements;
769 // branches.push_back(b);
770 // }
771 //
772 // void Case::addBranch(IntExprRef from, IntExprRef to, StatementsRef statements) {
773 // CaseBranchRef b = new CaseBranchRef;
774 // b->from = from;
775 // b->to = to;
776 // b->statements = statements;
777 // branches.push_back(b);
778 // }
779 //
780 // void Case::addBranch(CaseBranchRef branch) {
781 // branches.push_back(branch);
782 // }
783
784 void While::dump(int level) {
785 printIndents(level);
786 if (m_condition)
787 if (m_condition->isConstExpr())
788 printf("while (%lld) {\n", m_condition->evalInt());
789 else
790 printf("while ([runtime expr]) {\n");
791 else
792 printf("while ([INVALID]) {\n");
793 m_statements->dump(level+1);
794 printIndents(level);
795 printf("}\n");
796 }
797
798 Statements* While::statements() const {
799 return (m_statements) ? const_cast<Statements*>( &*m_statements ) : NULL;
800 }
801
802 bool While::evalLoopStartCondition() {
803 if (!m_condition) return false;
804 return m_condition->evalInt();
805 }
806
807 void SyncBlock::dump(int level) {
808 printIndents(level);
809 printf("sync {\n");
810 m_statements->dump(level+1);
811 printIndents(level);
812 printf("}\n");
813 }
814
815 Statements* SyncBlock::statements() const {
816 return (m_statements) ? const_cast<Statements*>( &*m_statements ) : NULL;
817 }
818
819 void Neg::dump(int level) {
820 printIndents(level);
821 printf("Negative Expr\n");
822 }
823
824 String ConcatString::evalStr() {
825 // temporaries required here to enforce the associative left (to right) order
826 // ( required for GCC and Visual Studio, see:
827 // http://stackoverflow.com/questions/25842902/why-stdstring-concatenation-operator-works-like-right-associative-one
828 // Personally I am not convinced that this is "not a bug" of the
829 // compiler/STL implementation and the allegedly underlying "function call"
830 // nature causing this is IMO no profound reason that the C++ language's
831 // "+" operator's left associativity is ignored. -- Christian, 2016-07-14 )
832 String l = lhs->evalCastToStr();
833 String r = rhs->evalCastToStr();
834 return l + r;
835 }
836
837 void ConcatString::dump(int level) {
838 printIndents(level);
839 printf("ConcatString(\n");
840 lhs->dump(level+1);
841 printIndents(level);
842 printf(",\n");
843 rhs->dump(level+1);
844 printIndents(level);
845 printf(")");
846 }
847
848 bool ConcatString::isConstExpr() const {
849 return lhs->isConstExpr() && rhs->isConstExpr();
850 }
851
852 vmint Relation::evalInt() {
853 switch (type) {
854 case LESS_THAN:
855 return lhs->evalInt() < rhs->evalInt();
856 case GREATER_THAN:
857 return lhs->evalInt() > rhs->evalInt();
858 case LESS_OR_EQUAL:
859 return lhs->evalInt() <= rhs->evalInt();
860 case GREATER_OR_EQUAL:
861 return lhs->evalInt() >= rhs->evalInt();
862 case EQUAL:
863 if (lhs->exprType() == STRING_EXPR || rhs->exprType() == STRING_EXPR)
864 return lhs->evalCastToStr() == rhs->evalCastToStr();
865 else
866 return lhs->evalInt() == rhs->evalInt();
867 case NOT_EQUAL:
868 if (lhs->exprType() == STRING_EXPR || rhs->exprType() == STRING_EXPR)
869 return lhs->evalCastToStr() != rhs->evalCastToStr();
870 else
871 return lhs->evalInt() != rhs->evalInt();
872 }
873 return 0;
874 }
875
876 void Relation::dump(int level) {
877 printIndents(level);
878 printf("Relation(\n");
879 lhs->dump(level+1);
880 printIndents(level);
881 switch (type) {
882 case LESS_THAN:
883 printf("LESS_THAN\n");
884 break;
885 case GREATER_THAN:
886 printf("GREATER_THAN\n");
887 break;
888 case LESS_OR_EQUAL:
889 printf("LESS_OR_EQUAL\n");
890 break;
891 case GREATER_OR_EQUAL:
892 printf("GREATER_OR_EQUAL\n");
893 break;
894 case EQUAL:
895 printf("EQUAL\n");
896 break;
897 case NOT_EQUAL:
898 printf("NOT_EQUAL\n");
899 break;
900 }
901 rhs->dump(level+1);
902 printIndents(level);
903 printf(")\n");
904 }
905
906 bool Relation::isConstExpr() const {
907 return lhs->isConstExpr() && rhs->isConstExpr();
908 }
909
910 vmint Or::evalInt() {
911 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
912 if (pLHS->evalInt()) return 1;
913 IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;
914 return (pRHS->evalInt()) ? 1 : 0;
915 }
916
917 void Or::dump(int level) {
918 printIndents(level);
919 printf("Or(\n");
920 lhs->dump(level+1);
921 printIndents(level);
922 printf(",\n");
923 rhs->dump(level+1);
924 printIndents(level);
925 printf(")\n");
926 }
927
928 vmint BitwiseOr::evalInt() {
929 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
930 IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
931 return pLHS->evalInt() | pRHS->evalInt();
932 }
933
934 void BitwiseOr::dump(int level) {
935 printIndents(level);
936 printf("BitwiseOr(\n");
937 lhs->dump(level+1);
938 printIndents(level);
939 printf(",\n");
940 rhs->dump(level+1);
941 printIndents(level);
942 printf(")\n");
943 }
944
945 vmint And::evalInt() {
946 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
947 if (!pLHS->evalInt()) return 0;
948 IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
949 return (pRHS->evalInt()) ? 1 : 0;
950 }
951
952 void And::dump(int level) {
953 printIndents(level);
954 printf("And(\n");
955 lhs->dump(level+1);
956 printIndents(level);
957 printf(",\n");
958 rhs->dump(level+1);
959 printIndents(level);
960 printf(")\n");
961 }
962
963 vmint BitwiseAnd::evalInt() {
964 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
965 IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
966 return pLHS->evalInt() & pRHS->evalInt();
967 }
968
969 void BitwiseAnd::dump(int level) {
970 printIndents(level);
971 printf("BitwiseAnd(\n");
972 lhs->dump(level+1);
973 printIndents(level);
974 printf(",\n");
975 rhs->dump(level+1);
976 printIndents(level);
977 printf(")\n");
978 }
979
980 void Not::dump(int level) {
981 printIndents(level);
982 printf("Not(\n");
983 expr->dump(level+1);
984 printIndents(level);
985 printf(")\n");
986 }
987
988 void BitwiseNot::dump(int level) {
989 printIndents(level);
990 printf("BitwiseNot(\n");
991 expr->dump(level+1);
992 printIndents(level);
993 printf(")\n");
994 }
995
996 void Final::dump(int level) {
997 printIndents(level);
998 printf("Final(\n");
999 expr->dump(level+1);
1000 printIndents(level);
1001 printf(")\n");
1002 }
1003
1004 StatementsRef ParserContext::userFunctionByName(const String& name) {
1005 if (!userFnTable.count(name)) {
1006 return StatementsRef();
1007 }
1008 return userFnTable.find(name)->second;
1009 }
1010
1011 VariableRef ParserContext::variableByName(const String& name) {
1012 if (!vartable.count(name)) {
1013 return VariableRef();
1014 }
1015 return vartable.find(name)->second;
1016 }
1017
1018 VariableRef ParserContext::globalVar(const String& name) {
1019 if (!vartable.count(name)) {
1020 //printf("No global var '%s'\n", name.c_str());
1021 //for (std::map<String,VariableRef>::const_iterator it = vartable.begin(); it != vartable.end(); ++it)
1022 // printf("-> var '%s'\n", it->first.c_str());
1023 return VariableRef();
1024 }
1025 return vartable.find(name)->second;
1026 }
1027
1028 IntVariableRef ParserContext::globalIntVar(const String& name) {
1029 return globalVar(name);
1030 }
1031
1032 StringVariableRef ParserContext::globalStrVar(const String& name) {
1033 return globalVar(name);
1034 }
1035
1036 ParserContext::~ParserContext() {
1037 destroyScanner();
1038 if (globalIntMemory) {
1039 delete globalIntMemory;
1040 globalIntMemory = NULL;
1041 }
1042 }
1043
1044 void ParserContext::addErr(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt) {
1045 ParserIssue e;
1046 e.type = PARSER_ERROR;
1047 e.txt = txt;
1048 e.firstLine = firstLine;
1049 e.lastLine = lastLine;
1050 e.firstColumn = firstColumn;
1051 e.lastColumn = lastColumn;
1052 vErrors.push_back(e);
1053 vIssues.push_back(e);
1054 }
1055
1056 void ParserContext::addWrn(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt) {
1057 ParserIssue w;
1058 w.type = PARSER_WARNING;
1059 w.txt = txt;
1060 w.firstLine = firstLine;
1061 w.lastLine = lastLine;
1062 w.firstColumn = firstColumn;
1063 w.lastColumn = lastColumn;
1064 vWarnings.push_back(w);
1065 vIssues.push_back(w);
1066 }
1067
1068 void ParserContext::addPreprocessorComment(int firstLine, int lastLine, int firstColumn, int lastColumn) {
1069 CodeBlock block;
1070 block.firstLine = firstLine;
1071 block.lastLine = lastLine;
1072 block.firstColumn = firstColumn;
1073 block.lastColumn = lastColumn;
1074 vPreprocessorComments.push_back(block);
1075 }
1076
1077 bool ParserContext::setPreprocessorCondition(const char* name) {
1078 if (builtinPreprocessorConditions.count(name)) return false;
1079 if (userPreprocessorConditions.count(name)) return false;
1080 userPreprocessorConditions.insert(name);
1081 return true;
1082 }
1083
1084 bool ParserContext::resetPreprocessorCondition(const char* name) {
1085 if (builtinPreprocessorConditions.count(name)) return false;
1086 if (!userPreprocessorConditions.count(name)) return false;
1087 userPreprocessorConditions.erase(name);
1088 return true;
1089 }
1090
1091 bool ParserContext::isPreprocessorConditionSet(const char* name) {
1092 if (builtinPreprocessorConditions.count(name)) return true;
1093 return userPreprocessorConditions.count(name);
1094 }
1095
1096 std::vector<ParserIssue> ParserContext::issues() const {
1097 return vIssues;
1098 }
1099
1100 std::vector<ParserIssue> ParserContext::errors() const {
1101 return vErrors;
1102 }
1103
1104 std::vector<ParserIssue> ParserContext::warnings() const {
1105 return vWarnings;
1106 }
1107
1108 std::vector<CodeBlock> ParserContext::preprocessorComments() const {
1109 return vPreprocessorComments;
1110 }
1111
1112 VMEventHandler* ParserContext::eventHandler(uint index) {
1113 if (!handlers) return NULL;
1114 return handlers->eventHandler(index);
1115 }
1116
1117 VMEventHandler* ParserContext::eventHandlerByName(const String& name) {
1118 if (!handlers) return NULL;
1119 return handlers->eventHandlerByName(name);
1120 }
1121
1122 void ParserContext::registerBuiltInConstIntVariables(const std::map<String,vmint>& vars) {
1123 for (std::map<String,vmint>::const_iterator it = vars.begin();
1124 it != vars.end(); ++it)
1125 {
1126 ConstIntVariableRef ref = new ConstIntVariable(it->second);
1127 vartable[it->first] = ref;
1128 }
1129 }
1130
1131 void ParserContext::registerBuiltInIntVariables(const std::map<String,VMIntPtr*>& vars) {
1132 for (std::map<String,VMIntPtr*>::const_iterator it = vars.begin();
1133 it != vars.end(); ++it)
1134 {
1135 BuiltInIntVariableRef ref = new BuiltInIntVariable(it->first, it->second);
1136 vartable[it->first] = ref;
1137 }
1138 }
1139
1140 void ParserContext::registerBuiltInIntArrayVariables(const std::map<String,VMInt8Array*>& vars) {
1141 for (std::map<String,VMInt8Array*>::const_iterator it = vars.begin();
1142 it != vars.end(); ++it)
1143 {
1144 BuiltInIntArrayVariableRef ref = new BuiltInIntArrayVariable(it->first, it->second);
1145 vartable[it->first] = ref;
1146 }
1147 }
1148
1149 void ParserContext::registerBuiltInDynVariables(const std::map<String,VMDynVar*>& vars) {
1150 for (std::map<String,VMDynVar*>::const_iterator it = vars.begin();
1151 it != vars.end(); ++it)
1152 {
1153 DynamicVariableCallRef ref = new DynamicVariableCall(it->first, this, it->second);
1154 vartable[it->first] = ref;
1155 }
1156 }
1157
1158 ExecContext::ExecContext() :
1159 status(VM_EXEC_NOT_RUNNING), flags(STMT_SUCCESS), stackFrame(-1),
1160 suspendMicroseconds(0), instructionsCount(0)
1161 {
1162 exitRes.value = NULL;
1163 }
1164
1165 void ExecContext::forkTo(VMExecContext* ectx) const {
1166 ExecContext* child = dynamic_cast<ExecContext*>(ectx);
1167
1168 child->polyphonicIntMemory.copyFlatFrom(polyphonicIntMemory);
1169 child->status = VM_EXEC_SUSPENDED;
1170 child->flags = STMT_SUCCESS;
1171 child->stack.copyFlatFrom(stack);
1172 child->stackFrame = stackFrame;
1173 child->suspendMicroseconds = 0;
1174 child->instructionsCount = 0;
1175 }
1176
1177 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC