void LuaStack::pushLuaValue(const LuaValue& value) { const LuaValueType type = value.getType(); if (type == LuaValueTypeInt) { return pushInt(value.intValue()); } else if (type == LuaValueTypeFloat) { return pushFloat(value.floatValue()); } else if (type == LuaValueTypeBoolean) { return pushBoolean(value.booleanValue()); } else if (type == LuaValueTypeString) { return pushString(value.stringValue().c_str()); } else if (type == LuaValueTypeDict) { pushLuaValueDict(value.dictValue()); } else if (type == LuaValueTypeArray) { pushLuaValueArray(value.arrayValue()); } else if (type == LuaValueTypeObject) { pushObject(value.ccobjectValue(), value.getObjectTypename().c_str()); } }
primitiveDotProduct(void) { sqInt arg; float *argPtr; sqInt i; sqInt length; sqInt rcvr; float *rcvrPtr; double result; arg = stackValue(0); rcvr = stackValue(1); if (!((isWords(arg)) && ((isWords(rcvr)) && (((length = stSizeOf(arg))) == (stSizeOf(rcvr)))))) { return primitiveFail(); } rcvrPtr = ((float *) (firstIndexableField(rcvr))); argPtr = ((float *) (firstIndexableField(arg))); result = 0.0; for (i = 0; i < length; i += 1) { result += (((double) (rcvrPtr[i]))) * (((double) (argPtr[i]))); } pop(2); pushFloat(result); return 0; }
int CCLuaEngine::pushCCLuaValue(const CCLuaValue& value) { const CCLuaValueType type = value.getType(); if (type == CCLuaValueTypeInt) { return pushInt(value.intValue()); } else if (type == CCLuaValueTypeFloat) { return pushFloat(value.floatValue()); } else if (type == CCLuaValueTypeBoolean) { return pushBoolean(value.booleanValue()); } else if (type == CCLuaValueTypeString) { return pushString(value.stringValue().c_str()); } else if (type == CCLuaValueTypeDict) { pushCCLuaValueDict(value.dictValue()); } else if (type == CCLuaValueTypeArray) { pushCCLuaValueArray(value.arrayValue()); } else if (type == CCLuaValueTypeCCObject) { pushCCObject(value.ccobjectValue(), value.getCCObjectTypename().c_str()); } return lua_gettop(m_state); }
void Stack::pushVariable(const Variable &var) { switch (var.getType()) { case kTypeNil: pushNil(); break; case kTypeBoolean: pushBoolean(var.getBool()); break; case kTypeNumber: pushFloat(var.getFloat()); break; case kTypeString: pushString(var.getString()); break; case kTypeTable: pushTable(var.getTable()); break; case kTypeFunction: pushFunction(var.getFunction()); break; case kTypeUserType: pushRawUserType(var.getRawUserType(), var.getExactType()); break; default: warning("Pushing a varible of type \"%s\" not supported", var.getExactType().c_str()); break; } }
primitiveDotProduct(void) { // FloatArrayPlugin>>#primitiveDotProduct sqInt arg; float *argPtr; sqInt i; sqInt length; sqInt rcvr; float *rcvrPtr; double result; arg = stackObjectValue(0); rcvr = stackObjectValue(1); if (failed()) { return null; } success(isWords(arg)); success(isWords(rcvr)); if (failed()) { return null; } length = stSizeOf(arg); success(length == (stSizeOf(rcvr))); if (failed()) { return null; } rcvrPtr = ((float *) (firstIndexableField(rcvr))); argPtr = ((float *) (firstIndexableField(arg))); result = 0.0; for (i = 0; i <= (length - 1); i += 1) { result += (((double) (rcvrPtr[i]))) * (((double) (argPtr[i]))); } pop(2); pushFloat(result); }
int Viewport::pushValueToLua(CXLUAFUNC handler,const float value) { int ret = -1; if (0 == handler) { return ret; } auto stack = LuaEngine::getInstance()->getLuaStack(); stack->pushFloat(value); ret = stack->executeFunctionByHandler(handler, 1); stack->clean(); return ret; }
int CCLuaEngine::executeSchedule(CCTimer* pTimer, float dt, CCNode* pNode/* = NULL*/) { int ret = 0; do { int nScriptHandler = pTimer->getScriptHandler(); CC_BREAK_IF(0 == nScriptHandler); cleanStack(); pushFloat(dt); ret = executeFunctionByHandler(nScriptHandler, 1); } while (0); return ret; }
primitiveTanH(void) { // FloatMathPlugin>>#primitiveTanH double rcvr; double result; rcvr = stackFloatValue(0); if (failed()) { return null; } result = __ieee754_tanh(rcvr); if (isnan(result)) { return primitiveFail(); } pop((methodArgumentCount()) + 1); pushFloat(result); }
primitiveFractionalPart(void) { // FloatMathPlugin>>#primitiveFractionalPart double rcvr; double result; double trunc; rcvr = stackFloatValue(0); if (failed()) { return null; } result = __ieee754_modf(rcvr, &trunc); if (isnan(result)) { return primitiveFail(); } pop((methodArgumentCount()) + 1); pushFloat(result); }
primitiveTimesTwoPower(void) { // FloatMathPlugin>>#primitiveTimesTwoPower sqInt arg; double rcvr; double result; arg = stackIntegerValue(0); rcvr = stackFloatValue(1); if (failed()) { return null; } result = __ieee754_ldexp(rcvr, arg); if (isnan(result)) { return primitiveFail(); } pop((methodArgumentCount()) + 1); pushFloat(result); }
primitiveRaisedToPower(void) { // FloatMathPlugin>>#primitiveRaisedToPower double arg; double rcvr; double result; arg = stackFloatValue(0); rcvr = stackFloatValue(1); if (failed()) { return null; } result = __ieee754_pow(rcvr, arg); if (isnan(result)) { return primitiveFail(); } pop((methodArgumentCount()) + 1); pushFloat(result); }
primitiveAt(void) { float *floatPtr; double floatValue; sqInt index; sqInt rcvr; index = stackIntegerValue(0); rcvr = stackValue(1); if (!((!(failed())) && ((isWords(rcvr)) && ((index > 0) && (index <= (slotSizeOf(rcvr))))))) { return primitiveFail(); } floatPtr = firstIndexableField(rcvr); floatValue = ((double) (floatPtr[index - 1]) ); pop(2); pushFloat(floatValue); return 0; }
primitiveAt(void) { // FloatArrayPlugin>>#primitiveAt float *floatPtr; double floatValue; sqInt index; sqInt rcvr; index = stackIntegerValue(0); rcvr = stackObjectValue(1); if (failed()) { return null; } success(isWords(rcvr)); success((index > 0) && (index <= (slotSizeOf(rcvr)))); if (failed()) { return null; } floatPtr = firstIndexableField(rcvr); floatValue = ((double) (floatPtr[index - 1]) ); pop(2); pushFloat(floatValue); }
void Operators::doOperator(Context *context, OperatorType oper) { Token token1, token2, token3; stutskFloat f1, f2; stutskInteger i1, i2; string s1, s2; switch (oper) { case OP_ASSIG: token1 = stack_back_safe(); stutskStack.pop_back(); // Variable token2 = stack_back_safe(); stutskStack.pop_back(); // Value setVariable(token1, token2); break; case OP_ASSIG_REF: token1 = stack_back_safe(); stutskStack.pop_back(); // Variable token2 = stack_back_safe(); stutskStack.pop_back(); // Value setVariable(token1, token2, true); break; case OP_FUNC: token1 = stack_back_safe(); stutskStack.pop_back(); // Name token2 = stack_back_safe(); stutskStack.pop_back(); // Codeblock recurseVariables(token2); if (token2.tokenType != T_CODEBLOCK) { throw StutskException(ET_ERROR, "Token is not a codeblock"); } else { OperatorType dummy; string functionName = *giveString(token1); if (readOperator(functionName, dummy)) throw StutskException(ET_ERROR, "Cannot override an operator"); if (functionName.substr(0,10) == "__builtin_") throw StutskException(ET_ERROR, "Cannot override an internal function"); userFunctions[functionName] = *token2.asTokenList; } break; case OP_UNSET: token1 = stack_back_safe(); stutskStack.pop_back(); if (token1.tokenType == T_VARIABLE) { struct Token::_un_TokenData::_un_VariableData *var = & token1.data.asVariable; TokenMap::iterator iter = var->context->variables.find(var->name); if (iter != var->context->variables.end()) var->context->variables.erase(iter); } else { UserFunctionsMap::iterator iter = userFunctions.find(*giveString(token1)); if (iter != userFunctions.end()) userFunctions.erase(iter); } break; case OP_DEREF: token1 = stack_back_safe(); stutskStack.pop_back(); if (token1.tokenType != T_VARIABLE) { throw StutskException(ET_ERROR, "Token is not a variable"); } else { recurseVariables(token1, true); stutskStack.push_back(copy_token(token1)); } break; case OP_PLUSPLUS: token1 = stack_back_safe(); stutskStack.pop_back(); // Name if (token1.tokenType == T_VARIABLE) { switch (giveGCD(token1, f1, i1, s1)) { case NT_INVALID: case NT_STRING: throw StutskException(ET_ERROR, "Variable is not a numeric type"); case NT_INTEGER: token2.tokenType = T_INTEGER; token2.data.asInteger = i1 + 1; setVariable(token1, token2); break; case NT_FLOAT: token2.tokenType = T_FLOAT; token2.data.asFloat = f1 + 1.; setVariable(token1, token2); break; } } else { switch (giveGCD(token1, f1, i1, s1)) { case NT_INVALID: case NT_STRING: throw StutskException(ET_ERROR, "Token is not a numeric type"); case NT_INTEGER: pushInteger(++i1); break; case NT_FLOAT: pushFloat(++f1); break; } } break; case OP_MINMIN: token1 = stack_back_safe(); stutskStack.pop_back(); // Name if (token1.tokenType == T_VARIABLE) { switch (giveGCD(token1, f1, i1, s1)) { case NT_INVALID: case NT_STRING: throw StutskException(ET_ERROR, "Variable is not a numeric type"); case NT_INTEGER: token2.tokenType = T_INTEGER; token2.data.asInteger = i1 - 1; setVariable(token1, token2); break; case NT_FLOAT: token2.tokenType = T_FLOAT; token2.data.asFloat = f1 - 1.; setVariable(token1, token2); break; } } else { switch (giveGCD(token1, f1, i1, s1)) { case NT_INVALID: case NT_STRING: throw StutskException(ET_ERROR, "Token is not a numeric type"); case NT_INTEGER: pushInteger(--i1); break; case NT_FLOAT: pushFloat(--f1); break; } } break; case OP_PLUS: token1 = stack_back_safe(); stutskStack.pop_back(); token2 = stack_back_safe(); stutskStack.pop_back(); switch (giveGCD(token1, f1, i1, s1)) { case NT_STRING: case NT_INVALID: throw StutskException(ET_ERROR, "Token is not a numeric type"); case NT_INTEGER: switch (giveGCD(token2, f2, i2, s1)) { case NT_STRING: case NT_INVALID: throw StutskException(ET_ERROR, "Token is not a numeric type"); case NT_INTEGER: i1 += i2; pushInteger(i1); break; case NT_FLOAT: f2 += i1; pushFloat(f2); break; } break; case NT_FLOAT: f1 += giveFloat(token2); pushFloat(f1); break; } break; case OP_MINUS: token1 = stack_back_safe(); stutskStack.pop_back(); token2 = stack_back_safe(); stutskStack.pop_back(); switch (giveGCD(token1, f1, i1, s1)) { case NT_STRING: case NT_INVALID: throw StutskException(ET_ERROR, "Token is not a numeric type"); case NT_INTEGER: switch (giveGCD(token2, f2, i2, s1)) { case NT_STRING: case NT_INVALID: throw StutskException(ET_ERROR, "Token is not a numeric type"); case NT_INTEGER: i2 -= i1; pushInteger(i2); break; case NT_FLOAT: f2 -= i1; pushFloat(f2); break; } break; case NT_FLOAT: f2 = giveFloat(token2) - f1; pushFloat(f2); break; } break; case OP_MULTIP: token1 = stack_back_safe(); stutskStack.pop_back(); token2 = stack_back_safe(); stutskStack.pop_back(); switch (giveGCD(token1, f1, i1, s1)) { case NT_STRING: case NT_INVALID: throw StutskException(ET_ERROR, "Token is not a numeric type"); case NT_INTEGER: switch (giveGCD(token2, f2, i2, s1)) { case NT_STRING: case NT_INVALID: throw StutskException(ET_ERROR, "Token is not a numeric type"); case NT_INTEGER: i1 *= i2; pushInteger(i1); break; case NT_FLOAT: f2 *= i1; pushFloat(f2); break; } break; case NT_FLOAT: f1 *= giveFloat(token2); pushFloat(f1); break; } break; case OP_DIV: token1 = stack_back_safe(); stutskStack.pop_back(); token2 = stack_back_safe(); stutskStack.pop_back(); switch (giveGCD(token1, f1, i1, s1)) { case NT_STRING: case NT_INVALID: throw StutskException(ET_ERROR, "Token is not a numeric type"); case NT_INTEGER: if (i1 == 0) throw StutskException(ET_ERROR, "Division by zero"); switch (giveGCD(token2, f2, i2, s1)) { case NT_STRING: case NT_INVALID: throw StutskException(ET_ERROR, "Token is not a numeric type"); case NT_INTEGER: f1 = (stutskFloat)i2 / (stutskFloat)i1; pushFloat(f1); break; case NT_FLOAT: f2 /= (stutskFloat)i1; pushFloat(f2); break; } break; case NT_FLOAT: if (f1 == 0.) throw StutskException(ET_ERROR, "Division by zero"); f2 = giveFloat(token2) / f1; pushFloat(f2); break; } break; case OP_DIVINT: token1 = stack_back_safe(); stutskStack.pop_back(); token2 = stack_back_safe(); stutskStack.pop_back(); switch (giveGCD(token1, f1, i1, s1)) { case NT_STRING: case NT_INVALID: throw StutskException(ET_ERROR, "Token is not a numeric type"); case NT_INTEGER: switch (giveGCD(token2, f2, i2, s1)) { case NT_STRING: case NT_INVALID: throw StutskException(ET_ERROR, "Token is not a numeric type"); case NT_INTEGER: i1 = (stutskInteger)i2 / i1; pushInteger(i1); break; case NT_FLOAT: i2 = (stutskInteger)f2 / i1; pushInteger(i2); break; } break; case NT_FLOAT: i2 = giveInteger(token2) / (stutskInteger)f1; pushInteger(i2); break; } break; case OP_MOD: token1 = stack_back_safe(); stutskStack.pop_back(); token2 = stack_back_safe(); stutskStack.pop_back(); switch (giveGCD(token1, f1, i1, s1)) { case NT_STRING: case NT_INVALID: throw StutskException(ET_ERROR, "Token is not a numeric type"); case NT_INTEGER: switch (giveGCD(token2, f2, i2, s1)) { case NT_STRING: case NT_INVALID: throw StutskException(ET_ERROR, "Token is not a numeric type"); case NT_INTEGER: i1 = (stutskInteger)i2 % i1; pushInteger(i1); break; case NT_FLOAT: i2 = (stutskInteger)f2 % i1; pushInteger(i2); break; } break; case NT_FLOAT: i2 = giveInteger(token2) % (stutskInteger)f1; pushInteger(i2); break; } break; case OP_LESSTHAN: token1 = stack_back_safe(); stutskStack.pop_back(); token2 = stack_back_safe(); stutskStack.pop_back(); pushBool(tokenNumericCompare(token1, token2) == CN_SMALLER); break; case OP_MORETHAN: token1 = stack_back_safe(); stutskStack.pop_back(); token2 = stack_back_safe(); stutskStack.pop_back(); pushBool(tokenNumericCompare(token1, token2) == CN_LARGER); break; case OP_LESSTHAN_EQ: token1 = stack_back_safe(); stutskStack.pop_back(); token2 = stack_back_safe(); stutskStack.pop_back(); pushBool(tokenNumericCompare(token1, token2) != CN_LARGER); break; case OP_MORETHAN_EQ: token1 = stack_back_safe(); stutskStack.pop_back(); token2 = stack_back_safe(); stutskStack.pop_back(); pushBool(tokenNumericCompare(token1, token2) != CN_SMALLER); break; case OP_EQ: token1 = stack_back_safe(); stutskStack.pop_back(); token2 = stack_back_safe(); stutskStack.pop_back(); pushBool(tokenEqual(token1, token2)); break; case OP_SAME: token1 = stack_back_safe(); stutskStack.pop_back(); token2 = stack_back_safe(); stutskStack.pop_back(); pushBool(tokenSame(token1, token2)); break; case OP_NOTEQ: token1 = stack_back_safe(); stutskStack.pop_back(); token2 = stack_back_safe(); stutskStack.pop_back(); pushBool(!tokenEqual(token1, token2)); break; case OP_GLOBAL: token1 = stack_back_safe(); stutskStack.pop_back(); // Variable if (token1.tokenType != T_VARIABLE) { throw StutskException(ET_ERROR, "Token is not a variable"); } else { context->variableScopeMap[token1.data.asVariable.name] = VS_GLOBAL; } break; case OP_AUTO: token1 = stack_back_safe(); stutskStack.pop_back(); // Variable if (token1.tokenType != T_VARIABLE) { throw StutskException(ET_ERROR, "Token is not a variable"); } else { context->variableScopeMap[token1.data.asVariable.name] = VS_AUTO; } break; case OP_STATIC: token1 = stack_back_safe(); stutskStack.pop_back(); // Variable if (token1.tokenType != T_VARIABLE) { throw StutskException(ET_ERROR, "Token is not a variable"); } else { context->variableScopeMap[token1.data.asVariable.name] = VS_STATIC; } break; case OP_FOREVER: token1 = stack_back_safe(); stutskStack.pop_back(); // Codeblock recurseVariables(token1); if (token1.tokenType != T_CODEBLOCK) { throw StutskException(ET_ERROR, "Token is not a codeblock"); } else { while (true) { context->run(*token1.asTokenList, "forever"); if (exitVar == OP_CONTINUE) exitVar = OP_INVALID; if (exitVar != OP_INVALID) break; } if (exitVar == OP_BREAK) exitVar = OP_INVALID; } break; case OP_FOREACH: token1 = stack_back_safe(); stutskStack.pop_back(); // Codeblock token2 = stack_back_safe(); stutskStack.pop_back(); // Codeblock recurseVariables(token1); if (token1.tokenType != T_CODEBLOCK) throw StutskException(ET_ERROR, "Token is not a codeblock"); recurseVariables(token2); if (token2.tokenType == T_ARRAY) { for (TokenList::const_iterator it = token2.asTokenList->begin(); it != token2.asTokenList->end(); ++it) { stutskStack.push_back(*it); stringstream ss; ss << "foreach [" << std::distance(token2.asTokenList->cbegin(), it) << "]"; context->run(*token1.asTokenList, ss.str()); if (exitVar == OP_CONTINUE) exitVar = OP_INVALID; if (exitVar != OP_INVALID) break; } } else if (token2.tokenType == T_DICTIONARY) { for (TokenMap::const_iterator it = token2.asDictionary->begin(); it != token2.asDictionary->end(); ++it) { stutskStack.push_back(it->second); StringPtr f = pushString(); *f = it->first; stringstream ss; ss << "foreach [" << it->first << "]"; context->run(*token1.asTokenList, ss.str()); if (exitVar == OP_CONTINUE) exitVar = OP_INVALID; if (exitVar != OP_INVALID) break; } } else { StringPtr s1_ptr = giveString(token2); for (int i = 0; i < (signed)s1_ptr->length(); i++) { *pushString() = (*s1_ptr)[i]; stringstream ss; ss << "foreach [" << i << "]"; context->run(*token1.asTokenList, ss.str()); if (exitVar == OP_CONTINUE) exitVar = OP_INVALID; if (exitVar != OP_INVALID) break; } } if (exitVar == OP_BREAK) exitVar = OP_INVALID; break; case OP_REPEAT: token1 = stack_back_safe(); stutskStack.pop_back(); // Codeblock token2 = stack_back_safe(); stutskStack.pop_back(); // Codeblock i1 = giveInteger(token2); recurseVariables(token1); if (token1.tokenType != T_CODEBLOCK) { throw StutskException(ET_ERROR, "Token is not a codeblock"); } else { while (i1 > 0) { stringstream ss; ss << "repeat [" << i1 << "]"; context->run(*token1.asTokenList, ss.str()); if (exitVar == OP_CONTINUE) exitVar = OP_INVALID; if (exitVar != OP_INVALID) break; i1--; } if (exitVar == OP_BREAK) exitVar = OP_INVALID; } break; case OP_TRY: token1 = stack_back_safe(); stutskStack.pop_back(); // Codeblock token2 = stack_back_safe(); stutskStack.pop_back(); // Codeblock recurseVariables(token1); recurseVariables(token2); if ((token2.tokenType != T_CODEBLOCK) || (token2.tokenType != T_CODEBLOCK)) { throw StutskException(ET_ERROR, "Token is not a codeblock"); } else { try { context->run(*token2.asTokenList, "try"); } catch (StutskException &e) { *pushString() = e.getMessage(); pushInteger(e.getLineNumber()); *pushString() = e.getFileName(); context->run(*token1.asTokenList, "try"); } catch (std::exception &e) { *pushString() = e.what(); pushInteger(errorToken.lineNum); *pushString() = ParseContext::get_by_id(errorToken.context_id).FileName; context->run(*token1.asTokenList, "try"); } } break; case OP_POWER: token1 = stack_back_safe(); stutskStack.pop_back(); // Codeblock token2 = stack_back_safe(); stutskStack.pop_back(); // Codeblock f1 = pow(giveFloat(token2), giveFloat(token1)); pushFloat(f1); break; case OP_THROW: token1 = stack_back_safe(); stutskStack.pop_back(); // Error name throw StutskException(ET_CUSTOM, *giveString(token1)); break; case OP_NOT: token1 = stack_back_safe(); stutskStack.pop_back(); pushBool(!giveBool(token1)); break; case OP_AND: token1 = stack_back_safe(); stutskStack.pop_back(); token2 = stack_back_safe(); stutskStack.pop_back(); pushBool(giveBool(token1) && giveBool(token2)); break; case OP_OR: token1 = stack_back_safe(); stutskStack.pop_back(); token2 = stack_back_safe(); stutskStack.pop_back(); pushBool(giveBool(token1) || giveBool(token2)); break; case OP_IF: token2 = stack_back_safe(); stutskStack.pop_back(); // Codeblock token1 = stack_back_safe(); stutskStack.pop_back(); // Codeblock recurseVariables(token2); if (token2.tokenType != T_CODEBLOCK) { throw StutskException(ET_ERROR, "Token is not a codeblock"); } else { if (giveBool(token1)) { context->run(*token2.asTokenList, "if"); } } break; case OP_IFELSE: token2 = stack_back_safe(); stutskStack.pop_back(); // Codeblock token3 = stack_back_safe(); stutskStack.pop_back(); // Codeblock token1 = stack_back_safe(); stutskStack.pop_back(); // Codeblock recurseVariables(token2); recurseVariables(token3); if ((token2.tokenType != T_CODEBLOCK) || (token3.tokenType != T_CODEBLOCK)) { throw StutskException(ET_ERROR, "Token is not a codeblock"); } else { if (giveBool(token1)) { context->run(*token3.asTokenList, "ifelse"); } else { context->run(*token2.asTokenList, "ifelse"); } } break; case OP_TERNARY: token2 = stack_back_safe(); stutskStack.pop_back(); // Codeblock token3 = stack_back_safe(); stutskStack.pop_back(); // Codeblock token1 = stack_back_safe(); stutskStack.pop_back(); // Codeblock stutskStack.push_back((giveBool(token1) ? token3 : token2)); break; case OP_CONCAT: token1 = stack_back_safe(); stutskStack.pop_back(); // Codeblock token2 = stack_back_safe(); stutskStack.pop_back(); // Codeblock // Be careful NOT to recurse variable here because we wouldn't want // to overwrite the saved value. if (token2.tokenType == T_STRING) // Performance optimization { token2.asString->append(*giveString(token1)); stutskStack.push_back(token2); } else // Should be fast enough ... *pushString() = *giveString(token2) + *giveString(token1); break; case OP_SWITCH: token2 = stack_back_safe(); stutskStack.pop_back(); // Codeblock token1 = stack_back_safe(); stutskStack.pop_back(); // Codeblock recurseVariables(token2); if (token2.tokenType != T_ARRAY) throw StutskException(ET_ERROR, "Token is not an array"); else { for (TokenList::iterator it = token2.asTokenList->begin(); it != token2.asTokenList->end(); ++it) { token3 = *it; recurseVariables(token3); if (token3.tokenType != T_ARRAY) throw StutskException(ET_ERROR, "Token is not an array"); else { if (token3.asTokenList->size() != 2) throw StutskException(ET_ERROR, "Array of wrong length"); if ((*token3.asTokenList)[1].tokenType != T_CODEBLOCK) throw StutskException(ET_ERROR, "Token is not a codeblock"); if (tokenEqual(token1, (*token3.asTokenList)[0])) { context->run(*(*token3.asTokenList)[1].asTokenList, "switch"); break; } } } } break; case OP_BREAK: case OP_CONTINUE: case OP_HALT: case OP_EXIT: exitVar = oper; break; case OP_ARRAY: token1 = stack_back_safe(); stutskStack.pop_back(); // Codeblock token2 = stack_back_safe(); stutskStack.pop_back(); // Codeblock recurseVariables(token1); if (token2.tokenType == T_VARIABLE) { if (token1.tokenType == T_ARRAY) { for (TokenList::iterator it = token1.asTokenList->begin(); it != token1.asTokenList->end(); ++it) token2.index.push_back(giveInteger(*it)); } else token2.index.push_back(giveInteger(token1)); stutskStack.push_back(token2); } else if (token2.tokenType == T_ARRAY) { if (token1.tokenType == T_ARRAY) { for (TokenList::iterator it = token1.asTokenList->begin(); it != token1.asTokenList->end(); ++it) { i1 = giveInteger(*it); if (i1 < 0) throw StutskException(ET_ERROR, "Array index underflow"); if ((signed)token2.asTokenList->size() >= i1 + 1) { token2 = (*token2.asTokenList)[i1]; } else throw StutskException(ET_ERROR, "Array index overflow"); } stutskStack.push_back(token2); } else { i1 = giveInteger(token1); if (i1 < 0) throw StutskException(ET_ERROR, "Array index underflow"); if ((signed)token2.asTokenList->size() >= i1 + 1) { stutskStack.push_back((*token2.asTokenList)[i1]); } else throw StutskException(ET_ERROR, "Array index overflow"); } } else { i1 = giveInteger(token1); StringPtr s1_ptr = giveString(token2); if (i1 < 0) throw StutskException(ET_ERROR, "String index underflow"); if ((signed)s1_ptr->length() >= i1 + 1) { *pushString() = (*s1_ptr)[i1]; } else throw StutskException(ET_ERROR, "String index overflow"); } } }
//------------------------------------------------------------------------------ // An adaptation of a function of the same name in the original Babuino code. //------------------------------------------------------------------------------ void Babuino::code_exec() { //Serial.println("code_exec()"); if (!_storage.getReadyToRead()) { // TO DO: What now? How do I report an error? } while (_states.getRunRequest() == RUNNING) { _storage.readByte(_regs.pc, _regs.opCode); _regs.pc++; switch (_regs.opCode) { case OP_CONFIG: withConfig(); break; case OP_MATH: withMath(); break; case OP_BYTE: case OP_INT8: case OP_SPAN: { //Serial.println("int8 "); uint8_t value; _regs.pc = _storage.readByte(_regs.pc, value); pushUint8(_stack, value); } break; case OP_SHORT: case OP_UINT16: { //Serial.print("int16: "); uint16_t value; _regs.pc = _storage.read<uint16_t>(_regs.pc, value); //Serial.println(value); pushUint16(_stack, value); } break; case OP_GLOBAL: { //Serial.print("global: "); STACKPTR value; _regs.pc = _storage.read<STACKPTR>(_regs.pc, value); //Serial.println(value); pushStackPtr(_stack, value); //_stack.push(_stack.getBottom() - value); } break; case OP_INT32: case OP_UINT32: { //Serial.print("int32 "); uint32_t value; _regs.pc = _storage.read<uint32_t>(_regs.pc, value); #ifdef SUPPORT_32BIT pushUint32(_stack, value); #else pushUint16(_stack, (value >> 16) & 0xFFFF); // High 16 bits pushUint16(_stack, value & 0xFFFF); // Low 16 bits #endif } break; #ifdef SUPPORT_FLOAT case OP_FLOAT: { //Serial.print("float "); float value; _regs.pc = _storage.read<float>(_regs.pc, value); pushFloat(_stack, value); } break; #endif #ifdef SUPPORT_DOUBLE case OP_DOUBLE: { //Serial.print("double "); double value; _regs.pc = _storage.read<double>(_regs.pc, value); pushDouble(_stack, value); } break; #endif case OP_BOOL: { //Serial.print("bool "); bool value; _regs.pc = _storage.read<bool>(_regs.pc, value); pushUint8(_stack, (uint8_t)value); } break; case OP_CPTR: { //Serial.print("cptr "); PROGPTR value; _regs.pc = _storage.read<PROGPTR>(_regs.pc, value); pushProgPtr(_stack, value); } break; #ifdef SUPPORT_STRING case OP_STRING: { //Serial.print("string: \""); // ***KLUDGE WARNING*** // Borrowing unused (hopefully) stack space as a buffer! // (To avoid having to allocate another buffer. uint8_t* psz = (uint8_t*)getTopAddress(_stack); uint8_t nextChar; int16_t i = -1; do { i++; _regs.pc = _storage.readByte(_regs.pc, nextChar); psz[i] = nextChar; } while (nextChar); //Serial.print((char *)psz); //Serial.print("\" "); // Logically this is wrong because I'm apparently // pushing a string to a location that it already // occupies. However, the stack implementation // pushes strings onto a separate stack, then // pushes the location onto the main stack. So // the string doesn't get copied over itself, and // is already copied before the first characters are // overwritten by pushing the said location onto the // main stack. //STACKSTATE state; //getStackState(_stack, &state); //Serial.print("[("); Serial.print(state.top); Serial.print(","); Serial.print(state.stringTop);Serial.print(") -> ("); pushString(_stack, psz); //getStackState(_stack, &state); //Serial.print(state.top); Serial.print(","); Serial.print(state.stringTop);Serial.println(")]"); } break; case OP_ASCII: { uint8_t* psz; topString(_stack, &psz); uint8_t ascii = psz[0]; popString(_stack); pushUint8(_stack, ascii); } break; case OP_STRLEN: { uint8_t* psz; topString(_stack, &psz); uint8_t len = strlen((char*)psz); popString(_stack); pushUint8(_stack, len); } break; #endif case OP_BEEP: //Serial.println("---beep---"); beep(); break; case OP_LEDON: //Serial.println("---LED on---"); userLed(true); // set the correct bit break; case OP_LEDOFF: //Serial.println("---LED off---"); userLed(false); break; case OP_WITHINT8: case OP_WITHUINT8: case OP_WITHINT16: case OP_WITHUINT16: case OP_WITHBOOL: case OP_WITHPTR: #ifdef SUPPORT_32BIT case OP_WITHINT32: case OP_WITHUINT32: #endif #ifdef SUPPORT_FLOAT case OP_WITHFLOAT: #endif #ifdef SUPPORT_DOUBLE case OP_WITHDOUBLE: #endif #ifdef SUPPORT_STRING case OP_WITHSTRING: #endif _regs.withCode = _regs.opCode; break; case OP_LOCAL: { //Serial.print("local: local frame ("); //Serial.print(_regs.localFrame); //Serial.print(") - "); STACKPTR varOffset; _regs.pc = _storage.read<uint16_t>(_regs.pc, (uint16_t&)varOffset); pushStackPtr(_stack, (STACKPTR)_regs.localFrame.top + varOffset); //Serial.print(varOffset); //Serial.print(" = global "); //Serial.println(_regs.localFrame + varOffset); } break; case OP_PARAM: { //Serial.print("param: "); STACKPTR varOffset; _regs.pc = _storage.read<uint16_t>(_regs.pc, (uint16_t&)varOffset); // We have an index into the parameters, which were put on // the stack in reverse order before the function call. // Calculate the absolute stack offset using the local // stack frame offset. // Also, the total size of the arguments was pushed last, // so we need to step past that too. // TODO: Check against the total argument size. pushStackPtr(_stack, getArgsLocation() - sizeof(uint8_t) // Number of args - varOffset // Offset to the required param ); } break; case OP_BLOCK: { //Serial.print("block "); descendBlock(); // Shift the flag to the next block bit //char psz[10]; //utoa(_regs.blockDepthMask, psz, 2); //Serial.println(psz); uint16_t blockLength; // Push address of next instruction (following the block // length data) pushProgPtr(_stack, (PROGPTR)_regs.pc + sizeof(uint16_t)); _storage.read<uint16_t>(_regs.pc, blockLength); // Step past the block (tests there will bring execution back) _regs.pc.increment(blockLength); } break; case OP_EOB: //Serial.println("--eob--"); setBlockExecuted(); // Set the bit to indicate that this block has executed break; case OP_DO: { //Serial.println("---do---"); // OP_DO is like OP_BLOCK except that execution falls through to // the top of the block of code unconditionally rather than jump // to the end where some condition is tested. // Need to: // - Push the address that the following OP_BLOCK would push // - Step past the: // - The OP_BLOCK code (uint8_t) // - The block size (uint16_t) // After going through the code block it should jump back to // the beginning of the OP_BLOCK and loop as usual. descendBlock(); // Shift the flag to the next block bit (normally done by OP_BLOCK) PROGPTR startOfBlock = (PROGPTR)_regs.pc + sizeof(uint8_t) +sizeof(uint16_t); pushProgPtr(_stack, startOfBlock); _regs.pc.set(startOfBlock); } break; case OP_WHILE: { //Serial.print("while "); bool condition; PROGPTR blockAddr; popUint8(_stack, (uint8_t*)&condition); //Serial.println(condition ? "true" : "false"); //_stack.pop(blockAddr); if (condition) // if true then go to the block start address { topProgPtr(_stack, &blockAddr); _regs.pc = blockAddr; } else { popProgPtr(_stack, &blockAddr); // Throw it away ascendBlock(); // Finished with this block now } } break; case OP_REPEAT: { //Serial.print("repeat "); PROGPTR blockAddr; uint16_t max; popProgPtr(_stack, &blockAddr); popUint16(_stack, &max); uint16_t repcount; if (!hasBlockExecuted()) // First time around? { repcount = 1; pushUint16(_stack, repcount); // point to the counter we just pushed STACKPTR slot = getTop(_stack); // Save outer loop's repcount pointer pushStackPtr(_stack, _regs.repcountLocation); // Set it to ours _regs.repcountLocation = slot; } else { getUint16(_stack, _regs.repcountLocation, &repcount); // Get counter value repcount++; } //Serial.println(repcount); if (repcount <= max) { setUint16(_stack, _regs.repcountLocation, repcount); pushUint16(_stack, max); pushProgPtr(_stack, blockAddr); _regs.pc = blockAddr; } else { // Restore the outer loop's repcount pointer popStackPtr(_stack, &_regs.repcountLocation); popUint16(_stack, &repcount); // Dispose of counter ascendBlock(); // Finished with this block now } } break; case OP_REPCOUNT: { uint16_t repcount; getUint16(_stack, _regs.repcountLocation, &repcount); pushUint16(_stack, repcount); } break; case OP_FOR: { //Serial.println("for "); // The counter variable has already been set to the from // value, so the from value isn't on the stack. PROGPTR blockAddr; int16_t step, to, from; STACKPTR counterOff; int16_t counterVal; popProgPtr(_stack, &blockAddr); popUint16(_stack, (uint16_t*)&step); popUint16(_stack, (uint16_t*)&to); popUint16(_stack, (uint16_t*)&from); popStackPtr(_stack, &counterOff); getUint16(_stack, counterOff, (uint16_t*)&counterVal); //Serial.print(counterVal); //Serial.print(" "); //Serial.print(to); //Serial.print(" "); //Serial.println(step); bool keepGoing; // See if this is the first time around if (!hasBlockExecuted()) { counterVal = from; keepGoing = true; } else { // If step > 0 then assume from < to otherwise assume from > to keepGoing = (step > 0) ? (counterVal < to) : (counterVal > to); counterVal += step; } if (keepGoing) { setUint16(_stack, counterOff, (uint16_t)counterVal); _regs.pc = blockAddr; // reiterate pushStackPtr(_stack, counterOff); // Var offset pushUint16(_stack, (uint16_t)from); // to pushUint16(_stack, (uint16_t)to); // to pushUint16(_stack, (uint16_t)step); // step pushProgPtr(_stack, blockAddr); } else { ascendBlock(); } } break; case OP_IF: { //Serial.print("if "); // If it's the first time through then check the // condition if (!hasBlockExecuted()) { PROGPTR blockAddr; bool condition; popProgPtr(_stack, &blockAddr); // Block initial address popUint8(_stack, (uint8_t*)&condition); // argument to test //Serial.println(condition ? "true" : "false"); if (condition) { _regs.pc = blockAddr; } else { ascendBlock(); } } else { ascendBlock(); } } break; // IFELSE starts with address of THEN and ELSE lists (and // CONDITIONAL) on the stack. CONDITIONAL is tested and // appropriate list is run. case OP_IFELSE: { //Serial.print("ifelse "); PROGPTR elseBlock; popProgPtr(_stack, &elseBlock); // ELSE block start // Note that descendBlock() will have been called twice // the first time around (once for each block). ascendBlock(); // Remove the else block... // ...and use the then block flag for both purposes if (!hasBlockExecuted()) { PROGPTR thenBlock; bool condition; popProgPtr(_stack, &thenBlock); // THEN block start popUint8(_stack, (uint8_t*)&condition); // argument to test if (condition) { //Serial.println("(then)"); _regs.pc = thenBlock; // The ELSE address will get pushed again when // execution falls into the ELSE block after // exiting the THEN block. // Another else block will be descended into // as well, and ascended away again above. // The eob code will be encountered at the end // of the then block, and that will set the // executed flag. } else { //Serial.println("(else)"); _regs.pc = elseBlock; // the "ELSE" list pushProgPtr(_stack, (PROGPTR)0); // Push fake ELSE to balance // Borrow the then block flag and set it now as // executed since it won't actually be set // otherwise. setBlockExecuted(); // Descend the else block now, as // this also won't be done in the block's code. descendBlock(); } } else { //popProgPtr(_stack, &elseBlock); // dispose of unrequired address ascendBlock(); // ie. the then block } } break; case OP_PUSH: { //Serial.print("push "); uint8_t amount; popUint8(_stack, &amount); pushn(_stack, (STACKPTR)amount); } break; case OP_POP: { //Serial.print("pop "); uint8_t amount; popUint8(_stack, &amount); popn(_stack, (STACKPTR)amount); } break; case OP_CHKPOINT: getStackState(_stack, &_regs.checkPoint); break; case OP_ROLLBACK: setStackState(_stack, &_regs.checkPoint); break; case OP_CALL: { //Serial.println("call"); PROGPTR procAddr; popProgPtr(_stack, &procAddr); // Get the function location // Save the args location used by the calling function, and // set it to what was the stack top before it was pushed. /* _regs.argsLoc = _stack.push(_regs.argsLoc); //Serial.print("args location: "); //Serial.println(_regs.argsLoc); */ pushProgPtr(_stack, (PROGPTR)_regs.pc); // Save the current code location for the return _regs.pc.set(procAddr); // Now jump to the function } break; case OP_BEGIN: //Serial.println("begin"); pushRegisters(); // Save state of the caller _regs.blockDepthMask = 0; _regs.blocksExecuted = 0; getStackState(_stack, &_regs.localFrame); // = getTop(_stack); //Serial.println(_regs.localFrame); break; case OP_RETURN: { //Serial.print("return "); //Unwind the stack to the beginning of the local frame setStackState(_stack, &_regs.localFrame); popRegisters(); PROGPTR returnAddr; popProgPtr(_stack, &returnAddr); // Get the return address //_stack.pop(_regs.argsLoc); // Restore the param location for the calling function _regs.pc.set(returnAddr); } break; case OP_EXIT: reset(); //Serial.println("---exit---"); break; case OP_LOOP: { //Serial.println("---loop---"); PROGPTR blockAddr; topProgPtr(_stack, &blockAddr); _regs.pc.set(blockAddr); } break; case OP_WAIT: { //Serial.println("---wait---"); uint16_t tenths; popUint16(_stack, &tenths); delay(100 * tenths); } break; case OP_TIMER: //Serial.print("timer "); pushUint16(_stack, _timerCount); // TODO: implement timer!! break; case OP_RESETT: //Serial.println("---resett---"); _timerCount = 0; break; case OP_RANDOM: //Serial.print("random "); pushUint16(_stack, (uint16_t)random(0, 32767)); break; case OP_RANDOMXY: { //Serial.print("randomxy "); int16_t x; int16_t y; popUint16(_stack, (uint16_t*)&y); popUint16(_stack, (uint16_t*)&x); pushUint16(_stack, (uint16_t)random(x, y)); } break; case OP_MOTORS: { //Serial.print("motors "); uint8_t selected; popUint8(_stack, &selected); _selectedMotors = (Motors::Selected)selected; } break; case OP_THISWAY: //Serial.print("---thisway---"); _motors.setDirection(_selectedMotors, MotorBase::THIS_WAY); break; case OP_THATWAY: //Serial.print("---thatway---"); _motors.setDirection(_selectedMotors, MotorBase::THAT_WAY); break; case OP_RD: //Serial.print("---rd---"); _motors.reverseDirection(_selectedMotors); break; case OP_SETPOWER: { //Serial.print("setpower "); uint8_t power; popUint8(_stack, &power); if (power > 7) power = 7; _motors.setPower(_selectedMotors, power); } break; case OP_BRAKE: //Serial.println("---brake---"); _motors.setBrake(_selectedMotors, MotorBase::BRAKE_ON); break; case OP_ON: //Serial.println("---on---"); _motors.on(_selectedMotors); break; case OP_ONFOR: { //Serial.print("onfor"); uint16_t tenths; popUint16(_stack, &tenths); _motors.on(_selectedMotors); delay(100 * tenths); _motors.off(_selectedMotors); } break; case OP_OFF: //Serial.println("---off---"); _motors.off(_selectedMotors); break; case OP_SENSOR1: case OP_SENSOR2: case OP_SENSOR3: case OP_SENSOR4: case OP_SENSOR5: case OP_SENSOR6: case OP_SENSOR7: case OP_SENSOR8: //Serial.print("sensor "); //Serial.print(_regs.opCode - OP_SENSOR1); //Serial.print(" "); pushUint16(_stack, (uint16_t)readAnalog(_regs.opCode - OP_SENSOR1)); break; case OP_AIN: { //Serial.print("ain "); uint8_t input; popUint8(_stack, &input); pushUint16(_stack, (uint16_t)readAnalog(input)); } break; case OP_AOUT: { //Serial.print("aout "); uint8_t output; uint8_t value; popUint8(_stack, &output); popUint8(_stack, &value); writeAnalog(output, value); } break; case OP_SWITCH1: case OP_SWITCH2: case OP_SWITCH3: case OP_SWITCH4: case OP_SWITCH5: case OP_SWITCH6: case OP_SWITCH7: case OP_SWITCH8: { //Serial.print("switch "); //Serial.print(_regs.opCode - OP_SWITCH1); //Serial.print(" "); int16_t val = readAnalog(_regs.opCode - OP_SWITCH1); if (val < 0) pushUint8(_stack, (uint8_t)false); else pushUint8(_stack, (uint8_t)!!(val >> 7)); } break; case OP_NOT: break; case OP_AND: break; case OP_OR: break; case OP_XOR: break; case OP_DIN: { //Serial.print("din "); uint8_t input; popUint8(_stack, &input); pushUint8(_stack, (uint8_t)readDigital(input)); } break; case OP_DOUT: { //Serial.print("dout "); uint8_t output; bool value; popUint8(_stack, &output); popUint8(_stack, (uint8_t*)&value); writeDigital(output, value); } break; case OP_BTOS: { int8_t value; popUint8(_stack, (uint8_t*)&value); pushUint16(_stack,(uint16_t)value); } break; case OP_UBTOS: { uint8_t value; popUint8(_stack, &value); pushUint16(_stack,(uint16_t)value); } break; case OP_STOB: // and OP_USTOB { //Serial.print("stob: "); uint16_t value; popUint16(_stack, (uint16_t*)&value); //Serial.println(value); pushUint8(_stack, (uint8_t)value); } break; #ifdef SUPPORT_32BIT case OP_BTOI: { int8_t value; popUint8(_stack, (uint8_t*)&value); pushUint32(_stack,(uint32_t)value); } break; case OP_UBTOI: { uint8_t value; popUint8(_stack, &value); pushUint32(_stack,(uint32_t)value); } break; case OP_STOI: { int16_t value; popUint16(_stack, (uint16_t*)&value); pushUint32(_stack,(uint32_t)value); } break; case OP_USTOI: { uint16_t value; popUint16(_stack, &value); pushUint32(_stack,(uint32_t)value); } break; case OP_ITOB: // and OP_UITOB { int32_t value; popUint32(_stack, (uint32_t*)&value); pushUint8(_stack, (uint8_t)value); } break; case OP_ITOS: //and OP_UITOS { int32_t value; popUint32(_stack, (uint32_t*)&value); pushUint16(_stack, (uint16_t)value); } break; #endif #ifdef SUPPORT_FLOAT case OP_BTOF: { int8_t value; popUint8(_stack, (uint8_t*)&value); pushFloat(_stack, (float)value); } break; case OP_UBTOF: { uint8_t value; popUint8(_stack, &value); pushFloat(_stack, (float)value); } break; case OP_STOF: { int16_t value; popUint16(_stack, (uint16_t*)&value); pushFloat(_stack, (float)value); } break; case OP_USTOF: { uint16_t value; popUint16(_stack, &value); pushFloat(_stack, (float)value); } break; case OP_FTOB: { float value; popFloat(_stack, &value); pushUint8(_stack, (uint8_t)value); } break; case OP_FTOS: { float value; popFloat(_stack, &value); pushUint16(_stack, (uint16_t)value); } break; #endif #ifdef SUPPORT_DOUBLE case OP_BTOD: { int8_t value; popUint8(_stack, (uint8_t*)&value); pushDouble(_stack, (double)value); } break; case OP_UBTOD: { uint8_t value; popUint8(_stack, &value); pushDouble(_stack, (double)value); } break; case OP_STOD: { int16_t value; popUint16(_stack, (uint16_t*)&value); pushDouble(_stack, (double)value); } break; case OP_USTOD: { uint16_t value; popUint8(_stack, (uint8_t*)&value); pushDouble(_stack, (double)value); } break; case OP_DTOB: { double value; popDouble(_stack, &value); pushUint8(_stack, (uint8_t)value); } break; case OP_DTOS: { double value; popDouble(_stack, &value); pushUint16(_stack, (uint16_t)value); } break; #endif #if defined(SUPPORT_DOUBLE) && defined(SUPPORT_32BIT) case OP_ITOD: { int32_t value; popUint32(_stack, (uint32_t*)&value); pushDouble(_stack, (double)value); } break; case OP_UITOD: { uint32_t value; popUint32(_stack, &value); pushDouble(_stack, (double)value); } break; case OP_DTOI: { double value; popDouble(_stack, &value); pushUint32(_stack, (uint32_t)value); } break; #endif #if defined(SUPPORT_DOUBLE) && defined(SUPPORT_FLOAT) case OP_FTOD: { float value; popFloat(_stack, &value); pushDouble(_stack, (double)value); } break; case OP_DTOF: { double value; popDouble(_stack, &value); pushFloat(_stack, (float)value); } break; #endif #if defined(SUPPORT_FLOAT) && defined(SUPPORT_32BIT) case OP_ITOF: { int32_t value; popUint32(_stack, (uint32_t*)&value); pushFloat(_stack, (float)value); } break; case OP_UITOF: { uint32_t value; popUint32(_stack, &value); pushFloat(_stack, (float)value); } break; case OP_FTOI: { float value; popFloat(_stack, &value); pushUint32(_stack, (uint32_t)value); } break; #endif case OP_I2CSTART: i2cStart(); break; case OP_I2CSTOP: i2cStop(); break; case OP_I2CTXRX: { uint16_t i2cAddr; uint16_t txBuffOffset; uint8_t txBuffLen; uint16_t rxBuffOffset; uint8_t rxBuffLen; uint16_t timeout; popUint16(_stack, &i2cAddr); popUint16(_stack, &txBuffOffset); popUint8(_stack, &txBuffLen); popUint16(_stack, &rxBuffOffset); popUint8(_stack, &rxBuffLen); popUint16(_stack, &timeout); i2cTxRx(i2cAddr, (uint8_t*)getStackAddress(_stack, txBuffOffset), txBuffLen, (uint8_t*)getStackAddress(_stack, rxBuffOffset), rxBuffLen, timeout); } break; case OP_I2CRX: { uint16_t addr; uint16_t rxBuffOffset; uint8_t rxBuffLen; uint16_t timeout; popUint16(_stack, &addr); popUint16(_stack, &rxBuffOffset); popUint8(_stack, &rxBuffLen); popUint16(_stack, &timeout); i2cRx(addr, (uint8_t*)getStackAddress(_stack, rxBuffOffset), rxBuffLen, timeout); } break; #ifdef SUPPORT_32BIT case OP_I2CERR: { //Serial.println("---i2cerr---"); uint32_t errors = i2cErrors(); pushUint32(_stack, errors); } break; #endif case OP_WAITUNTIL: case OP_RECORD: case OP_RECALL: case OP_RESETDP: case OP_SETDP: case OP_ERASE: case OP_SETSVH: case OP_SVR: case OP_SVL: // TODO!!! break; default: // All of the type specific codes are dealt with here if (!withCurrentType()) { //beep(); // Just an indication for now. Serial.print("unrecognised opcode: "); Serial.println(_regs.opCode); } break; } } }
int CCLuaEngine::executeSchedule(int nHandler, float dt, CCNode* pNode/* = NULL*/) { cleanStack(); pushFloat(dt); return executeFunctionByHandler(nHandler, 1); }