/[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 3557 - (hide annotations) (download)
Sun Aug 18 00:06:04 2019 UTC (4 years, 7 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 schoenebeck 2581 /*
2 schoenebeck 3551 * Copyright (c) 2014 - 2019 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 schoenebeck 3311 return statement->statementType() == STMT_NOOP;
20 schoenebeck 2581 }
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 schoenebeck 3293 String IntArrayExpr::evalCastToStr() {
38 schoenebeck 3056 String s = "{";
39 schoenebeck 3557 for (vmint i = 0; i < arraySize(); ++i) {
40     vmint val = evalIntElement(i);
41 schoenebeck 3056 if (i) s += ",";
42     s += ToString(val);
43     }
44     s += "}";
45     return s;
46 schoenebeck 3293 }
47 schoenebeck 3056
48 schoenebeck 3557 vmint IntLiteral::evalInt() {
49 schoenebeck 2581 return value;
50     }
51    
52     void IntLiteral::dump(int level) {
53     printIndents(level);
54 schoenebeck 3557 printf("IntLiteral %lld\n", value);
55 schoenebeck 2581 }
56    
57     void StringLiteral::dump(int level) {
58     printIndents(level);
59     printf("StringLiteral: '%s'\n", value.c_str());
60     }
61    
62 schoenebeck 3557 vmint Add::evalInt() {
63 schoenebeck 2581 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 schoenebeck 3557 vmint Sub::evalInt() {
80 schoenebeck 2581 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 schoenebeck 3557 vmint Mul::evalInt() {
97 schoenebeck 2581 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 schoenebeck 3557 vmint Div::evalInt() {
114 schoenebeck 2581 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
115 schoenebeck 2945 IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
116     if (!pLHS || !pRHS) return 0;
117 schoenebeck 3557 vmint l = pLHS->evalInt();
118     vmint r = pRHS->evalInt();
119 schoenebeck 2945 if (r == 0) return 0;
120     return l / r;
121 schoenebeck 2581 }
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 schoenebeck 3557 vmint Mod::evalInt() {
135 schoenebeck 2581 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 schoenebeck 2645 bool Args::isPolyphonic() const {
162 schoenebeck 3557 for (vmint i = 0; i < args.size(); ++i)
163 schoenebeck 2645 if (args[i]->isPolyphonic())
164     return true;
165     return false;
166     }
167    
168 schoenebeck 2581 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 schoenebeck 3557 for (vmint i = 0; i < args.size(); ++i)
191 schoenebeck 2581 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 schoenebeck 2645 bool EventHandlers::isPolyphonic() const {
202 schoenebeck 3557 for (vmint i = 0; i < args.size(); ++i)
203 schoenebeck 2645 if (args[i]->isPolyphonic())
204     return true;
205     return false;
206     }
207    
208 schoenebeck 2581 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 schoenebeck 2645 EventHandler::EventHandler(StatementsRef statements) {
226     this->statements = statements;
227     usingPolyphonics = statements->isPolyphonic();
228     }
229    
230 schoenebeck 2581 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 schoenebeck 2645 bool Statements::isPolyphonic() const {
254 schoenebeck 3557 for (vmint i = 0; i < args.size(); ++i)
255 schoenebeck 2645 if (args[i]->isPolyphonic())
256     return true;
257     return false;
258     }
259    
260 schoenebeck 2942 DynamicVariableCall::DynamicVariableCall(const String& name, ParserContext* ctx, VMDynVar* v)
261     : Variable(ctx, 0, false), dynVar(v), varName(name)
262     {
263     }
264    
265 schoenebeck 3557 vmint DynamicVariableCall::evalInt() {
266 schoenebeck 2942 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 schoenebeck 2581 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 schoenebeck 3557 vmint FunctionCall::evalInt() {
319 schoenebeck 2581 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 schoenebeck 3056 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 schoenebeck 2581 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 schoenebeck 2588 //printf("globalIntVar parserctx=0x%lx memPOS=%d\n", ctx, memPos);
357     assert(ctx);
358 schoenebeck 2581 }
359    
360 schoenebeck 3557 inline static vmint postfixInc(vmint& object, vmint incBy) {
361     const vmint i = object;
362 schoenebeck 2588 object += incBy;
363     return i;
364     }
365    
366 schoenebeck 3557 IntVariable::IntVariable(ParserContext* ctx, bool polyphonic, bool bConst, vmint size)
367 schoenebeck 2588 : Variable(ctx, !ctx ? 0 : polyphonic ? postfixInc(ctx->polyphonicIntVarCount, size) : postfixInc(ctx->globalIntVarCount, size), bConst),
368 schoenebeck 2581 polyphonic(polyphonic)
369     {
370 schoenebeck 2588 //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 schoenebeck 2581 }
376    
377     void IntVariable::assign(Expression* expr) {
378     IntExpr* intExpr = dynamic_cast<IntExpr*>(expr);
379 schoenebeck 3034 if (intExpr) {
380 schoenebeck 2581 if (polyphonic)
381     context->execContext->polyphonicIntMemory[memPos] = intExpr->evalInt();
382     else
383     (*context->globalIntMemory)[memPos] = intExpr->evalInt();
384 schoenebeck 3034 }
385 schoenebeck 2581 }
386    
387 schoenebeck 3557 vmint IntVariable::evalInt() {
388 schoenebeck 2581 //printf("IntVariable::eval pos=%d\n", memPos);
389 schoenebeck 2588 if (polyphonic) {
390     //printf("evalInt() poly memPos=%d execCtx=0x%lx\n", memPos, (uint64_t)context->execContext);
391 schoenebeck 2581 return context->execContext->polyphonicIntMemory[memPos];
392 schoenebeck 2588 }
393 schoenebeck 2581 return (*context->globalIntMemory)[memPos];
394     }
395    
396     void IntVariable::dump(int level) {
397     printIndents(level);
398 schoenebeck 2945 printf("IntVariable\n");
399 schoenebeck 2588 //printf("IntVariable memPos=%d\n", memPos);
400 schoenebeck 2581 }
401    
402     //ConstIntVariable::ConstIntVariable(ParserContext* ctx, int value)
403 schoenebeck 3557 ConstIntVariable::ConstIntVariable(vmint value)
404 schoenebeck 2581 : 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 schoenebeck 3557 vmint ConstIntVariable::evalInt() {
420 schoenebeck 2581 return value;
421     }
422    
423     void ConstIntVariable::dump(int level) {
424     printIndents(level);
425 schoenebeck 3557 printf("ConstIntVariable val=%lld\n", value);
426 schoenebeck 2581 }
427    
428 schoenebeck 3557 BuiltInIntVariable::BuiltInIntVariable(const String& name, VMIntPtr* ptr)
429 schoenebeck 2594 : 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 schoenebeck 3557 vmint BuiltInIntVariable::evalInt() {
440 schoenebeck 2594 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 schoenebeck 2581 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 schoenebeck 3557 IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size)
459 schoenebeck 2581 : Variable(ctx, 0, false)
460     {
461     values.resize(size);
462 schoenebeck 3557 memset(&values[0], 0, size * sizeof(vmint));
463 schoenebeck 2581 }
464    
465 schoenebeck 3557 IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size, ArgsRef values, bool _bConst)
466 schoenebeck 3257 : Variable(ctx, 0, _bConst)
467 schoenebeck 2581 {
468     this->values.resize(size);
469 schoenebeck 3557 for (vmint i = 0; i < values->argsCount(); ++i) {
470 schoenebeck 2581 VMIntExpr* expr = dynamic_cast<VMIntExpr*>(values->arg(i));
471     if (expr) this->values[i] = expr->evalInt();
472     }
473     }
474    
475 schoenebeck 2594 IntArrayVariable::IntArrayVariable(ParserContext* ctx, bool bConst)
476     : Variable(ctx, 0, bConst)
477     {
478     }
479    
480 schoenebeck 3557 vmint IntArrayVariable::evalIntElement(vmuint i) {
481 schoenebeck 2581 if (i >= values.size()) return 0;
482     return values[i];
483     }
484    
485 schoenebeck 3557 void IntArrayVariable::assignIntElement(vmuint i, vmint value) {
486 schoenebeck 2581 if (i >= values.size()) return;
487     values[i] = value;
488     }
489    
490     void IntArrayVariable::dump(int level) {
491     printIndents(level);
492     printf("IntArray(");
493 schoenebeck 3557 for (vmint i = 0; i < values.size(); ++i) {
494 schoenebeck 2581 if (i % 12 == 0) {
495     printf("\n");
496     printIndents(level+1);
497     }
498 schoenebeck 3557 printf("%lld, ", values[i]);
499 schoenebeck 2581 }
500     printIndents(level);
501     printf(")\n");
502     }
503    
504 schoenebeck 2594 BuiltInIntArrayVariable::BuiltInIntArrayVariable(const String& name, VMInt8Array* array)
505     : IntArrayVariable(NULL, false), name(name), array(array)
506     {
507     }
508    
509 schoenebeck 3557 vmint BuiltInIntArrayVariable::evalIntElement(vmuint i) {
510 schoenebeck 2594 return i >= array->size ? 0 : array->data[i];
511     }
512    
513 schoenebeck 3557 void BuiltInIntArrayVariable::assignIntElement(vmuint i, vmint value) {
514 schoenebeck 2594 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 schoenebeck 3293 IntArrayElement::IntArrayElement(IntArrayExprRef array, IntExprRef arrayIndex)
524 schoenebeck 2581 : 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 schoenebeck 3557 vmint value = valueExpr->evalInt();
532 schoenebeck 2581
533     if (!index) return;
534 schoenebeck 3557 vmint idx = index->evalInt();
535 schoenebeck 2581 if (idx < 0 || idx >= array->arraySize()) return;
536    
537     array->assignIntElement(idx, value);
538     }
539    
540 schoenebeck 3557 vmint IntArrayElement::evalInt() {
541 schoenebeck 2581 if (!index) return 0;
542 schoenebeck 3557 vmint idx = index->evalInt();
543 schoenebeck 2581 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 schoenebeck 3557 printf("StringVariable memPos=%lld\n", memPos);
576 schoenebeck 2581 }
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 schoenebeck 3557 vmint If::evalBranch() {
609 schoenebeck 2581 if (condition->evalInt()) return 0;
610     if (elseStatements) return 1;
611     return -1;
612     }
613    
614 schoenebeck 3557 Statements* If::branch(vmuint i) const {
615 schoenebeck 2581 if (i == 0) return (Statements*) &*ifStatements;
616     if (i == 1) return (elseStatements) ? (Statements*) &*elseStatements : NULL;
617     return NULL;
618     }
619    
620 schoenebeck 2645 bool If::isPolyphonic() const {
621     if (condition->isPolyphonic() || ifStatements->isPolyphonic())
622     return true;
623     return elseStatements ? elseStatements->isPolyphonic() : false;
624     }
625    
626 schoenebeck 2581 void SelectCase::dump(int level) {
627     printIndents(level);
628     if (select)
629     if (select->isConstExpr())
630 schoenebeck 3557 printf("Case select %lld\n", select->evalInt());
631 schoenebeck 2581 else
632     printf("Case select [runtime expr]\n");
633     else
634     printf("Case select NULL\n");
635 schoenebeck 3557 for (vmint i = 0; i < branches.size(); ++i) {
636 schoenebeck 2581 printIndents(level+1);
637     CaseBranch& branch = branches[i];
638     if (branch.from && branch.to)
639     if (branch.from->isConstExpr() && branch.to->isConstExpr())
640 schoenebeck 3557 printf("case %lld to %lld\n", branch.from->evalInt(), branch.to->evalInt());
641 schoenebeck 2581 else if (branch.from->isConstExpr() && !branch.to->isConstExpr())
642 schoenebeck 3557 printf("case %lld to [runtime expr]\n", branch.from->evalInt());
643 schoenebeck 2581 else if (!branch.from->isConstExpr() && branch.to->isConstExpr())
644 schoenebeck 3557 printf("case [runtime expr] to %lld\n", branch.to->evalInt());
645 schoenebeck 2581 else
646     printf("case [runtime expr] to [runtime expr]\n");
647     else if (branch.from)
648     if (branch.from->isConstExpr())
649 schoenebeck 3557 printf("case %lld\n", branch.from->evalInt());
650 schoenebeck 2581 else
651     printf("case [runtime expr]\n");
652     else
653     printf("case NULL\n");
654     }
655     }
656    
657 schoenebeck 3557 vmint SelectCase::evalBranch() {
658     vmint value = select->evalInt();
659     for (vmint i = 0; i < branches.size(); ++i) {
660 schoenebeck 2581 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 schoenebeck 3557 Statements* SelectCase::branch(vmuint i) const {
671 schoenebeck 2581 if (i < branches.size())
672     return const_cast<Statements*>( &*branches[i].statements );
673     return NULL;
674     }
675    
676 schoenebeck 2645 bool SelectCase::isPolyphonic() const {
677     if (select->isPolyphonic()) return true;
678 schoenebeck 3557 for (vmint i = 0; i < branches.size(); ++i)
679 schoenebeck 2645 if (branches[i].statements->isPolyphonic())
680     return true;
681     return false;
682     }
683    
684 schoenebeck 2581 // 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 schoenebeck 3557 printf("while (%lld) {\n", m_condition->evalInt());
708 schoenebeck 2581 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 schoenebeck 3260 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 schoenebeck 2581 void Neg::dump(int level) {
739     printIndents(level);
740     printf("Negative Expr\n");
741     }
742    
743     String ConcatString::evalStr() {
744 schoenebeck 2945 // temporaries required here to enforce the associative left (to right) order
745 schoenebeck 2948 // ( 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 schoenebeck 2945 String l = lhs->evalCastToStr();
752     String r = rhs->evalCastToStr();
753     return l + r;
754 schoenebeck 2581 }
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 schoenebeck 3557 vmint Relation::evalInt() {
772 schoenebeck 2581 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 schoenebeck 3557 vmint Or::evalInt() {
830 schoenebeck 2581 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
831 schoenebeck 2611 if (pLHS->evalInt()) return 1;
832 schoenebeck 2581 IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);;
833 schoenebeck 2611 return (pRHS->evalInt()) ? 1 : 0;
834 schoenebeck 2581 }
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 schoenebeck 3557 vmint BitwiseOr::evalInt() {
848 schoenebeck 2935 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 schoenebeck 3557 vmint And::evalInt() {
865 schoenebeck 2581 IntExpr* pLHS = dynamic_cast<IntExpr*>(&*lhs);
866 schoenebeck 2611 if (!pLHS->evalInt()) return 0;
867     IntExpr* pRHS = dynamic_cast<IntExpr*>(&*rhs);
868     return (pRHS->evalInt()) ? 1 : 0;
869 schoenebeck 2581 }
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 schoenebeck 3557 vmint BitwiseAnd::evalInt() {
883 schoenebeck 2935 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 schoenebeck 2581 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 schoenebeck 2935 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 schoenebeck 2951 StatementsRef ParserContext::userFunctionByName(const String& name) {
916     if (!userFnTable.count(name)) {
917     return StatementsRef();
918     }
919     return userFnTable.find(name)->second;
920     }
921    
922 schoenebeck 2581 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 schoenebeck 2588 ParserContext::~ParserContext() {
948     destroyScanner();
949     if (globalIntMemory) {
950     delete globalIntMemory;
951     globalIntMemory = NULL;
952     }
953     }
954    
955 schoenebeck 2889 void ParserContext::addErr(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt) {
956 schoenebeck 2581 ParserIssue e;
957     e.type = PARSER_ERROR;
958     e.txt = txt;
959 schoenebeck 2889 e.firstLine = firstLine;
960     e.lastLine = lastLine;
961     e.firstColumn = firstColumn;
962     e.lastColumn = lastColumn;
963 schoenebeck 2588 vErrors.push_back(e);
964     vIssues.push_back(e);
965 schoenebeck 2581 }
966    
967 schoenebeck 2889 void ParserContext::addWrn(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt) {
968 schoenebeck 2581 ParserIssue w;
969     w.type = PARSER_WARNING;
970     w.txt = txt;
971 schoenebeck 2889 w.firstLine = firstLine;
972     w.lastLine = lastLine;
973     w.firstColumn = firstColumn;
974     w.lastColumn = lastColumn;
975 schoenebeck 2588 vWarnings.push_back(w);
976     vIssues.push_back(w);
977 schoenebeck 2581 }
978    
979 schoenebeck 3285 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 schoenebeck 2581 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 schoenebeck 2588 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 schoenebeck 3285 std::vector<CodeBlock> ParserContext::preprocessorComments() const {
1020     return vPreprocessorComments;
1021     }
1022    
1023 schoenebeck 2588 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 schoenebeck 3557 void ParserContext::registerBuiltInConstIntVariables(const std::map<String,vmint>& vars) {
1034     for (std::map<String,vmint>::const_iterator it = vars.begin();
1035 schoenebeck 2594 it != vars.end(); ++it)
1036     {
1037     ConstIntVariableRef ref = new ConstIntVariable(it->second);
1038     vartable[it->first] = ref;
1039     }
1040     }
1041    
1042 schoenebeck 3557 void ParserContext::registerBuiltInIntVariables(const std::map<String,VMIntPtr*>& vars) {
1043     for (std::map<String,VMIntPtr*>::const_iterator it = vars.begin();
1044 schoenebeck 2594 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 schoenebeck 2942 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 schoenebeck 3551 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 schoenebeck 3293 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 schoenebeck 2581 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC