/[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 3557 - (show annotations) (download)
Sun Aug 18 00:06:04 2019 UTC (4 years, 8 months ago) by schoenebeck
File size: 29917 byte(s)
* NKSP: Introducing 64 bit support for NKSP integer scripts
  variables (declare $foo).
* Require C++11 compiler support.
* Autoconf: Added m4/ax_cxx_compile_stdcxx.m4 macro which is used
  for checking in configure for C++11 support (as mandatory
  requirement) and automatically adds compiler argument if required
  (e.g. -std=C++11).
* Bumped version (2.1.1.svn3).

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

  ViewVC Help
Powered by ViewVC