Example #1
0
void execIfStatement(void)
{
	getCodeToken();
	PSTR falseLocation = getCodeAddressMarker();
	//-------------------------------
	// Eval the boolean expression. Note that, unlike C/C++, the expression
	// must be true(1) or false(0). In C/C++, an expression is true if it's
	// non-zero. Not the case in ABL using this current implementation. Do we
	// want to change this?
	getCodeToken();
	execExpression();
	bool test = (tos->integer == 1);
	pop();
	if(test)
	{
		//---------------------------
		// execute the TRUE branch...
		getCodeToken();
		if((codeToken != TKN_END_IF) && (codeToken != TKN_ELSE))
			do
			{
				execStatement();
				if(ExitWithReturn)
					return;
			}
			while((codeToken != TKN_END_IF) && (codeToken != TKN_ELSE));
		if(codeToken == TKN_ELSE)
		{
			getCodeToken();
			codeSegmentPtr = getCodeAddressMarker();
			getCodeToken();
		}
	}
	else
	{
		//----------------------------
		// Execute the FALSE branch...
		codeSegmentPtr = falseLocation;
		getCodeToken();
		if(codeToken == TKN_ELSE)
		{
			getCodeToken();
			getCodeAddressMarker();
			getCodeToken();
			if(codeToken != TKN_END_IF)
				do
				{
					execStatement();
					if(ExitWithReturn)
						return;
				}
				while(codeToken != TKN_END_IF);
		}
	}
	getCodeToken();
}
Example #2
0
void execRepeatStatement(void)
{
	PSTR loopStartLocation = codeSegmentPtr;
	int32_t iterations = 0;
	do
	{
		getCodeToken();
		if(codeToken != TKN_UNTIL)
			do
			{
				execStatement();
				if(ExitWithReturn)
					return;
			}
			while(codeToken != TKN_UNTIL);
		//---------------------------
		// Check for infinite loop...
		iterations++;
		if(iterations == MaxLoopIterations)
			runtimeError(ABL_ERR_RUNTIME_INFINITE_LOOP);
		//-------------------------------
		// Eval the boolean expression...
		getCodeToken();
		execExpression();
		if(tos->integer == 0)
			codeSegmentPtr = loopStartLocation;
		//--------------------------
		// Grab the boolean value...
		pop();
	}
	while(codeSegmentPtr == loopStartLocation);
}
Example #3
0
void execSwitchStatement (void) {

	getCodeToken();
		
	char* branchTableLocation = getCodeAddressMarker();

	getCodeToken();
	TypePtr switchExpressionTypePtr = execExpression();

	long switchExpressionValue;
	if ((switchExpressionTypePtr == IntegerTypePtr) || (switchExpressionTypePtr->form == FRM_ENUM))
		switchExpressionValue = tos->integer;
	else
		switchExpressionValue = tos->byte;
	pop();

	//---------------------------------------------------------
	// Now, search the branch table for the expression value...
	codeSegmentPtr = branchTableLocation;
	getCodeToken();
	long caseLabelCount = getCodeInteger();
	bool done = false;
	char* caseBranchLocation = NULL;
	while (!done && caseLabelCount--) {
		long caseLabelValue = getCodeInteger();
		caseBranchLocation = getCodeAddress();
		done = (caseLabelValue == switchExpressionValue);
	}

	//-----------------------------------------------
	// If found, go to the aprropriate branch code...
	if (caseLabelCount >= 0) {
		codeSegmentPtr = caseBranchLocation;
		getCodeToken();

		if (codeToken != TKN_END_CASE)
			do {
				execStatement();
				if (ExitWithReturn)
					return;
			} while (codeToken != TKN_END_CASE);
		

		//----------------------------------
		// Grab the end case and semi-colon...
		getCodeToken();
		getCodeToken();
		codeSegmentPtr = getCodeAddressMarker();
		getCodeToken();
		}
	else {
		//-----------------------------------------------------------------
		// Since the branch table is located at the end of the case blocks,
		// the code directly after the switch statement follows our
		// current code location, already. Just grab the endswitch
		// and semi-colon...
		getCodeToken();
		getCodeToken();
	}
}
Example #4
0
void execWhileStatement (void) {

	getCodeToken();
	char* loopEndLocation = getCodeAddressMarker();
	char* testLocation = codeSegmentPtr;

	bool loopDone = false;
	long iterations = 0;
	do {
		//-------------------------------
		// Eval the boolean expression...
		getCodeToken();
		execExpression();
		if (tos->integer == 0) {
			codeSegmentPtr = loopEndLocation;
			loopDone = true;
		}
		
		//-------------------------
		// Get the boolean value...
		pop();

		//----------------------------------
		// If TRUE, execute the statement...
		if (!loopDone) {
			getCodeToken();

			if (codeToken != TKN_END_WHILE)
				do {
					execStatement();
					if (ExitWithReturn)
						return;
				} while (codeToken != TKN_END_WHILE);

			codeSegmentPtr = testLocation;

			//---------------------------
			// Check for infinite loop...
			iterations++;
			if (iterations == MaxLoopIterations)
				runtimeError(ABL_ERR_RUNTIME_INFINITE_LOOP);
		}
	} while (!loopDone);

	getCodeToken();
}
Example #5
0
void execute(SymTableNodePtr routineIdPtr)
{
	SymTableNodePtr thisRoutineIdPtr = CurRoutineIdPtr;
	CurRoutineIdPtr = routineIdPtr;
	routineEntry(routineIdPtr);
	//----------------------------------------------------
	// Now, search this module for the function we want...
	if(CallModuleInit)
	{
		CallModuleInit = false;
		SymTableNodePtr initFunctionIdPtr = searchSymTable("init", ModuleRegistry[CurModule->getHandle()].moduleIdPtr->defn.info.routine.localSymTable);
		if(initFunctionIdPtr)
		{
			execRoutineCall(initFunctionIdPtr, false);
			//-------------------------------------------------------------------------
			// Since we're calling the function directly, we need to compensate for the
			// codeSegmentPtr being incremented by 1 in the normal execRoutineCall...
			codeSegmentPtr--;
		}
	}
	if(routineIdPtr->defn.info.routine.flags & ROUTINE_FLAG_FSM)
	{
		NewStateSet = true;
		static char stateList[60][256];
		strcpy(SetStateDebugStr, "--");
		while(NewStateSet)
		{
			NumStateTransitions++;
			sprintf(stateList[NumStateTransitions], "%s (%s)", CurModule->getState()->name, SetStateDebugStr);
			if(NumStateTransitions == 50)
			{
				UserFile* userFile = UserFile::getNewFile();
				char errStr[512];
				if(userFile)
				{
					int32_t err = userFile->open("endless.log");
					if(!err)
					{
						//char s[1024];
						//sprintf(s, "Current Date: %s\n", GetTime());
						//userFile->write(s);
						userFile->write(ModuleRegistry[CurModule->getHandle()].fileName);
						for(size_t i = 1; i < 51; i++)
							userFile->write(stateList[i]);
						userFile->write(" ");
						if(ABLEndlessStateCallback)
							(*ABLEndlessStateCallback)(userFile);
						userFile->close();
					}
				}
				sprintf(errStr, " ABL endless state loop in %s [%s:%s] ", ModuleRegistry[CurModule->getHandle()].fileName, CurModule->getState()->name, CurModule->getPrevState()->name);
#if 0
				ABL_Fatal(NumStateTransitions, errStr);
#else
				NewStateSet = false;
#endif
			}
			else
			{
				NewStateSet = false;
				SymTableNodePtr curState = CurModule->getState();
				if(!curState)
					ABL_Fatal(0, " ABL.execute: nullptr state in FSM ");
				execRoutineCall(curState, false);
				codeSegmentPtr--;
			}
			//---------------------------------------------
			// In case we exited with a return statement...
			ExitWithReturn = false;
			ExitFromTacOrder = false;
		}
	}
	else
	{
		getCodeToken();
		execStatement();
		//---------------------------------------------
		// In case we exited with a return statement...
		ExitWithReturn = false;
		ExitFromTacOrder = false;
	}
	routineExit(routineIdPtr);
	CurRoutineIdPtr = thisRoutineIdPtr;
}
Example #6
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();
}
Example #7
0
void execForStatement(void)
{
	getCodeToken();
	//---------------------------------------
	// Grab address of the end of the loop...
	PSTR loopEndLocation = getCodeAddressMarker();
	//--------------------------------------------------------
	// Get the address of the control variable's stack item...
	getCodeToken();
	SymTableNodePtr controlIdPtr = getCodeSymTableNodePtr();
	TypePtr controlTypePtr = execVariable(controlIdPtr, USE_TARGET);
	StackItemPtr targetPtr = (StackItemPtr)tos->address;
	//------------------------------------
	// Control variable address...
	pop();
	//-------------------------------
	// Eval the initial expression...
	getCodeToken();
	execExpression();
	int32_t initialValue;
	if(controlTypePtr == IntegerTypePtr)
		initialValue = tos->integer;
	else
		initialValue = tos->byte;
	//---------------------
	// The initial value...
	pop();
	int32_t deltaValue;
	if(codeToken == TKN_TO)
		deltaValue = 1;
	else
		deltaValue = -1;
	//----------------------------------
	// Now, eval the final expression...
	getCodeToken();
	execExpression();
	int32_t finalValue;
	if(controlTypePtr == IntegerTypePtr)
		finalValue = tos->integer;
	else
		finalValue = tos->byte;
	//-------------------
	// The final value...
	pop();
	//----------------------------
	// Address of start of loop...
	PSTR loopStartLocation = codeSegmentPtr;
	int32_t controlValue = initialValue;
	//-----------------------------
	// Now, execute the FOR loop...
	int32_t iterations = 0;
	if(deltaValue == 1)
		while(controlValue <= finalValue)
		{
			if(controlTypePtr == IntegerTypePtr)
				targetPtr->integer = controlValue;
			else
				targetPtr->byte = (uint8_t)controlValue;
			getCodeToken();
			if(codeToken != TKN_END_FOR)
				do
				{
					execStatement();
					if(ExitWithReturn)
						return;
				}
				while(codeToken != TKN_END_FOR);
			//---------------------------
			// Check for infinite loop...
			if(++iterations == MaxLoopIterations)
				runtimeError(ABL_ERR_RUNTIME_INFINITE_LOOP);
			controlValue++;
			codeSegmentPtr = loopStartLocation;
		}
	else
		while(controlValue >= finalValue)
		{
			if(controlTypePtr == IntegerTypePtr)
				targetPtr->integer = controlValue;
			else
				targetPtr->byte = (uint8_t)controlValue;
			getCodeToken();
			if(codeToken != TKN_END_FOR)
				do
				{
					execStatement();
					if(ExitWithReturn)
						return;
				}
				while(codeToken != TKN_END_FOR);
			//---------------------------
			// Check for infinite loop...
			if(++iterations == MaxLoopIterations)
				runtimeError(ABL_ERR_RUNTIME_INFINITE_LOOP);
			controlValue--;
			codeSegmentPtr = loopStartLocation;
		}
	codeSegmentPtr = loopEndLocation;
	getCodeToken();
}