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); }
void searchAndEnterThisTable (SymTableNodePtr& IdPtr, SymTableNodePtr thisTable) { if ((IdPtr = searchSymTable(wordString, thisTable)) == NULL) IdPtr = enterSymTable(wordString, &thisTable); else syntaxError(ABL_ERR_SYNTAX_REDEFINED_IDENTIFIER); }
void searchAndEnterLocalSymTable (SymTableNodePtr& IdPtr) { if ((IdPtr = searchSymTable(wordString, SymTableDisplay[level])) == NULL) IdPtr = enterSymTable(wordString, &SymTableDisplay[level]); else syntaxError(ABL_ERR_SYNTAX_REDEFINED_IDENTIFIER); }
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); }
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); }
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); }
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; }
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; }
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); }
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); }
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); }
inline void searchThisSymTable (SymTableNodePtr& IdPtr, SymTableNodePtr thisTable) { IdPtr = searchSymTable(wordString, thisTable); }
void searchLocalSymTable (SymTableNodePtr& IdPtr) { IdPtr = searchSymTable(wordString, SymTableDisplay[level]); }