/[svn]/linuxsampler/trunk/src/scriptvm/tree.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/scriptvm/tree.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3293 - (hide annotations) (download)
Tue Jun 27 22:19:19 2017 UTC (6 years, 9 months ago) by schoenebeck
File size: 29641 byte(s)
* NKSP: Added built-in script function "fork()".
* NKSP: Added built-in array variable %NKSP_CALLBACK_CHILD_ID[].
* NKSP: Added built-in variable $NKSP_CALLBACK_PARENT_ID.
* NKSP: Fixed potential crash when accessing dynamic built-in
  array variables.
* Bumped version (2.0.0.svn65).

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

  ViewVC Help
Powered by ViewVC