--- linuxsampler/trunk/src/scriptvm/tree.cpp 2019/08/27 17:11:08 3572 +++ linuxsampler/trunk/src/scriptvm/tree.cpp 2019/08/27 21:36:53 3573 @@ -34,6 +34,10 @@ return ToString(evalInt()); } +String RealExpr::evalCastToStr() { + return ToString(evalReal()); +} + String IntArrayExpr::evalCastToStr() { String s = "{"; for (vmint i = 0; i < arraySize(); ++i) { @@ -45,6 +49,17 @@ return s; } +String RealArrayExpr::evalCastToStr() { + String s = "{"; + for (vmint i = 0; i < arraySize(); ++i) { + vmfloat val = evalRealElement(i); + if (i) s += ","; + s += ToString(val); + } + s += "}"; + return s; +} + MetricPrefix_t Unit::unitPrefix(vmuint i) const { if (i >= prefix.size()) return VM_NO_PREFIX; return prefix[i]; @@ -65,7 +80,7 @@ prefix.add(prefixes[i]); } -void Unit::copyUnitFrom(const IntExprRef& src) { +void Unit::copyUnitFrom(const UnitRef& src) { unit = src->unitType(); prefix.clear(); for (int i = 0; true; ++i) { @@ -84,6 +99,15 @@ printf("IntLiteral %lld\n", value); } +vmfloat RealLiteral::evalReal() { + return value; +} + +void RealLiteral::dump(int level) { + printIndents(level); + printf("RealLiteral %f\n", value); +} + void StringLiteral::dump(int level) { printIndents(level); printf("StringLiteral: '%s'\n", value.c_str()); @@ -95,6 +119,12 @@ return (pLHS && pRHS) ? pLHS->evalInt() + pRHS->evalInt() : 0; } +vmfloat Add::evalReal() { + RealExpr* pLHS = dynamic_cast(&*lhs); + RealExpr* pRHS = dynamic_cast(&*rhs);; + return (pLHS && pRHS) ? pLHS->evalReal() + pRHS->evalReal() : 0; +} + void Add::dump(int level) { printIndents(level); printf("Add(\n"); @@ -112,6 +142,12 @@ return (pLHS && pRHS) ? pLHS->evalInt() - pRHS->evalInt() : 0; } +vmfloat Sub::evalReal() { + RealExpr* pLHS = dynamic_cast(&*lhs); + RealExpr* pRHS = dynamic_cast(&*rhs);; + return (pLHS && pRHS) ? pLHS->evalReal() - pRHS->evalReal() : 0; +} + void Sub::dump(int level) { printIndents(level); printf("Sub(\n"); @@ -129,6 +165,12 @@ return (pLHS && pRHS) ? pLHS->evalInt() * pRHS->evalInt() : 0; } +vmfloat Mul::evalReal() { + RealExpr* pLHS = dynamic_cast(&*lhs); + RealExpr* pRHS = dynamic_cast(&*rhs);; + return (pLHS && pRHS) ? pLHS->evalReal() * pRHS->evalReal() : 0; +} + void Mul::dump(int level) { printIndents(level); printf("Mul(\n"); @@ -141,15 +183,15 @@ } MetricPrefix_t Mul::unitPrefix(vmuint i) const { - const IntExpr* pLHS = dynamic_cast(&*lhs); - const IntExpr* pRHS = dynamic_cast(&*rhs); + const ScalarNumberExpr* pLHS = dynamic_cast(&*lhs); + const ScalarNumberExpr* pRHS = dynamic_cast(&*rhs); // currently the NKSP parser only allows a unit prefix on either side return (pLHS->unitPrefix(0)) ? pLHS->unitPrefix(i) : pRHS->unitPrefix(i); } StdUnit_t Mul::unitType() const { - const IntExpr* pLHS = dynamic_cast(&*lhs); - const IntExpr* pRHS = dynamic_cast(&*rhs); + const ScalarNumberExpr* pLHS = dynamic_cast(&*lhs); + const ScalarNumberExpr* pRHS = dynamic_cast(&*rhs); // currently the NKSP parser only allows a unit type on either side return (pLHS->unitType()) ? pLHS->unitType() : pRHS->unitType(); } @@ -164,6 +206,16 @@ return l / r; } +vmfloat Div::evalReal() { + RealExpr* pLHS = dynamic_cast(&*lhs); + RealExpr* pRHS = dynamic_cast(&*rhs);; + if (!pLHS || !pRHS) return 0; + vmfloat l = pLHS->evalReal(); + vmfloat r = pRHS->evalReal(); + if (r == vmfloat(0)) return 0; + return l / r; +} + void Div::dump(int level) { printIndents(level); printf("Div(\n"); @@ -176,16 +228,16 @@ } MetricPrefix_t Div::unitPrefix(vmuint i) const { - const IntExpr* pLHS = dynamic_cast(&*lhs); - const IntExpr* pRHS = dynamic_cast(&*rhs); + const ScalarNumberExpr* pLHS = dynamic_cast(&*lhs); + const ScalarNumberExpr* pRHS = dynamic_cast(&*rhs); // currently the NKSP parser only allows either A) a unit prefix on left // side and none on right side or B) an identical unit prefix on both sides return (pLHS->unitPrefix(0) && pRHS->unitPrefix(0)) ? VM_NO_PREFIX : pLHS->unitPrefix(i); } StdUnit_t Div::unitType() const { - const IntExpr* pLHS = dynamic_cast(&*lhs); - const IntExpr* pRHS = dynamic_cast(&*rhs); + const ScalarNumberExpr* pLHS = dynamic_cast(&*lhs); + const ScalarNumberExpr* pRHS = dynamic_cast(&*rhs); // the NKSP parser only allows either A) a unit type on left side and none // on right side or B) an identical unit type on both sides return (pLHS->unitType() && pRHS->unitType()) ? VM_NO_UNIT : pLHS->unitType(); @@ -383,6 +435,14 @@ return intExpr->evalInt(); } +vmfloat FunctionCall::evalReal() { + VMFnResult* result = execVMFn(); + if (!result) return 0; + VMRealExpr* realExpr = dynamic_cast(result->resultValue()); + if (!realExpr) return 0; + return realExpr->evalReal(); +} + VMIntArrayExpr* FunctionCall::asIntArray() const { VMFnResult* result = const_cast(this)->execVMFn(); if (!result) return 0; @@ -390,6 +450,13 @@ return intArrExpr; } +VMRealArrayExpr* FunctionCall::asRealArray() const { + VMFnResult* result = const_cast(this)->execVMFn(); + if (!result) return 0; + VMRealArrayExpr* realArrExpr = dynamic_cast(result->resultValue()); + return realArrExpr; +} + String FunctionCall::evalStr() { VMFnResult* result = execVMFn(); if (!result) return ""; @@ -401,19 +468,30 @@ String FunctionCall::evalCastToStr() { VMFnResult* result = execVMFn(); if (!result) return ""; - if (result->resultValue()->exprType() == STRING_EXPR) { + const ExprType_t resultType = result->resultValue()->exprType(); + if (resultType == STRING_EXPR) { VMStringExpr* strExpr = dynamic_cast(result->resultValue()); return strExpr ? strExpr->evalStr() : ""; + } else if (resultType == REAL_EXPR) { + VMRealExpr* realExpr = dynamic_cast(result->resultValue()); + return realExpr ? ToString(realExpr->evalReal()) : ""; } else { VMIntExpr* intExpr = dynamic_cast(result->resultValue()); return intExpr ? ToString(intExpr->evalInt()) : ""; } } -IntVariable::IntVariable(ParserContext* ctx) - : Variable(ctx, ctx ? ctx->globalIntVarCount++ : 0, false), +ScalarNumberVariable::ScalarNumberVariable(ParserContext* ctx, vmint _memPos, + bool _bConst, bool _bPolyphonic, + bool _bFinal) + : Variable(ctx, _memPos, _bConst), Unit(), - polyphonic(false), finalVal(false) + polyphonic(_bPolyphonic), finalVal(_bFinal) +{ +} + +IntVariable::IntVariable(ParserContext* ctx) + : ScalarNumberVariable(ctx, ctx ? ctx->globalIntVarCount++ : 0) { //printf("globalIntVar parserctx=0x%lx memPOS=%d\n", ctx, memPos); assert(ctx); @@ -425,13 +503,16 @@ return i; } -IntVariable::IntVariable(ParserContext* ctx, bool polyphonic, bool bConst, vmint size) - : Variable(ctx, !ctx ? 0 : polyphonic ? postfixInc(ctx->polyphonicIntVarCount, size) : postfixInc(ctx->globalIntVarCount, size), bConst), - Unit(), - polyphonic(polyphonic), finalVal(false) +IntVariable::IntVariable(ParserContext* ctx, bool bPolyphonic, bool bConst, vmint size) + : ScalarNumberVariable( + ctx, + !ctx ? 0 : bPolyphonic ? postfixInc(ctx->polyphonicIntVarCount, size) : + postfixInc(ctx->globalIntVarCount, size), + bConst, bPolyphonic + ) { - //printf("InvVar size=%d parserCtx=0x%lx\n", size, (uint64_t)ctx); - if (polyphonic) { + //printf("IntVar size=%d parserCtx=0x%lx\n", size, (uint64_t)ctx); + if (bPolyphonic) { //printf("polyIntVar memPOS=%d\n", memPos); assert(ctx); } @@ -440,7 +521,7 @@ void IntVariable::assign(Expression* expr) { IntExpr* intExpr = dynamic_cast(expr); if (intExpr) { - if (polyphonic) + if (isPolyphonic()) context->execContext->polyphonicIntMemory[memPos] = intExpr->evalInt(); else (*context->globalIntMemory)[memPos] = intExpr->evalInt(); @@ -449,7 +530,7 @@ vmint IntVariable::evalInt() { //printf("IntVariable::eval pos=%d\n", memPos); - if (polyphonic) { + if (isPolyphonic()) { //printf("evalInt() poly memPos=%d execCtx=0x%lx\n", memPos, (uint64_t)context->execContext); return context->execContext->polyphonicIntMemory[memPos]; } @@ -462,7 +543,53 @@ //printf("IntVariable memPos=%d\n", memPos); } -//ConstIntVariable::ConstIntVariable(ParserContext* ctx, int value) +RealVariable::RealVariable(ParserContext* ctx) + : ScalarNumberVariable(ctx, ctx ? ctx->globalRealVarCount++ : 0) +{ + //printf("globalRealVar parserctx=0x%lx memPOS=%d\n", ctx, memPos); + assert(ctx); +} + +RealVariable::RealVariable(ParserContext* ctx, bool bPolyphonic, bool bConst, vmint size) + : ScalarNumberVariable( + ctx, + !ctx ? 0 : bPolyphonic ? postfixInc(ctx->polyphonicRealVarCount, size) : + postfixInc(ctx->globalRealVarCount, size), + bConst, bPolyphonic + ) +{ + //printf("RealVar size=%d parserCtx=0x%lx\n", size, (uint64_t)ctx); + if (bPolyphonic) { + //printf("polyRealVar memPOS=%d\n", memPos); + assert(ctx); + } +} + +void RealVariable::assign(Expression* expr) { + RealExpr* realExpr = dynamic_cast(expr); + if (realExpr) { + if (isPolyphonic()) + context->execContext->polyphonicRealMemory[memPos] = realExpr->evalReal(); + else + (*context->globalRealMemory)[memPos] = realExpr->evalReal(); + } +} + +vmfloat RealVariable::evalReal() { + //printf("RealVariable::eval pos=%d\n", memPos); + if (isPolyphonic()) { + //printf("evalReal() poly memPos=%d execCtx=0x%lx\n", memPos, (uint64_t)context->execContext); + return context->execContext->polyphonicRealMemory[memPos]; + } + return (*context->globalRealMemory)[memPos]; +} + +void RealVariable::dump(int level) { + printIndents(level); + printf("RealVariable\n"); + //printf("RealVariable memPos=%d\n", memPos); +} + ConstIntVariable::ConstIntVariable(vmint value) : IntVariable(NULL,false,true), value(value) { @@ -488,6 +615,24 @@ printf("ConstIntVariable val=%lld\n", value); } +ConstRealVariable::ConstRealVariable(vmfloat value) + : RealVariable(NULL,false,true), value(value) +{ +} + +void ConstRealVariable::assign(Expression* expr) { + // ignore assignment +} + +vmfloat ConstRealVariable::evalReal() { + return value; +} + +void ConstRealVariable::dump(int level) { + printIndents(level); + printf("ConstRealVariable val=%f\n", value); +} + BuiltInIntVariable::BuiltInIntVariable(const String& name, VMIntPtr* ptr) : IntVariable(NULL,false,false), name(name), ptr(ptr) { @@ -518,6 +663,16 @@ printf("PolyphonicIntVariable\n"); } +PolyphonicRealVariable::PolyphonicRealVariable(ParserContext* ctx) + : RealVariable(ctx,true,false) +{ +} + +void PolyphonicRealVariable::dump(int level) { + printIndents(level); + printf("PolyphonicRealVariable\n"); +} + IntArrayVariable::IntArrayVariable(ParserContext* ctx, vmint size) : Variable(ctx, 0, false) { @@ -564,6 +719,52 @@ printf(")\n"); } +RealArrayVariable::RealArrayVariable(ParserContext* ctx, vmint size) + : Variable(ctx, 0, false) +{ + values.resize(size); + memset(&values[0], 0, size * sizeof(vmfloat)); +} + +RealArrayVariable::RealArrayVariable(ParserContext* ctx, vmint size, ArgsRef values, bool _bConst) + : Variable(ctx, 0, _bConst) +{ + this->values.resize(size); + for (vmint i = 0; i < values->argsCount(); ++i) { + VMRealExpr* expr = dynamic_cast(values->arg(i)); + if (expr) this->values[i] = expr->evalReal(); + } +} + +RealArrayVariable::RealArrayVariable(ParserContext* ctx, bool bConst) + : Variable(ctx, 0, bConst) +{ +} + +vmfloat RealArrayVariable::evalRealElement(vmuint i) { + if (i >= values.size()) return 0; + return values[i]; +} + +void RealArrayVariable::assignRealElement(vmuint i, vmfloat value) { + if (i >= values.size()) return; + values[i] = value; +} + +void RealArrayVariable::dump(int level) { + printIndents(level); + printf("RealArray("); + for (vmint i = 0; i < values.size(); ++i) { + if (i % 12 == 0) { + printf("\n"); + printIndents(level+1); + } + printf("%f, ", values[i]); + } + printIndents(level); + printf(")\n"); +} + BuiltInIntArrayVariable::BuiltInIntArrayVariable(const String& name, VMInt8Array* array) : IntArrayVariable(NULL, false), name(name), array(array) { @@ -613,6 +814,36 @@ printf("IntArrayElement\n"); } +RealArrayElement::RealArrayElement(RealArrayExprRef array, IntExprRef arrayIndex) + : RealVariable(NULL, false, false, 0), array(array), index(arrayIndex) +{ +} + +void RealArrayElement::assign(Expression* expr) { + RealExpr* valueExpr = dynamic_cast(expr); + if (!valueExpr) return; + vmfloat value = valueExpr->evalReal(); + + if (!index) return; + vmint idx = index->evalInt(); + if (idx < 0 || idx >= array->arraySize()) return; + + array->assignRealElement(idx, value); +} + +vmfloat RealArrayElement::evalReal() { + if (!index) return 0; + vmint idx = index->evalInt(); + if (idx < 0 || idx >= array->arraySize()) return 0; + + return array->evalRealElement(idx); +} + +void RealArrayElement::dump(int level) { + printIndents(level); + printf("RealArrayElement\n"); +} + StringVariable::StringVariable(ParserContext* ctx) : Variable(ctx,ctx->globalStrVarCount++,false) { @@ -658,24 +889,33 @@ printf("ConstStringVariable val='%s'\n", value.c_str()); } -MetricPrefix_t IntBinaryOp::unitPrefix(vmuint i) const { - IntExprRef l = (IntExprRef) lhs; - IntExprRef r = (IntExprRef) rhs; +MetricPrefix_t ScalarNumberBinaryOp::unitPrefix(vmuint i) const { + ScalarNumberExprRef l = (ScalarNumberExprRef) lhs; + ScalarNumberExprRef r = (ScalarNumberExprRef) rhs; return (r->unitFactor() < l->unitFactor()) ? r->unitPrefix(i) : l->unitPrefix(i); } -StdUnit_t IntBinaryOp::unitType() const { - IntExprRef l = (IntExprRef) lhs; - IntExprRef r = (IntExprRef) rhs; +StdUnit_t ScalarNumberBinaryOp::unitType() const { + ScalarNumberExprRef l = (ScalarNumberExprRef) lhs; + ScalarNumberExprRef r = (ScalarNumberExprRef) rhs; return (l->unitType()) ? l->unitType() : r->unitType(); } -bool IntBinaryOp::isFinal() const { - IntExprRef l = (IntExprRef) lhs; - IntExprRef r = (IntExprRef) rhs; +bool ScalarNumberBinaryOp::isFinal() const { + ScalarNumberExprRef l = (ScalarNumberExprRef) lhs; + ScalarNumberExprRef r = (ScalarNumberExprRef) rhs; return l->isFinal() || r->isFinal(); } +ExprType_t VaritypeScalarBinaryOp::exprType() const { + return (lhs->exprType() == REAL_EXPR || rhs->exprType() == REAL_EXPR) ? REAL_EXPR : INT_EXPR; +} + +String VaritypeScalarBinaryOp::evalCastToStr() { + return (exprType() == REAL_EXPR) ? + RealExpr::evalCastToStr() : IntExpr::evalCastToStr(); +} + void If::dump(int level) { printIndents(level); if (ifStatements && elseStatements) @@ -849,28 +1089,54 @@ return lhs->isConstExpr() && rhs->isConstExpr(); } -vmint Relation::evalInt() { +template +static inline vmint _evalRelation(Relation::Type type, T_LHS lhs, T_RHS rhs) { switch (type) { - case LESS_THAN: - return lhs->evalInt() < rhs->evalInt(); - case GREATER_THAN: - return lhs->evalInt() > rhs->evalInt(); - case LESS_OR_EQUAL: - return lhs->evalInt() <= rhs->evalInt(); - case GREATER_OR_EQUAL: - return lhs->evalInt() >= rhs->evalInt(); - case EQUAL: - if (lhs->exprType() == STRING_EXPR || rhs->exprType() == STRING_EXPR) + case Relation::LESS_THAN: + return lhs < rhs; + case Relation::GREATER_THAN: + return lhs > rhs; + case Relation::LESS_OR_EQUAL: + return lhs <= rhs; + case Relation::GREATER_OR_EQUAL: + return lhs >= rhs; + case Relation::EQUAL: + return lhs == rhs; + case Relation::NOT_EQUAL: + return lhs != rhs; + } + return 0; +} + +vmint Relation::evalInt() { + const ExprType_t lType = lhs->exprType(); + const ExprType_t rType = rhs->exprType(); + if (lType == STRING_EXPR || rType == STRING_EXPR) { + switch (type) { + case EQUAL: return lhs->evalCastToStr() == rhs->evalCastToStr(); - else - return lhs->evalInt() == rhs->evalInt(); - case NOT_EQUAL: - if (lhs->exprType() == STRING_EXPR || rhs->exprType() == STRING_EXPR) + case NOT_EQUAL: return lhs->evalCastToStr() != rhs->evalCastToStr(); - else - return lhs->evalInt() != rhs->evalInt(); + default: + return 0; + } + } else if (lType == REAL_EXPR && rType == REAL_EXPR) { + return _evalRelation( + type, lhs->asReal()->evalReal(), rhs->asReal()->evalReal() + ); + } else if (lType == REAL_EXPR && rType == INT_EXPR) { + return _evalRelation( + type, lhs->asReal()->evalReal(), rhs->asInt()->evalInt() + ); + } else if (lType == INT_EXPR && rType == REAL_EXPR) { + return _evalRelation( + type, lhs->asInt()->evalInt(), rhs->asReal()->evalReal() + ); + } else { + return _evalRelation( + type, lhs->asInt()->evalInt(), rhs->asInt()->evalInt() + ); } - return 0; } void Relation::dump(int level) { @@ -993,6 +1259,13 @@ printf(")\n"); } +String Final::evalCastToStr() { + if (exprType() == REAL_EXPR) + return ToString(evalReal()); + else + return ToString(evalInt()); +} + void Final::dump(int level) { printIndents(level); printf("Final(\n"); @@ -1029,6 +1302,10 @@ return globalVar(name); } +RealVariableRef ParserContext::globalRealVar(const String& name) { + return globalVar(name); +} + StringVariableRef ParserContext::globalStrVar(const String& name) { return globalVar(name); } @@ -1039,6 +1316,10 @@ delete globalIntMemory; globalIntMemory = NULL; } + if (globalRealMemory) { + delete globalRealMemory; + globalRealMemory = NULL; + } } void ParserContext::addErr(int firstLine, int lastLine, int firstColumn, int lastColumn, const char* txt) { @@ -1166,6 +1447,7 @@ ExecContext* child = dynamic_cast(ectx); child->polyphonicIntMemory.copyFlatFrom(polyphonicIntMemory); + child->polyphonicRealMemory.copyFlatFrom(polyphonicRealMemory); child->status = VM_EXEC_SUSPENDED; child->flags = STMT_SUCCESS; child->stack.copyFlatFrom(stack);