void execStatement(void) { if(codeToken == TKN_STATEMENT_MARKER) { execLineNumber = getCodeStatementMarker(); execStatementCount++; statementStartPtr = codeSegmentPtr; if(debugger) debugger->traceStatementExecution(); getCodeToken(); } switch(codeToken) { case TKN_IDENTIFIER: { SymTableNodePtr idPtr = getCodeSymTableNodePtr(); ABL_Assert(idPtr != nullptr, 0, " oops "); if(idPtr->defn.key == DFN_FUNCTION) { bool skipOrder = false; uint8_t orderDWord = 0; uint8_t orderBitMask = 0; if((idPtr->defn.info.routine.flags & ROUTINE_FLAG_ORDER) && CurModule->getOrderCallFlags()) { orderDWord = getCodeByte(); orderBitMask = getCodeByte(); skipOrder = !CurModule->isLibrary() && CurModule->getOrderCallFlag(orderDWord, orderBitMask); } TypePtr returnType = execRoutineCall(idPtr, skipOrder); if(idPtr->defn.info.routine.flags & ROUTINE_FLAG_ORDER) { if(AutoReturnFromOrders) { //----------------------------------------------------------------- // We called an Order function, and we're in an Orders/State block, // so do we continue the flow of orders or stop here? int32_t returnVal = tos->integer; pop(); if(returnVal == 0) execOrderReturn(returnVal); else if(CurModule->getOrderCallFlags()) { CurModule->setOrderCallFlag(orderDWord, orderBitMask); } } } else if(returnType) { //------------------------------------------ // In case this routine returns a value, pop // the return value off the stack... pop(); } } else execAssignmentStatement(idPtr); } break; case TKN_CODE: { bool wasAutoReturnFromOrders = AutoReturnFromOrders; AutoReturnFromOrders = ((CurRoutineIdPtr->defn.info.routine.flags & (ROUTINE_FLAG_ORDER + ROUTINE_FLAG_STATE)) != 0); getCodeToken(); TokenCodeType endToken = TKN_END_FUNCTION; if(CurRoutineIdPtr->defn.info.routine.flags & ROUTINE_FLAG_ORDER) endToken = TKN_END_ORDER; else if(CurRoutineIdPtr->defn.info.routine.flags & ROUTINE_FLAG_STATE) endToken = TKN_END_STATE; TokenCodeType endTokenFinal = TKN_END_MODULE; if(CurLibrary) endTokenFinal = TKN_END_LIBRARY; else if(CurRoutineIdPtr->defn.info.routine.flags & ROUTINE_FLAG_FSM) endTokenFinal = TKN_END_FSM; while((codeToken != endToken) && (codeToken != endTokenFinal) && !NewStateSet) execStatement(); if(NewStateSet) return; getCodeToken(); AutoReturnFromOrders = wasAutoReturnFromOrders; } break; case TKN_FOR: execForStatement(); break; case TKN_IF: execIfStatement(); break; case TKN_REPEAT: execRepeatStatement(); break; case TKN_WHILE: execWhileStatement(); break; case TKN_SWITCH: execSwitchStatement(); break; case TKN_TRANS: execTransStatement(); break; case TKN_TRANS_BACK: execTransBackStatement(); break; case TKN_SEMICOLON: case TKN_ELSE: case TKN_UNTIL: break; default: //runtimeError(ABL_ERR_RUNTIME_UNIMPLEMENTED_FEATURE); NODEFAULT; } while(codeToken == TKN_SEMICOLON) getCodeToken(); }