예제 #1
0
TypePtr execConstant(SymTableNodePtr idPtr)
{
	TypePtr typePtr = idPtr->typePtr;
	if ((typePtr == IntegerTypePtr) || (typePtr->form == FRM_ENUM))
		pushInteger(idPtr->defn.info.constant.value.integer);
	else if (typePtr == RealTypePtr)
		pushReal(idPtr->defn.info.constant.value.real);
	else if (typePtr == CharTypePtr)
		pushInteger(idPtr->defn.info.constant.value.character);
	else if (typePtr->form == FRM_ARRAY)
		pushAddress(idPtr->defn.info.constant.value.stringPtr);
	if (debugger)
		debugger->traceDataFetch(idPtr, typePtr, tos);
	getCodeToken();
	return (typePtr);
}
예제 #2
0
TypePtr execVariable(SymTableNodePtr idPtr, UseType use)
{
	TypePtr typePtr = (TypePtr)(idPtr->typePtr);
	// First, point to the variable's stack item. If the variable's scope
	// level is less than the current scope level, follow the static links
	// to the proper stack frame base...
	StackItemPtr dataPtr = nullptr;
	StackItem tempStackItem;
	switch (idPtr->defn.info.data.varType)
	{
	case VAR_TYPE_NORMAL:
	{
		StackFrameHeaderPtr headerPtr = (StackFrameHeaderPtr)stackFrameBasePtr;
		int32_t delta				  = level - idPtr->level;
		while (delta-- > 0)
			headerPtr = (StackFrameHeaderPtr)headerPtr->staticLink.address;
		dataPtr = (StackItemPtr)headerPtr + idPtr->defn.info.data.offset;
	}
	break;
	case VAR_TYPE_ETERNAL:
		dataPtr = (StackItemPtr)stack + idPtr->defn.info.data.offset;
		break;
	case VAR_TYPE_STATIC:
		//---------------------------------------------------------
		// If we're referencing a library's static variable, we may
		// need to shift to its static data space temporarily...
		if (idPtr->library && (idPtr->library != CurModule))
			StaticDataPtr = idPtr->library->getStaticData();
		dataPtr = (StackItemPtr)StaticDataPtr + idPtr->defn.info.data.offset;
		if (idPtr->library && (idPtr->library != CurModule))
			StaticDataPtr = CurModule->getStaticData();
		break;
	case VAR_TYPE_REGISTERED:
		tempStackItem.address = (PSTR)idPtr->defn.info.data.registeredData;
		dataPtr				  = &tempStackItem;
		break;
	}
	//---------------------------------------------------------------
	// If it's a scalar or enumeration reference parameter, that item
	// points to the actual item...
	if (idPtr->defn.key == DFN_REFPARAM)
		if (typePtr->form != FRM_ARRAY) /* && (typePtr->form != FRM_RECORD)*/
			dataPtr = (StackItemPtr)dataPtr->address;
	ABL_Assert(dataPtr != nullptr, 0, " ABL.execVariable(): dataPtr is nullptr ");
	//-----------------------------------------------------
	// Now, push the address of the variable's data area...
	if ((typePtr->form == FRM_ARRAY) /*|| (typePtr->form == FRM_RECORD)*/)
	{
		// pushInteger(typePtr->size);
		pushAddress((Address)dataPtr->address);
	}
	else if (idPtr->defn.info.data.varType == VAR_TYPE_REGISTERED)
		pushAddress((Address)dataPtr->address);
	else
		pushAddress((Address)dataPtr);
	//-----------------------------------------------------------------------------------
	// If there is a subscript (or field identifier, if records are being used
	// in ABL) then modify the address to point to the proper element of the
	// array (or record)...
	getCodeToken();
	while ((codeToken == TKN_LBRACKET) /*|| (codeTOken == TKN_PERIOD)*/)
	{
		// if (codeToken == TKN_LBRACKET)
		typePtr = execSubscripts(typePtr);
		// else if (codeToken == TKN_PERIOD)
		//	typePtr = execField(typePtr);
	}
	//------------------------------------------------------------
	// Leave the modified address on the top of the stack if:
	//		a) it's an assignment target;
	//		b) it reresents a parameter passed by reference;
	//		c) it's the address of an array or record;
	// Otherwise, replace the address with the value it points to.
	if ((use != USE_TARGET) && (use != USE_REFPARAM) && (typePtr->form != FRM_ARRAY))
	{
		if ((typePtr == IntegerTypePtr) || (typePtr->form == FRM_ENUM))
		{
			tos->integer = *((int32_t*)tos->address);
		}
		else if (typePtr == CharTypePtr)
			tos->byte = *((PSTR)tos->address);
		else
			tos->real = *((float*)tos->address);
	}
	if (debugger)
	{
		if ((use != USE_TARGET) && (use != USE_REFPARAM))
		{
			if (typePtr->form == FRM_ARRAY)
				debugger->traceDataFetch(idPtr, typePtr, (StackItemPtr)tos->address);
			else
				debugger->traceDataFetch(idPtr, typePtr, tos);
		}
	}
	return (typePtr);
}