예제 #1
0
SymTableNodePtr searchLibrarySymTable (char* name, SymTableNodePtr nodePtr) {

	//-------------------------------------------------------------
	// Since all libraries are at the symbol display 0-level, we'll
	// check the local symbol table of all libraries. WARNING: This
	// will find the FIRST instance of a symbol with that name,
	// so don't load two libraries with a similarly named function
	// or variable, otherwise you may not get the one you want
	// unless you explicitly reference the library you want
	// (e.g. testLib.fudge, rather than just fudge). This is WAY
	// inefficient compared to simply knowing the library we want,
	// so any ABL programmer that causes this function to be called
	// should be shot --gd 9/29/97

	if (nodePtr) {
		long compareResult = strcmp(name, nodePtr->name);
		if (compareResult == 0)
			return(nodePtr);
		else {
			if (nodePtr->library && (nodePtr->defn.key == DFN_MODULE)) {
				SymTableNodePtr memberNodePtr = searchSymTable(name, nodePtr->defn.info.routine.localSymTable);
				if (memberNodePtr)
					return(memberNodePtr);
			}
			SymTableNodePtr nodeFoundPtr = searchLibrarySymTable(name, nodePtr->left);
			if (nodeFoundPtr)
				return(nodeFoundPtr);
			nodeFoundPtr = searchLibrarySymTable(name, nodePtr->right);
			if (nodeFoundPtr)
				return(nodeFoundPtr);
		}
	}
	return(NULL);
}
예제 #2
0
void searchAndEnterThisTable (SymTableNodePtr& IdPtr, SymTableNodePtr thisTable) {

	if ((IdPtr = searchSymTable(wordString, thisTable)) == NULL)
		IdPtr = enterSymTable(wordString, &thisTable);
	else
		syntaxError(ABL_ERR_SYNTAX_REDEFINED_IDENTIFIER);
}
예제 #3
0
void searchAndEnterLocalSymTable (SymTableNodePtr& IdPtr) {

	if ((IdPtr = searchSymTable(wordString, SymTableDisplay[level])) == NULL)
		IdPtr = enterSymTable(wordString, &SymTableDisplay[level]);
	else
		syntaxError(ABL_ERR_SYNTAX_REDEFINED_IDENTIFIER);
}
예제 #4
0
SymTableNodePtr searchSymTableDisplay (char* name) {

	//---------------------------------------------------------------------
	// First check if this is an explicit library reference. If so, we need
	// to determine which library and which identifier in that library...
	char* separator = strchr(name, '.');
	SymTableNodePtr nodePtr = NULL;

	if (separator) {
		*separator = NULL;
		SymTableNodePtr libraryNodePtr = searchSymTable(name, SymTableDisplay[0]);
		if (!libraryNodePtr)
			return(NULL);
		//-------------------------------------
		// Now, search for the member symbol...
		char* memberName = separator + 1;
		SymTableNodePtr memberNodePtr = searchSymTable(memberName, libraryNodePtr->defn.info.routine.localSymTable);
		if (memberNodePtr)
			recordLibraryUsed(memberNodePtr);
		return(memberNodePtr);
		}
	else {	
		for (long i = level; i >= 0; i--) {
			SymTableNodePtr nodePtr = searchSymTable(name, SymTableDisplay[i]);
			if (nodePtr)
				return(nodePtr);
		}
		//------------------------------------------------------------
		// We haven't found it, so maybe it's from a library but just
		// is not explicitly called with the library name. Since all
		// libraries are at the symbol table's 0-level, we'll check
		// the local symbol table of all libraries. WARNING: This
		// will find the FIRST instance of a symbol with that name,
		// so don't load two libraries with a similarly named function
		// or variable, otherwise you may not get the one you want
		// unless you explicitly reference the library you want
		// (e.g. testLib.fudge, rather than just fudge)...
		nodePtr = searchLibrarySymTableDisplay(name);
		if (nodePtr)
			recordLibraryUsed(nodePtr);
	}

	return(nodePtr);
}
예제 #5
0
SymTableNodePtr ABLModule::findSymbol(PSTR symbolName, SymTableNodePtr curFunction, bool searchLibraries)
{
    if(curFunction)
    {
        SymTableNodePtr symbol = searchSymTable(strlwr(symbolName), curFunction->defn.info.routine.localSymTable);
        if(symbol)
            return(symbol);
    }
    SymTableNodePtr symbol = searchSymTable(strlwr(symbolName), ModuleRegistry[handle].moduleIdPtr->defn.info.routine.localSymTable);
    if(!symbol && searchLibraries)
    {
        for(size_t i = 0; i < ModuleRegistry[handle].numLibrariesUsed; i++)
        {
            symbol = searchSymTable(strlwr(symbolName), ModuleRegistry[ModuleRegistry[handle].librariesUsed[i]->handle].moduleIdPtr->defn.info.routine.localSymTable);
            if(symbol)
                break;
        }
    }
    return(symbol);
}
예제 #6
0
SymTableNodePtr ABLModule::findFunction(PSTR functionName, bool searchLibraries)
{
    SymTableNodePtr symbol = searchSymTableForFunction(functionName, ModuleRegistry[handle].moduleIdPtr->defn.info.routine.localSymTable);
    if(!symbol && searchLibraries)
    {
        for(size_t i = 0; i < ModuleRegistry[handle].numLibrariesUsed; i++)
        {
            char temp[1024];
            memset(temp, 0, 1024);
            strncpy(temp, functionName, (strlen(functionName) > 1020) ? 1020 : strlen(functionName));
            symbol = searchSymTable(_strlwr(temp), ModuleRegistry[ModuleRegistry[handle].librariesUsed[i]->handle].moduleIdPtr->defn.info.routine.localSymTable);
            if(symbol)
                break;
        }
    }
    return(symbol);
}
예제 #7
0
void executeChild(SymTableNodePtr routineIdPtr, SymTableNodePtr childRoutineIdPtr)
{
	// THIS DOES NOT SUPPORT CALLING FUNCTIONS WITH PARAMETERS YET!
	SymTableNodePtr thisRoutineIdPtr = CurRoutineIdPtr;
	CurRoutineIdPtr = routineIdPtr;
	routineEntry(routineIdPtr);
	//----------------------------------------------------
	// Now, search this module for the function we want...
	SymTableNodePtr initFunctionIdPtr = nullptr;
	if(CallModuleInit)
	{
		CallModuleInit = false;
		initFunctionIdPtr = searchSymTable("init", routineIdPtr->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(initFunctionIdPtr != childRoutineIdPtr)
	{
		//-----------------------------------------------------------------------
		// If we're calling the module's init function, and we just did above,
		// don't call it again! That's why we make the check on the above line...
		execRoutineCall(childRoutineIdPtr, false);
		//-------------------------------------------------------------------------
		// Since we're calling the function directly, we need to compensate for the
		// codeSegmentPtr being incremented by 1 in the normal execRoutineCall...
		codeSegmentPtr--;
	}
	//---------------------------------------------
	// In case we exited with a return statement...
	ExitWithReturn = false;
	ExitFromTacOrder = false;
	routineExit(routineIdPtr);
	CurRoutineIdPtr = thisRoutineIdPtr;
}
예제 #8
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;
}
예제 #9
0
TypePtr factor (void) {

	TypePtr thisType = NULL;
	switch (curToken) {
		case TKN_IDENTIFIER: {
			SymTableNodePtr IdPtr = NULL;
			searchAndFindAllSymTables(IdPtr);
			switch (IdPtr->defn.key) {
				case DFN_FUNCTION:
					crunchSymTableNodePtr(IdPtr);
					getToken();
					thisType = routineCall(IdPtr, 1);
					break;
				case DFN_CONST:
					crunchSymTableNodePtr(IdPtr);
					getToken();
					thisType = (TypePtr)(IdPtr->typePtr);
					break;
				default:
					thisType = (TypePtr)variable(IdPtr);
					break;
			}
			}
			break;
		case TKN_NUMBER: {
			SymTableNodePtr thisNode = searchSymTable(tokenString, SymTableDisplay[1]);
			if (!thisNode)
				thisNode = enterSymTable(tokenString, &SymTableDisplay[1]);
			if (curLiteral.type == LIT_INTEGER) {
				thisNode->typePtr = IntegerTypePtr;
				thisType = (TypePtr)(thisNode->typePtr);
				thisNode->defn.info.constant.value.integer = curLiteral.value.integer;
				}
			else {
				thisNode->typePtr = RealTypePtr;
				thisType = (TypePtr)(thisNode->typePtr);
				thisNode->defn.info.constant.value.real = curLiteral.value.real;
			}
			crunchSymTableNodePtr(thisNode);
			getToken();
			}
			break;
		case TKN_STRING: {
			long length = strlen(curLiteral.value.string);
			if (EnterStateSymbol) {
				SymTableNodePtr stateSymbol = searchSymTableForState(curLiteral.value.string, SymTableDisplay[1]);
				if (!stateSymbol)
					forwardState(curLiteral.value.string);
			}
			SymTableNodePtr thisNode = searchSymTableForString(tokenString, SymTableDisplay[1]);
			if (!thisNode)// {
				thisNode = enterSymTable(tokenString, &SymTableDisplay[1]);
				if (length == 1) {
					thisNode->defn.info.constant.value.character = curLiteral.value.string[0];
					thisType = CharTypePtr;
					}
				else {
					thisNode->typePtr = thisType = makeStringType(length);
					thisNode->info = (char*)ABLSymbolMallocCallback(length + 1);
					if (!thisNode->info)
						ABL_Fatal(0, " ABL: Unable to AblSymTableHeap->malloc string literal ");
					strcpy(thisNode->info, curLiteral.value.string);
				}
			//}
			crunchSymTableNodePtr(thisNode);

			getToken();
			}
			break;
		case TKN_NOT:
			getToken();
			thisType = factor();
			break;
		case TKN_LPAREN:
			getToken();
			thisType = expression();
			ifTokenGetElseError(TKN_RPAREN, ABL_ERR_SYNTAX_MISSING_RPAREN);
			break;
		default:
			syntaxError(ABL_ERR_SYNTAX_INVALID_EXPRESSION);
			thisType = &DummyType;
			break;
	}
	return(thisType);
}
예제 #10
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);
}
예제 #11
0
TypePtr caseLabel (CaseItemPtr& caseItemHead, CaseItemPtr& caseItemTail, long& caseLabelCount) {

	CaseItemPtr newCaseItem = (CaseItemPtr)ABLStackMallocCallback(sizeof(CaseItem));
	if (!newCaseItem)
		ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc case item ");
	if (caseItemHead) {
		caseItemTail->next = newCaseItem;
		caseItemTail = newCaseItem;
		}
	else
		caseItemHead = caseItemTail = newCaseItem;
	newCaseItem->next = NULL;
	caseLabelCount++;

	TokenCodeType sign = TKN_PLUS;
	bool sawSign = false;
	if ((curToken == TKN_PLUS) || (curToken == TKN_MINUS)) {
		sign = curToken;
		sawSign = true;
		getToken();
	}

	if (curToken == TKN_NUMBER) {
		SymTableNodePtr thisNode = searchSymTable(tokenString, SymTableDisplay[1]);
		if (!thisNode)
			thisNode = enterSymTable(tokenString, &SymTableDisplay[1]);
		crunchSymTableNodePtr(thisNode);
		if (curLiteral.type == LIT_INTEGER)
			newCaseItem->labelValue = (sign == TKN_PLUS) ? curLiteral.value.integer : -curLiteral.value.integer;
		else
			syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT);
		return(IntegerTypePtr);
		}
	else if (curToken == TKN_IDENTIFIER) {
		SymTableNodePtr idPtr;
		searchAllSymTables(idPtr);
		crunchSymTableNodePtr(idPtr);
		if (!idPtr) {
			syntaxError(ABL_ERR_SYNTAX_UNDEFINED_IDENTIFIER);
			return(&DummyType);
			}
		else if (idPtr->defn.key != DFN_CONST) {
			syntaxError(ABL_ERR_SYNTAX_NOT_A_CONSTANT_IDENTIFIER);
			return(&DummyType);
			}
		else if (idPtr->typePtr == IntegerTypePtr) {
			newCaseItem->labelValue = (sign == TKN_PLUS ? idPtr->defn.info.constant.value.integer : -idPtr->defn.info.constant.value.integer);
			return(IntegerTypePtr);
			}
		else if (idPtr->typePtr == CharTypePtr) {
			if (sawSign)
				syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT);
			newCaseItem->labelValue = idPtr->defn.info.constant.value.character;
			return(CharTypePtr);
			}
		else if (idPtr->typePtr->form == FRM_ENUM) {
			if (sawSign)
				syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT);
			newCaseItem->labelValue = idPtr->defn.info.constant.value.integer;
			return(idPtr->typePtr);
			}
		else
			return(&DummyType);
		}
	else if (curToken == TKN_STRING) {
		// STRING/CHAR TYPE...
		}
	else {
		syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT);
		return(&DummyType);
	}
	return(&DummyType);
}
예제 #12
0
inline void searchThisSymTable (SymTableNodePtr& IdPtr, SymTableNodePtr thisTable) {

	IdPtr = searchSymTable(wordString, thisTable);
}
예제 #13
0
void searchLocalSymTable (SymTableNodePtr& IdPtr) {

	IdPtr = searchSymTable(wordString, SymTableDisplay[level]);
}