Exemple #1
0
float* ABLi_peekRealPtr (void) {

	getCodeToken();
	SymTableNodePtr idPtr = getCodeSymTableNodePtr();
	execVariable(idPtr, USE_REFPARAM);
	return((float*)(&((StackItemPtr)tos->address)->real));
}
Exemple #2
0
long* ABLi_peekIntegerPtr (void) {

	getCodeToken();
	SymTableNodePtr idPtr = getCodeSymTableNodePtr();
	execVariable(idPtr, USE_REFPARAM);
	return((long*)(&((StackItemPtr)tos->address)->integer));
}
void execAssignmentStatement(SymTableNodePtr idPtr)
{
	StackItemPtr targetPtr;
	TypePtr targetTypePtr;
	TypePtr expressionTypePtr;
	//--------------------------
	// Assignment to variable...
	targetTypePtr = execVariable(idPtr, USE_TARGET);
	targetPtr = (StackItemPtr)tos->address;
	//------------------------------
	// Pop off the target address...
	pop();
	//------------------------
	// Pop the size, if nec...
	//if (targetTypePtr->form == FRM_ARRAY)
	//	pop();
	//---------------------------------------------------------------
	// Routine execExpression() leaves the expression value on top of
	// stack...
	getCodeToken();
	expressionTypePtr = execExpression();
	//--------------------------
	// Now, do the assignment...
	if((targetTypePtr == RealTypePtr) && (expressionTypePtr == IntegerTypePtr))
	{
		//-------------------------
		// integer assigned to real
		targetPtr->real = (float)(tos->integer);
	}
	else if(targetTypePtr->form == FRM_ARRAY)
	{
		//-------------------------
		// Copy the array/record...
		PSTR dest = (PSTR)targetPtr;
		PSTR src = tos->address;
		int32_t size = targetTypePtr->size;
		memcpy(dest, src, size);
	}
	else if((targetTypePtr == IntegerTypePtr) || (targetTypePtr->form == FRM_ENUM))
	{
		//------------------------------------------------------
		// Range check assignment to integer or enum subrange...
		targetPtr->integer = tos->integer;
	}
	else if(targetTypePtr == CharTypePtr)
		targetPtr->byte = tos->byte;
	else
	{
		//-----------------------
		// Assign real to real...
		targetPtr->real = tos->real;
	}
	//-----------------------------
	// Grab the expression value...
	pop();
	if(debugger)
		debugger->traceDataStore(idPtr, idPtr->typePtr, targetPtr, targetTypePtr);
}
void execActualParams(SymTableNodePtr routineIdPtr)
{
	//--------------------------
	// Execute the parameters...
	for(SymTableNodePtr formalIdPtr = (SymTableNodePtr)(routineIdPtr->defn.info.routine.params);
			formalIdPtr != nullptr;
			formalIdPtr = formalIdPtr->next)
	{
		TypePtr formalTypePtr = (TypePtr)(formalIdPtr->typePtr);
		getCodeToken();
		if(formalIdPtr->defn.key == DFN_VALPARAM)
		{
			//-------------------
			// pass by value parameter...
			TypePtr actualTypePtr = execExpression();
			if((formalTypePtr == RealTypePtr) && (actualTypePtr == IntegerTypePtr))
			{
				//---------------------------------------------
				// Real formal parameter, but integer actual...
				tos->real = (float)(tos->integer);
			}
			//----------------------------------------------------------
			// Formal parameter is an array or record, so make a copy...
			if((formalTypePtr->form == FRM_ARRAY)/* || (formalTypePtr->form == FRM_RECORD)*/)
			{
				//------------------------------------------------------------------------------
				// The following is a little inefficient, but is kept this way to keep it clear.
				// Once it's verified to work, optimize...
				int32_t size = formalTypePtr->size;
				PSTR src = tos->address;
				PSTR dest = (PSTR)ABLStackMallocCallback((size_t)size);
				if(!dest)
				{
					char err[255];
					sprintf(err, " ABL: Unable to AblStackHeap->malloc actual array param in module %s)", CurModule->getName());
					ABL_Fatal(0, err);
				}
				PSTR savePtr = dest;
				memcpy(dest, src, size);
				tos->address = savePtr;
			}
		}
		else
		{
			//-------------------------------
			// pass by reference parameter...
			SymTableNodePtr idPtr = getCodeSymTableNodePtr();
			execVariable(idPtr, USE_REFPARAM);
		}
	}
}
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();
}
TypePtr execFactor(void)
{
	TypePtr resultTypePtr = nullptr;
	switch (codeToken)
	{
	case TKN_IDENTIFIER:
	{
		SymTableNodePtr idPtr = getCodeSymTableNodePtr();
		if (idPtr->defn.key == DFN_FUNCTION)
		{
			SymTableNodePtr thisRoutineIdPtr = CurRoutineIdPtr;
			resultTypePtr					 = execRoutineCall(idPtr, false);
			CurRoutineIdPtr					 = thisRoutineIdPtr;
		}
		else if (idPtr->defn.key == DFN_CONST)
			resultTypePtr = execConstant(idPtr);
		else
			resultTypePtr = execVariable(idPtr, USE_EXPR);
	}
	break;
	case TKN_NUMBER:
	{
		SymTableNodePtr numberPtr = getCodeSymTableNodePtr();
		if (numberPtr->typePtr == IntegerTypePtr)
		{
			pushInteger(numberPtr->defn.info.constant.value.integer);
			resultTypePtr = IntegerTypePtr;
		}
		else
		{
			pushReal(numberPtr->defn.info.constant.value.real);
			resultTypePtr = RealTypePtr;
		}
		getCodeToken();
	}
	break;
	case TKN_STRING:
	{
		SymTableNodePtr nodePtr = getCodeSymTableNodePtr();
		int32_t length			= strlen(nodePtr->name);
		if (length > 1)
		{
			//-----------------------------------------------------------------------
			// Remember, the double quotes are on the back and front of the
			// string...
			pushAddress(nodePtr->info);
			resultTypePtr = nodePtr->typePtr;
		}
		else
		{
			//----------------------------------------------
			// Just push the one character in this string...
			pushByte(nodePtr->name[0]);
			resultTypePtr = CharTypePtr;
		}
		getCodeToken();
	}
	break;
	case TKN_NOT:
		getCodeToken();
		resultTypePtr = execFactor();
		//--------------------------------------
		// Following flips 1 to 0, and 0 to 1...
		tos->integer = 1 - tos->integer;
		break;
	case TKN_LPAREN:
		getCodeToken();
		resultTypePtr = execExpression();
		getCodeToken();
		break;
	}
	return (resultTypePtr);
}