/* * Copyright (c) 2014-2015 Christian Schoenebeck * * http://www.linuxsampler.org * * This file is part of LinuxSampler and released under the same terms. * See README file for details. */ #include "CoreVMFunctions.h" #include #include #include #include "tree.h" #include "ScriptVM.h" namespace LinuxSampler { /////////////////////////////////////////////////////////////////////////// // class VMEmptyResultFunction VMFnResult* VMEmptyResultFunction::errorResult() { result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED); return &result; } VMFnResult* VMEmptyResultFunction::successResult() { result.flags = STMT_SUCCESS; return &result; } /////////////////////////////////////////////////////////////////////////// // class VMIntResultFunction VMFnResult* VMIntResultFunction::errorResult(int i) { result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED); result.value = i; return &result; } VMFnResult* VMIntResultFunction::successResult(int i) { result.flags = STMT_SUCCESS; result.value = i; return &result; } /////////////////////////////////////////////////////////////////////////// // class VMStringResultFunction VMFnResult* VMStringResultFunction::errorResult(const String& s) { result.flags = StmtFlags_t(STMT_ABORT_SIGNALLED | STMT_ERROR_OCCURRED); result.value = s; return &result; } VMFnResult* VMStringResultFunction::successResult(const String& s) { result.flags = STMT_SUCCESS; result.value = s; return &result; } /////////////////////////////////////////////////////////////////////////// // built-in script function: message() bool CoreVMFunction_message::acceptsArgType(int iArg, ExprType_t type) const { return type == INT_EXPR || type == STRING_EXPR; } VMFnResult* CoreVMFunction_message::exec(VMFnArgs* args) { if (!args->argsCount()) return errorResult(); VMStringExpr* strExpr = dynamic_cast(args->arg(0)); if (strExpr) { std::cout << "[ScriptVM] " << strExpr->evalStr() << "\n"; return successResult(); } VMIntExpr* intExpr = dynamic_cast(args->arg(0)); if (intExpr) { std::cout << "[ScriptVM] " << intExpr->evalInt() << "\n"; return successResult(); } return errorResult(); } /////////////////////////////////////////////////////////////////////////// // built-in script function: exit() VMFnResult* CoreVMFunction_exit::exec(VMFnArgs* args) { this->result.flags = STMT_ABORT_SIGNALLED; return &result; } /////////////////////////////////////////////////////////////////////////// // built-in script function: wait() VMFnResult* CoreVMFunction_wait::exec(VMFnArgs* args) { ExecContext* ctx = dynamic_cast(vm->currentVMExecContext()); VMIntExpr* expr = dynamic_cast(args->arg(0)); int us = expr->evalInt(); if (us < 0) { wrnMsg("wait(): argument may not be negative! Aborting script!"); this->result.flags = STMT_ABORT_SIGNALLED; } else if (us == 0) { wrnMsg("wait(): argument may not be zero! Aborting script!"); this->result.flags = STMT_ABORT_SIGNALLED; } else { ctx->suspendMicroseconds = us; this->result.flags = STMT_SUSPEND_SIGNALLED; } return &result; } /////////////////////////////////////////////////////////////////////////// // built-in script function: abs() bool CoreVMFunction_abs::acceptsArgType(int iArg, ExprType_t type) const { return type == INT_EXPR; } VMFnResult* CoreVMFunction_abs::exec(VMFnArgs* args) { return successResult( ::abs(args->arg(0)->asInt()->evalInt()) ); } /////////////////////////////////////////////////////////////////////////// // built-in script function: random() bool CoreVMFunction_random::acceptsArgType(int iArg, ExprType_t type) const { return type == INT_EXPR; } VMFnResult* CoreVMFunction_random::exec(VMFnArgs* args) { int iMin = args->arg(0)->asInt()->evalInt(); int iMax = args->arg(1)->asInt()->evalInt(); float f = float(::rand()) / float(RAND_MAX); return successResult( iMin + roundf( f * float(iMax - iMin) ) ); } /////////////////////////////////////////////////////////////////////////// // built-in script function: num_elements() bool CoreVMFunction_num_elements::acceptsArgType(int iArg, ExprType_t type) const { return type == INT_ARR_EXPR; } VMFnResult* CoreVMFunction_num_elements::exec(VMFnArgs* args) { return successResult( args->arg(0)->asIntArray()->arraySize() ); } /////////////////////////////////////////////////////////////////////////// // built-in script function: inc() VMFnResult* CoreVMFunction_inc::exec(VMFnArgs* args) { VMExpr* arg = args->arg(0); VMIntExpr* in = dynamic_cast(arg); VMVariable* out = dynamic_cast(arg); if (!in || !out) successResult(0); int i = in->evalInt() + 1; IntLiteral tmp(i); out->assignExpr(&tmp); return successResult(i); } /////////////////////////////////////////////////////////////////////////// // built-in script function: dec() VMFnResult* CoreVMFunction_dec::exec(VMFnArgs* args) { VMExpr* arg = args->arg(0); VMIntExpr* in = dynamic_cast(arg); VMVariable* out = dynamic_cast(arg); if (!in || !out) successResult(0); int i = in->evalInt() - 1; IntLiteral tmp(i); out->assignExpr(&tmp); return successResult(i); } /////////////////////////////////////////////////////////////////////////// // built-in script function: sh_left() VMFnResult* CoreVMFunction_sh_left::exec(VMFnArgs* args) { int i = args->arg(0)->asInt()->evalInt(); int n = args->arg(1)->asInt()->evalInt(); return successResult(i << n); } /////////////////////////////////////////////////////////////////////////// // built-in script function: sh_right() VMFnResult* CoreVMFunction_sh_right::exec(VMFnArgs* args) { int i = args->arg(0)->asInt()->evalInt(); int n = args->arg(1)->asInt()->evalInt(); return successResult(i >> n); } /////////////////////////////////////////////////////////////////////////// // built-in script function: min() VMFnResult* CoreVMFunction_min::exec(VMFnArgs* args) { int l = args->arg(0)->asInt()->evalInt(); int r = args->arg(1)->asInt()->evalInt(); return successResult(l < r ? l : r); } /////////////////////////////////////////////////////////////////////////// // built-in script function: max() VMFnResult* CoreVMFunction_max::exec(VMFnArgs* args) { int l = args->arg(0)->asInt()->evalInt(); int r = args->arg(1)->asInt()->evalInt(); return successResult(l > r ? l : r); } } // namespace LinuxSampler