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

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

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

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

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

* Bumped version (2.1.1.svn4).

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

  ViewVC Help
Powered by ViewVC