Esempio n. 1
0
void execStdGetModule (void) {

	//----------------------------------------------------------
	// Return the handle of the current module being executed...
	char* curBuffer = ABLi_popCharPtr();
	char* fsmBuffer = ABLi_popCharPtr();
	strcpy(curBuffer, CurModule->getFileName());
	strcpy(fsmBuffer, CurFSM ? CurFSM->getFileName() : "none");
	ABLi_pushInteger(CurModuleHandle);
}
Esempio n. 2
0
void execStdPrint (void) {

	//---------------------------
	// Grab the opening LPAREN...
	getCodeToken();

	//----------------------------
	// Get parameter expression...
	getCodeToken();
	TypePtr paramTypePtr = execExpression();

	char buffer[20];
	char* s = buffer;
	if (paramTypePtr == IntegerTypePtr)
		sprintf(buffer, "%d", tos->integer);
	else if (paramTypePtr == BooleanTypePtr)
		sprintf(buffer, "%s", tos->integer ? "true" : "false");
	else if (paramTypePtr == CharTypePtr)
		sprintf(buffer, "%c", tos->byte);
	else if (paramTypePtr == RealTypePtr)
		sprintf(buffer, "%.4f", tos->real);
	else if ((paramTypePtr->form == FRM_ARRAY) && (paramTypePtr->info.array.elementTypePtr == CharTypePtr))
		s = (char*)tos->address;
	pop();

	if (debugger) {
		char message[512];
		sprintf(message, "PRINT:  \"%s\"", s);
		debugger->print(message);
		sprintf(message, "   MODULE %s", CurModule->getName());
		debugger->print(message);
		sprintf(message, "   FILE %s", CurModule->getSourceFile(FileNumber));
		debugger->print(message);
		sprintf(message, "   LINE %d", execLineNumber);
		debugger->print(message);
		}
/*	else if (TACMAP) {
		aChatWindow* chatWin = TACMAP->getChatWindow();
		if (chatWin)
			chatWin->processChatString(0, s, -1);
		else {
#ifdef _DEBUG
			OutputDebugString(s);
#endif
		}
		}
*/	else {
#ifdef _DEBUG
		ABLDebugPrintCallback(s);
#endif
	}
	//-----------------------
	// Grab closing RPAREN...
	getCodeToken();
}
Esempio n. 3
0
void execStdSetState (void) {

	unsigned long stateHandle = ABLi_popInteger();

	if (stateHandle > 0) {
		SymTableNodePtr stateFunction = ModuleRegistry[CurFSM->getHandle()].stateHandles[stateHandle].state;
		CurFSM->setPrevState(CurFSM->getState());
		CurFSM->setState(stateFunction);
		sprintf(SetStateDebugStr, "%s:%s, line %d", CurFSM->getFileName(), stateFunction->name, execLineNumber);
		NewStateSet = true;
	}
}
Esempio n. 4
0
void execStdGetStateHandle (void) {

	char* name = ABLi_popCharPtr();

	long stateHandle = CurFSM->findStateHandle(_strlwr(name));
	ABLi_pushInteger(stateHandle);
}
Esempio n. 5
0
void execStdResetOrders (void) {

	long scope = ABLi_popInteger();

	if (scope == 0)
		CurModule->resetOrderCallFlags();
	else if (scope == 1) {
		long startIndex = CurRoutineIdPtr->defn.info.routine.orderCallIndex;
		long endIndex = startIndex + CurRoutineIdPtr->defn.info.routine.numOrderCalls;
		for (long i = startIndex; i < endIndex; i++) {
			unsigned char orderDWord = (unsigned char)(i / 32);
			unsigned char orderBitMask = (unsigned char)(i % 32);
			CurModule->clearOrderCallFlag(orderDWord, orderBitMask);
		}
	}
}
Esempio n. 6
0
void execTransBackStatement(void)
{
	SymTableNodePtr prevState = CurModule->getPrevState();
	if(!prevState)
		runtimeError(ABL_ERR_RUNTIME_NULL_PREVSTATE);
	transState(prevState);
	getCodeToken();
}
Esempio n. 7
0
void execStdAssert (void) {

	//----------------------------------------------------------------------
	//
	//	ASSERT function:
	//
	//		If the debugger is active, this immediately jumps into debug mode
	//		if expression is FALSE. Otherwise, the assert statement is ignored
	//		unless the #debug directive has been issued in the module. If
	//		so, a fatal occurs and exits the game (displaying the
	//		string passed in).
	//
	//		PARAMS:	boolean							expression
	//
	//				integer							assert code to display
	//
	//				char[]							message
	//
	//		RETURN: none
	//
	//----------------------------------------------------------------------

	long expression = ABLi_popInteger();
	long code = ABLi_popInteger();
	char* s = ABLi_popCharPtr();

	if (!expression) {
		char message[512];
		if (debugger) {
			sprintf(message, "ASSERT:  [%d] \"%s\"", code, s);
			debugger->print(message);
			sprintf(message, "   MODULE (%d) %s", CurModule->getId(), CurModule->getName());
			debugger->print(message);
			sprintf(message, "   FILE %s", CurModule->getSourceFile(FileNumber));
			debugger->print(message);
			sprintf(message, "   LINE %d", execLineNumber);
			debugger->print(message);
			debugger->debugMode();
			}
		else {
			sprintf(message, "ABL ASSERT: [%d] %s", code, s);
			ABL_Fatal(0, message);
		}
	}
}
Esempio n. 8
0
TypePtr execStandardRoutineCall (SymTableNodePtr routineIdPtr, bool skipOrder) {

	long key = routineIdPtr->defn.info.routine.key;
	switch (key) {
		case RTN_RETURN:
			execStdReturn();
			return(NULL);
		case RTN_PRINT:
			execStdPrint();
			return(NULL);
		case RTN_CONCAT:
			return(execStdConcat());
		default: {
			if (key >= NumStandardFunctions) {
				char err[255];
				sprintf(err, " ABL: Undefined ABL RoutineKey in %s:%d", CurModule->getName(), execLineNumber);
				ABL_Fatal(0, err);
			}
			if (FunctionInfoTable[key].numParams > 0)
				getCodeToken();
			SkipOrder = skipOrder;
			if (FunctionCallbackTable[key])
				(*FunctionCallbackTable[key])();
			else
			{
				char err[255];
				sprintf(err, " ABL: Undefined ABL RoutineKey %d in %s:%d", key, CurModule->getName(), execLineNumber);
				ABL_Fatal(key,err);
			}

			getCodeToken();
			switch (FunctionInfoTable[key].returnType) {
				case RETURN_TYPE_NONE:
					return(NULL);
				case RETURN_TYPE_INTEGER:
					return(IntegerTypePtr);
				case RETURN_TYPE_REAL:
					return(RealTypePtr);
				case RETURN_TYPE_BOOLEAN:
					return(BooleanTypePtr);
			}
		}
	}
	return(NULL);
}
Esempio n. 9
0
void execStdGetFunctionHandle (void) {

	char* name = ABLi_popCharPtr();

	SymTableNodePtr function = CurModule->findFunction(name, false);
	if (function)
		ABLi_pushInteger((unsigned long)function);
	else
		ABLi_pushInteger(0);
}
Esempio n. 10
0
void runtimeError (long errCode) {

	char message[512];

	if (debugger) {
		sprintf(message, "RUNTIME ERROR:  [%d] %s", errCode, runtimeErrorMessages[errCode]);
		debugger->print(message);
		sprintf(message, "MODULE %s", CurModule->getName());
		debugger->print(message);
		if (FileNumber > -1)
			sprintf(message, "FILE %s", CurModule->getSourceFile(FileNumber));
		else
			sprintf(message, "FILE %s: unavailable");
		debugger->print(message);
		sprintf(message, "LINE %d", execLineNumber);
		debugger->print(message);
		debugger->debugMode();
	}

	sprintf(message, "ABL RUNTIME ERROR %s [line %d] - (type %d) %s\n", (FileNumber > -1) ? CurModule->getSourceFile(FileNumber) : "unavailable", execLineNumber, errCode, runtimeErrorMessages[errCode]);
	ABL_Fatal(-ABL_ERR_RUNTIME_ABORT, message);
}
Esempio n. 11
0
void execStdFatal (void) {

	//----------------------------------------------------------------------
	//
	//	FATAL function:
	//
	//		If the debugger is active, this immediately jumps into debug mode.
	//		Otherwise, it causes a fatal and exits the game (displaying the
	//		string passed in).
	//
	//		PARAMS:	integer							fatal code to display
	//
	//				char[]							message
	//
	//		RETURN: none
	//
	//----------------------------------------------------------------------

	long code = ABLi_popInteger();
	char* s = ABLi_popCharPtr();

	char message[512];
	if (debugger) {
		sprintf(message, "FATAL:  [%d] \"%s\"", code, s);
		debugger->print(message);
		sprintf(message, "   MODULE (%d) %s", CurModule->getId(), CurModule->getName());
		debugger->print(message);
		sprintf(message, "   FILE %s", CurModule->getSourceFile(FileNumber));
		debugger->print(message);
		sprintf(message, "   LINE %d", execLineNumber);
		debugger->print(message);
		debugger->debugMode();
		}
	else {
		sprintf(message, "ABL FATAL: [%d] %s", code, s);
		ABL_Fatal(0, s);
	}
}
Esempio n. 12
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;
}
Esempio n. 13
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();
}
Esempio n. 14
0
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);
		}
	}
}
Esempio n. 15
0
TypePtr execDeclaredRoutineCall(SymTableNodePtr routineIdPtr, bool skipOrder)
{
	if(skipOrder)
	{
		StackItemPtr curStackFrameBase = tos;
		//----------------------------------------
		// Push parameter values onto the stack...
		getCodeToken();
		if(codeToken == TKN_LPAREN)
		{
			execActualParams(routineIdPtr);
			getCodeToken();
		}
		getCodeToken();
		tos = curStackFrameBase;
		pushInteger(1);
		return((TypePtr)(routineIdPtr->typePtr));
	}
	int32_t oldLevel = level;						// level of caller
	int32_t newLevel = routineIdPtr->level + 1;	// level of callee
	CallStackLevel++;
	//-------------------------------------------
	// First, set up the stack frame of callee...
	StackItemPtr newStackFrameBasePtr = tos + 1;
	bool isLibraryCall = (routineIdPtr->library && (routineIdPtr->library != CurRoutineIdPtr->library));
	if(isLibraryCall)
		pushStackFrameHeader(-1, -1);
	else
		pushStackFrameHeader(oldLevel, newLevel);
	//----------------------------------------
	// Push parameter values onto the stack...
	getCodeToken();
	if(codeToken == TKN_LPAREN)
	{
		execActualParams(routineIdPtr);
		getCodeToken();
	}
	//-------------------------------------------------
	// Set the return address in the new stack frame...
	level = newLevel;
	stackFrameBasePtr = newStackFrameBasePtr;
	StackFrameHeaderPtr headerPtr = (StackFrameHeaderPtr)stackFrameBasePtr;
	headerPtr->returnAddress.address = codeSegmentPtr - 1;
	//---------------------------------------------------------
	// If we're calling a library function, we need to set some
	// module-specific info...
	ABLModulePtr PrevModule = nullptr;
	if(isLibraryCall)
	{
		PrevModule = CurModule;
		CurModule = routineIdPtr->library;
		CurModuleHandle = CurModule->getHandle();
		if(debugger)
			debugger->setModule(CurModule);
		StaticDataPtr = CurModule->getStaticData();
		CallModuleInit = !CurModule->getInitCalled();
		CurModule->setInitCalled(true);
		//	routineEntry(ModuleRegistry[CurModule->getHandle()].moduleIdPtr);
	}
	if(ProfileLog)
	{
		int32_t functionStartTime = ABLGetTimeCallback();
		execute(routineIdPtr);
		int32_t functionExecTime = ABLGetTimeCallback() - functionStartTime;
		if(functionExecTime > ProfileLogFunctionTimeLimit)
		{
			char s[512];
			sprintf_s(s, _countof(s), "[%08d] ", NumExecutions);
			for(size_t i = 0; i < CallStackLevel; i++)
				strcat(s, " ");
			char s1[512];
			sprintf_s(s1, _countof(s1), "%s (%d)\n", routineIdPtr->name, functionExecTime);
			strcat(s, s1);
			ABL_AddToProfileLog(s);
		}
	}
	else
		execute(routineIdPtr);
	//----------------------------------------------------------------
	// If we're calling a library function, reset some module-specific
	// info...
	if(isLibraryCall)
	{
		//	routineExit(ModuleRegistry[CurModule->getHandle()].moduleIdPtr);
		CurModule = PrevModule;
		CurModuleHandle = CurModule->getHandle();
		if(debugger)
			debugger->setModule(CurModule);
		StaticDataPtr = CurModule->getStaticData();
	}
	//-------------------------------------------------------
	// Return from the callee, and grab the first token after
	// the return...
	level = oldLevel;
	getCodeToken();
	CallStackLevel--;
	return((TypePtr)(routineIdPtr->typePtr));
}
Esempio n. 16
0
int32_t ABLModule::init(int32_t moduleHandle)
{
    if(moduleHandle == -1)
    {
        //----------
        // Clean up!
        return(-1);
    }
    id = NumModules++;
    handle = moduleHandle;
    staticData = nullptr;
    int32_t numStatics = ModuleRegistry[handle].numStaticVars;
    if(numStatics)
    {
        staticData = (StackItemPtr)ABLStackMallocCallback(sizeof(StackItem) * numStatics);
        if(!staticData)
        {
            char err[255];
            sprintf(err, "ABL: Unable to AblStackHeap->malloc staticData [Module %d]", id);
            ABL_Fatal(0, err);
        }
        int32_t* sizeList = ModuleRegistry[handle].sizeStaticVars;
        for(size_t i = 0; i < numStatics; i++)
            if(sizeList[i] > 0)
            {
                staticData[i].address = (PSTR)ABLStackMallocCallback(sizeList[i]);
                if(!staticData)
                {
                    char err[255];
                    sprintf(err, "ABL: Unable to AblStackHeap->malloc staticData address [Module %d]", id);
                    ABL_Fatal(0, err);
                }
            }
            else
                staticData[i].integer = 0;
    }
    if(ModuleRegistry[handle].numOrderCalls)
    {
        int32_t numLongs = 1 + ModuleRegistry[handle].numOrderCalls / 32;
        orderCallFlags = (uint32_t*)ABLStackMallocCallback(sizeof(uint32_t) * numLongs);
        if(!orderCallFlags)
        {
            char err[255];
            sprintf(err, "ABL: Unable to AblStackHeap->malloc orderCallFlags [Module %d]", id);
            ABL_Fatal(0, err);
        }
        for(size_t i = 0; i < numLongs; i++)
            orderCallFlags[i] = 0;
    }
    ModuleRegistry[handle].numInstances++;
    initCalled = false;
    //------------------------------------------------------
    // This Active Module is now on the instance registry...
    ModuleInstanceRegistry[NumModuleInstances++] = this;
    if(debugger)
    {
        watchManager = new WatchManager;
        if(!watchManager)
            ABL_Fatal(0, " Unable to AblStackHeap->malloc WatchManager ");
        int32_t result = watchManager->init(MaxWatchesPerModule);
        if(result != ABL_NO_ERR)
            ABL_Fatal(0, " Unable to AblStackHeap->malloc WatchManager ");
        breakPointManager = new BreakPointManager;
        if(!breakPointManager)
            ABL_Fatal(0, " Unable to AblStackHeap->malloc BreakPointManager ");
        result = breakPointManager->init(MaxBreakPointsPerModule);
        if(result != ABL_NO_ERR)
            ABL_Fatal(0, " Unable to AblStackHeap->malloc BreakPointManager ");
    }
    if(ModuleRegistry[handle].moduleIdPtr->defn.info.routine.flags & ROUTINE_FLAG_FSM)
    {
        //--------------------------------
        // Always starts in START state...
        SymTableNodePtr startState = searchSymTable("start", ModuleRegistry[handle].moduleIdPtr->defn.info.routine.localSymTable);
        if(!startState)
        {
            char err[255];
            sprintf(err, "ABL: FSM has no Start state [%s]", CurModule->getName());
            ABL_Fatal(0, err);
        }
        prevState = nullptr;
        state = startState;
    }
    //--------------------
    // Can this ever fail?
    return(ABL_NO_ERR);
}
Esempio n. 17
0
void ABLi_loadEnvironment(ABLFile* ablFile, bool malloc)
{
    int32_t numLibs = ablFile->readLong();
    int32_t numModsRegistered = ablFile->readLong();
    int32_t numMods = ablFile->readLong();
    int32_t i;
    for(i = 0; i < numLibs; i++)
    {
        uint8_t fileName[1024];
        int32_t result = ablFile->readString(fileName);
        if(!result)
        {
            char err[255];
            sprintf(err, "ABLi_loadEnvironment: Unable to read filename [Module %d]", i);
            ABL_Fatal(0, err);
        }
        if(malloc)
        {
            int32_t numErrors, numLinesProcessed;
            ABLModulePtr library = ABLi_loadLibrary((PSTR)fileName, &numErrors, &numLinesProcessed, nullptr, false, false);
            if(!library)
            {
                char err[255];
                sprintf(err, "ABLi_loadEnvironment: Unable to load library [Module %d]", i);
                ABL_Fatal(0, err);
            }
        }
    }
    for(i = 0; i < (numModsRegistered - numLibs); i++)
    {
        uint8_t fileName[1024];
        int32_t result = ablFile->readString(fileName);
        if(!result)
        {
            char err[255];
            sprintf(err, "ABLi_loadEnvironment: Unable to read filename [Module %d]", i);
            ABL_Fatal(0, err);
        }
        int32_t numErrors, numLinesProcessed;
        if(malloc)
        {
            int32_t handle = ABLi_preProcess((PSTR)fileName, &numErrors, &numLinesProcessed);
            if(handle < 0)
            {
                char err[255];
                sprintf(err, "ABLi_loadEnvironment: Unable to preprocess [Module %d]", i);
                ABL_Fatal(0, err);
            }
        }
    }
    //int32_t mark = ablFile->readLong();
    for(i = 0; i < eternalOffset; i++)
    {
        StackItemPtr dataPtr = (StackItemPtr)stack + i;
        if(EternalVariablesSizes[i] > 0)
            ablFile->read((puint8_t)dataPtr->address, EternalVariablesSizes[i]);
        else
            ablFile->read((puint8_t)dataPtr, sizeof(StackItem));
    }
    for(i = 0; i < numLibs; i++)
    {
        ABLModulePtr library = LibraryInstanceRegistry[i];
        library->read(ablFile);
    }
    for(i = 0; i < (numMods - numLibs); i++)
    {
        ABLModulePtr module = nullptr;
        if(malloc)
            module = new ABLModule;
        else
            module = ModuleInstanceRegistry[numLibs + i];
        module->read(ablFile);
    }
}
Esempio n. 18
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);
}
Esempio n. 19
0
void execStdGetCurrentStateHandle (void) {

	long stateHandle = CurFSM->getStateHandle();
	ABLi_pushInteger(stateHandle);
}