Esempio n. 1
0
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();
}