/[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 3577 - (hide annotations) (download)
Wed Aug 28 15:23:23 2019 UTC (4 years, 7 months ago) by schoenebeck
File size: 41334 byte(s)
NKSP: Introducing variable return type for built-in functions.

* Changed method signature VMFunction::returnType() ->
  VMFunction::returnType(VMFnArgs* args) to allow built-in
  functions to proclaim a different result value type depending
  on the arguments to be passed to the function.

* Built-in script function abs() optionally accepts and returns
  real number.

* Built-in script functions min() and max() optionally accept
  real number arguments and return real number as result in that
  case.

* Added real number test cases for the built-in abs(), min() and
  max() functions.

* Bumped version (2.1.1.svn7).

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

  ViewVC Help
Powered by ViewVC