12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691 |
- //===========================================================================//
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- //===========================================================================//
- //***************************************************************************
- //
- // ABLRTN.CPP
- //
- //***************************************************************************
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #ifndef ABLGEN_H
- #include "ablgen.h"
- #endif
- #ifndef ABLERR_H
- #include "ablerr.h"
- #endif
- #ifndef ABLSCAN_H
- #include "ablscan.h"
- #endif
- #ifndef ABLSYMT_H
- #include "ablsymt.h"
- #endif
- #ifndef ABLPARSE_H
- #include "ablparse.h"
- #endif
- #ifndef ABLEXEC_H
- #include "ablexec.h"
- #endif
- #ifndef ABLENV_H
- #include "ablenv.h"
- #endif
- #ifndef ABL_H
- #include "abl.h"
- #endif
- #ifndef ABLDBUG_H
- #include "abldbug.h"
- #endif
- //***************************************************************************
- extern long MaxBreaks;
- extern long MaxWatches;
- extern DebuggerPtr debugger;
- extern long NumModules;
- extern ModuleEntryPtr ModuleRegistry;
- extern ABLModulePtr* ModuleInstanceRegistry;
- extern long MaxModules;
- extern ABLModulePtr* LibraryInstanceRegistry;
- extern long MaxLibraries;
- extern long NumModulesRegistered;
- extern long NumModuleInstances;
- extern long MaxWatchesPerModule;
- extern long MaxBreakPointsPerModule;
- extern long MaxCodeBufferSize;
- extern ABLModulePtr CurModule;
- extern ABLModulePtr CurLibrary;
- extern char* codeBuffer;
- extern char* codeBufferPtr;
- extern char* codeSegmentPtr;
- extern char* codeSegmentLimit;
- extern char* statementStartPtr;
- extern StackItem* stack;
- extern StackItemPtr tos;
- extern StackItemPtr stackFrameBasePtr;
- extern StackItemPtr StaticDataPtr;
- extern long* StaticVariablesSizes;
- extern long* EternalVariablesSizes;
- extern long MaxEternalVariables;
- extern long eternalOffset;
- extern long MaxStaticVariables;
- extern long NumStaticVariables;
- extern long NumOrderCalls;
- extern StateHandleInfo StateHandleList[MAX_STATE_HANDLES_PER_MODULE];
- extern long NumStateHandles;
- extern long CurModuleHandle;
- extern bool CallModuleInit;
- extern bool AutoReturnFromOrders;
- extern long MaxLoopIterations;
- extern bool AssertEnabled;
- extern bool IncludeDebugInfo;
- extern bool ProfileABL;
- extern bool Crunch;
- extern long level;
- extern long lineNumber;
- extern long FileNumber;
- extern ABLFile* sourceFile;
- extern bool printFlag;
- extern bool blockFlag;
- extern BlockType blockType;
- extern SymTableNodePtr CurModuleIdPtr;
- extern SymTableNodePtr CurRoutineIdPtr;
- extern bool DumbGetCharOn;
- extern long NumOpenFiles;
- extern long NumSourceFiles;
- extern long NumLibrariesUsed;
- extern ABLModulePtr LibrariesUsed[MAX_LIBRARIES_USED];
- extern long bufferOffset;
- extern char* bufferp;
- extern char* tokenp;
- extern long digitCount;
- extern bool countError;
- extern long pageNumber;
- extern long lineCount;
- extern long CurAlarm;
- extern bool eofFlag;
- extern bool ExitWithReturn;
- extern bool ExitFromTacOrder;
- extern long dummyCount;
- extern long lineNumber;
- extern long FileNumber;
- extern long errorCount;
- extern long execStatementCount;
- extern long NumSourceFiles;
- extern char SourceFiles[MAX_SOURCE_FILES][MAXLEN_FILENAME];
-
- extern TokenCodeType curToken;
- extern char wordString[];
- extern SymTableNodePtr symTableDisplay[];
- extern long level;
- extern bool blockFlag;
- extern BlockType blockType;
- extern bool printFlag;
- extern SymTableNodePtr CurRoutineIdPtr;
- extern Type DummyType;
- extern StackItem* stack;
- //extern StackItem* eternalStack;
- extern StackItemPtr tos;
- extern StackItemPtr stackFrameBasePtr;
- extern long eternalOffset;
- extern TokenCodeType statementStartList[];
- extern TokenCodeType statementEndList[];
- extern TokenCodeType declarationStartList[];
- extern char tokenString[MAXLEN_TOKENSTRING];
- extern CharCodeType charTable[256];
- extern char sourceBuffer[MAXLEN_SOURCELINE];
- extern long bufferOffset;
- extern char* bufferp;
- extern char* tokenp;
- extern long digitCount;
- extern bool countError;
- extern bool eofFlag;
- extern long pageNumber;
- extern SymTableNodePtr SymTableDisplay[MAX_NESTING_LEVEL];
- extern TypePtr IntegerTypePtr;
- extern TypePtr RealTypePtr;
- extern TypePtr BooleanTypePtr;
- extern StackItemPtr StaticDataPtr;
- extern StackItem returnValue;
- extern ModuleEntryPtr ModuleRegistry;
- extern long MaxModules;
- extern long NumModulesRegistered;
- extern long MaxStaticVariables;
- extern long NumStaticVariables;
- extern long NumSourceFiles;
- extern bool IncludeDebugInfo;
- extern bool AssertEnabled;
- extern bool PrintEnabled;
- extern bool StringFunctionsEnabled;
- extern bool DebugCodeEnabled;
- extern DebuggerPtr debugger;
- bool ABLenabled = false;
- char buffer[MAXLEN_PRINTLINE];
- extern long CallStackLevel;
- extern bool SkipOrder;
- extern ABLModulePtr CurFSM;
- extern bool NewStateSet;
- extern void transState (SymTableNodePtr newState);
- long numLibrariesLoaded = 0;
- long NumExecutions = 0;
- void* (*ABLSystemMallocCallback) (unsigned long memSize) = NULL;
- void* (*ABLStackMallocCallback) (unsigned long memSize) = NULL;
- void* (*ABLCodeMallocCallback) (unsigned long memSize) = NULL;
- void* (*ABLSymbolMallocCallback) (unsigned long memSize) = NULL;
- void (*ABLSystemFreeCallback) (void* memBlock) = NULL;
- void (*ABLStackFreeCallback) (void* memBlock) = NULL;
- void (*ABLCodeFreeCallback) (void* memBlock) = NULL;
- void (*ABLSymbolFreeCallback) (void* memBlock) = NULL;
- void (*ABLDebugPrintCallback) (char* s) = NULL;
- long (*ABLRandomCallback) (long range) = NULL;
- void (*ABLSeedRandomCallback) (unsigned long range) = NULL;
- unsigned long (*ABLGetTimeCallback) (void) = NULL;
- void (*ABLFatalCallback) (long code, char* s) = NULL;
- void (*ABLEndlessStateCallback) (UserFile* log) = NULL;
- //***************************************************************************
- TokenCodeType followHeaderList[] = {
- TKN_SEMICOLON,
- TKN_EOF,
- TKN_NONE
- };
- TokenCodeType followModuleIdList[] = {
- TKN_LPAREN,
- TKN_COLON,
- TKN_SEMICOLON,
- TKN_EOF,
- TKN_NONE
- };
- TokenCodeType followFunctionIdList[] = {
- TKN_LPAREN,
- TKN_COLON,
- TKN_SEMICOLON,
- TKN_EOF,
- TKN_NONE
- };
- TokenCodeType followParamsList[] = {
- TKN_RPAREN,
- TKN_COMMA,
- TKN_EOF,
- TKN_NONE
- };
- TokenCodeType followParamList[] = {
- TKN_COMMA,
- TKN_RPAREN,
- TKN_NONE
- };
- TokenCodeType followModuleDeclsList[] = {
- TKN_SEMICOLON,
- TKN_CODE,
- TKN_EOF,
- TKN_NONE
- };
- TokenCodeType followRoutineDeclsList[] = {
- TKN_SEMICOLON,
- TKN_CODE,
- TKN_EOF,
- TKN_NONE
- };
- TokenCodeType followDeclsList[] = {
- TKN_SEMICOLON,
- TKN_EOF,
- TKN_NONE
- };
- void ABL_CloseProfileLog (void);
- void ABL_OpenProfileLog (void);
- void ABL_AddToProfileLog (char* profileString);
- //***************************************************************************
- // ABL library interface routines
- //***************************************************************************
- long DefaultRandom (long range) {
- return(0);
- }
- //---------------------------------------------------------------------------
- void DefaultSeedRandom (unsigned long seed) {
- }
- //---------------------------------------------------------------------------
- void DefaultDebugPrintCallback (char* s) {
- }
- //---------------------------------------------------------------------------
- unsigned long DefaultGetTimeCallback (void) {
- return(0);
- }
- //---------------------------------------------------------------------------
- void ABLi_setRandomCallbacks (void (*seedRandomCallback) (unsigned long seed),
- long (*randomCallback) (long range)) {
- ABLSeedRandomCallback = seedRandomCallback;
- ABLRandomCallback = randomCallback;
- }
- //---------------------------------------------------------------------------
- void ABLi_setDebugPrintCallback (void (*debugPrintCallback) (char* s)) {
- ABLDebugPrintCallback = debugPrintCallback;
- }
- //---------------------------------------------------------------------------
- void ABLi_setGetTimeCallback (unsigned long (*getTimeCallback) (void)) {
- ABLGetTimeCallback = getTimeCallback;
- }
- //---------------------------------------------------------------------------
- void ABLi_setEndlessStateCallback (void (*endlessStateCallback) (UserFile* log)) {
- ABLEndlessStateCallback = endlessStateCallback;
- }
- //---------------------------------------------------------------------------
- void ABLi_init (unsigned long runtimeStackSize,
- unsigned long maxCodeBufferSize,
- unsigned long maxRegisteredModules,
- unsigned long maxStaticVariables,
- void* (*systemMallocCallback) (unsigned long memSize),
- void* (*stackMallocCallback) (unsigned long memSize),
- void* (*codeMallocCallback) (unsigned long memSize),
- void* (*symbolMallocCallback) (unsigned long memSize),
- void (*systemFreeCallback) (void* memBlock),
- void (*stackFreeCallback) (void* memBlock),
- void (*codeFreeCallback) (void* memBlock),
- void (*symbolFreeCallback) (void* memBlock),
- long (*fileCreateCB) (void** file, char* fName),
- long (*fileOpenCB) (void** file, char* fName),
- long (*fileCloseCB) (void** file),
- bool (*fileEofCB) (void* file),
- long (*fileReadCB) (void* file, unsigned char* buffer, long length),
- long (*fileReadLongCB) (void* file),
- long (*fileReadStringCB) (void* file, unsigned char* buffer),
- long (*fileReadLineExCB) (void* file, unsigned char* buffer, long maxLength),
- long (*fileWriteCB) (void* file, unsigned char* buffer, long length),
- long (*fileWriteByteCB) (void* file, unsigned char byte),
- long (*fileWriteLongCB) (void* file, long value),
- long (*fileWriteStringCB) (void* file, char* buffer),
- void (*debuggerPrintCallback) (char* s),
- void (*fatalCallback) (long code, char* s),
- bool debugInfo,
- bool debug,
- bool profile) {
- // HACK, for testing...
- #ifdef _DEBUG
- profile = true;
- #endif
- //
- //-------------------------------------------------------------------
- // Let's make sure we have not created too many built-in ABL routines
- // for the lovely user...
- if (NUM_ABL_ROUTINES > 254)
- ABL_Fatal(0, " MAJOR ABL ERROR: Too Many ABL Routines ");
- ABLSystemMallocCallback = systemMallocCallback;
- ABLStackMallocCallback = stackMallocCallback;
- ABLCodeMallocCallback = codeMallocCallback;
- ABLSymbolMallocCallback = symbolMallocCallback;
- ABLSystemFreeCallback = systemFreeCallback;
- ABLStackFreeCallback = stackFreeCallback;
- ABLCodeFreeCallback = codeFreeCallback;
- ABLSymbolFreeCallback = symbolFreeCallback;
- ABLDebugPrintCallback = DefaultDebugPrintCallback;
- ABLRandomCallback = DefaultRandom;
- ABLSeedRandomCallback = DefaultSeedRandom;
- ABLGetTimeCallback = DefaultGetTimeCallback;
- ABLFatalCallback = fatalCallback;
- ABLFile::createCB = fileCreateCB;
- ABLFile::openCB = fileOpenCB;
- ABLFile::closeCB = fileCloseCB;
- ABLFile::eofCB = fileEofCB;
- ABLFile::readCB = fileReadCB;
- ABLFile::readLongCB = fileReadLongCB;
- ABLFile::readStringCB = fileReadStringCB;
- ABLFile::readLineExCB = fileReadLineExCB;
- ABLFile::writeCB = fileWriteCB;
- ABLFile::writeByteCB = fileWriteByteCB;
- ABLFile::writeLongCB = fileWriteLongCB;
- ABLFile::writeStringCB = fileWriteStringCB;
- NumStandardFunctions = NUM_ABL_ROUTINES;
- ABLenabled = true;
- MaxBreaks = 50;
- MaxWatches = 50;
- debugger = NULL;
- NumModules = 0;
- ModuleRegistry = NULL;
- ModuleInstanceRegistry = NULL;
- LibraryInstanceRegistry = NULL;
- MaxModules = 0;
- MaxLibraries = 0;
- NumModulesRegistered = 0;
- NumModuleInstances = 0;
- MaxWatchesPerModule = 20;
- MaxBreakPointsPerModule = 20;
- CurModule = NULL;
- errorCount = 0;
- codeBuffer = NULL;
- codeBufferPtr = NULL;
- codeSegmentPtr = NULL;
- codeSegmentLimit = NULL;
- statementStartPtr = NULL;
- execStatementCount = 0;
- stack = NULL;
- tos = NULL;
- stackFrameBasePtr = NULL;
- StaticDataPtr = NULL;
- StaticVariablesSizes = NULL;
- EternalVariablesSizes = NULL;
- MaxEternalVariables = 5000;
- eternalOffset = 0;
- MaxStaticVariables = 0;
- NumStaticVariables = 0;
- NumOrderCalls = 0;
- NumStateHandles = 1;
- CurModuleHandle = 0;
- CallModuleInit = false;
- AutoReturnFromOrders = false;
- MaxLoopIterations = 100001;
- AssertEnabled = false;
- PrintEnabled = false;
- StringFunctionsEnabled = true;
- IncludeDebugInfo = true;
- ProfileABL = profile;
- Crunch = true;
- level = 0;
- lineNumber = 0;
- FileNumber = 0;
- sourceFile = NULL;
- printFlag = true;
- blockFlag = false;
- blockType = BLOCK_MODULE;
- CurModuleIdPtr = NULL;
- CurRoutineIdPtr = NULL;
- DumbGetCharOn = false;
- NumOpenFiles = 0;
- NumSourceFiles = 0;
- bufferOffset = 0;
- bufferp = sourceBuffer;
- tokenp = tokenString;
- digitCount = 0;
- countError = false;
- pageNumber = 0;
- lineCount = MAX_LINES_PER_PAGE;
- eofFlag = false;
- ExitWithReturn = false;
- ExitFromTacOrder = false;
- dummyCount = 0;
- numLibrariesLoaded = 0;
-
- //----------------------------------
- // Initialize the character table...
- for (long curCh = 0; curCh < 256; curCh++)
- charTable[curCh] = CHR_SPECIAL;
- for (curCh = '0'; curCh <= '9'; curCh++)
- charTable[curCh] = CHR_DIGIT;
- for (curCh = 'A'; curCh <= 'Z'; curCh++)
- charTable[curCh] = CHR_LETTER;
- for (curCh = 'a'; curCh <= 'z'; curCh++)
- charTable[curCh] = CHR_LETTER;
- charTable['\"'] = CHR_DQUOTE;
- charTable[CHAR_EOF] = CHR_EOF;
- //--------------------------------------------------------------------
- // Allocate the code buffer used during pre-processing/interpreting...
- MaxCodeBufferSize = maxCodeBufferSize;
- codeBuffer = (char*)ABLCodeMallocCallback(maxCodeBufferSize);
- if (!codeBuffer)
- ABL_Fatal(0, " ABL: Unable to AblCodeHeap->malloc preprocess code buffer ");
-
- //----------------------------------------------------------------------
- // Alloc the static variable data block. Ultimately, we may want to just
- // implement the static data construction with a linked list, rather
- // than a set max size...
- MaxStaticVariables = maxStaticVariables;
- NumStaticVariables = 0;
- NumOrderCalls = 0;
- NumStateHandles = 1;
- StaticDataPtr = NULL;
- StaticVariablesSizes = NULL;
- if (MaxStaticVariables > 0) {
- StaticVariablesSizes = (long*)ABLStackMallocCallback(sizeof(long) * MaxStaticVariables);
- if (!StaticVariablesSizes)
- ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc StaticVariablesSizes ");
- }
- //------------------------------
- // Allocate the runtime stack...
- stack = (StackItemPtr)ABLStackMallocCallback(sizeof(StackItem) * (runtimeStackSize / sizeof(StackItem)));
- if (!stack)
- ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc stack ");
- //-----------------------------------
- // Allocate Eternal Vars Size List...
- if (MaxEternalVariables > 0) {
- EternalVariablesSizes = (long*)ABLStackMallocCallback(sizeof(long) * MaxEternalVariables);
- if (!EternalVariablesSizes)
- ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc EternalVariablesSizes ");
- }
- //-------------------------
- // Prep the symbol table...
- initSymTable();
- initModuleRegistry(maxRegisteredModules);
- initLibraryRegistry(10);
- //--------------------------------
- // Init the debugger, if needed...
- IncludeDebugInfo = debugInfo;
- if (debug) {
- IncludeDebugInfo = true;
- debugger = new Debugger;
- if (!debugger)
- ABL_Fatal(0, " Unable to initialize ABL Debugger. ");
- debugger->init(debuggerPrintCallback, NULL);
- }
- UserFile::setup();
- if (ProfileABL)
- ABL_OpenProfileLog();
- #ifdef TEST_ABLFILE
- ABLFile* aFile = new ABLFile;
- aFile->create("ablFile.txt");
- aFile->writeString("Testing writeString");
- aFile->writeByte(NULL);
- aFile->writeLong(100);
- aFile->close();
- delete aFile;
- aFile = NULL;
- unsigned char s[100];
- ABLFile* bFile = new ABLFile;
- bFile->open("ablFile.txt");
- bFile->readString(s);
- long val = bFile->readLong();
- bFile->close();
- delete bFile;
- bFile = NULL;
- #endif
- }
- //***************************************************************************
- long ABLi_preProcess (char* sourceFileName, long* numErrors, long* numLinesProcessed, long* numFilesProcessed, bool printLines) {
- //--------------------------------------------------------------------------------
- // First, check if this module has already been registered into the environment...
- for (long i = 0; i < NumModulesRegistered; i++)
- if (strcmp(strlwr(sourceFileName), ModuleRegistry[i].fileName) == 0)
- return(i);
- //---------------------------------
- // Init some important variables...
- level = 0;
- lineNumber = 0;
- FileNumber = 0;
- AssertEnabled = (debugger != NULL);
- PrintEnabled = (debugger != NULL);
- StringFunctionsEnabled = true;
- DebugCodeEnabled = (debugger != NULL);
- NumSourceFiles = 0;
- NumLibrariesUsed = 0;
- sourceFile = NULL;
- printFlag = printLines;
- blockFlag = false;
- blockType = BLOCK_MODULE;
- bufferOffset = 0;
- bufferp = sourceBuffer;
- tokenp = tokenString;
- digitCount = 0;
- countError = false;
- pageNumber = 0;
- errorCount = 0;
- execStatementCount = 0;
- eofFlag = false;
- NumStaticVariables = 0;
- NumOrderCalls = 0;
- NumStateHandles = 1;
- for (i = 0; i < MAX_STATE_HANDLES_PER_MODULE; i++) {
- StateHandleList[i].name[0] = NULL;
- StateHandleList[i].state = NULL;
- }
- if (numErrors)
- *numErrors = 0;
- if (numLinesProcessed)
- *numLinesProcessed = 0;
- //---------------------------------------
- // Now, let's open the ABL source file...
- long openErr = ABL_NO_ERR;
- if ((openErr = openSourceFile(sourceFileName)) != ABL_NO_ERR)
- return(openErr);
- //------------------------
- // Set up the code buffer.
- codeBufferPtr = codeBuffer;
- //------------------
- // Get it rolling...
- getToken();
- SymTableNodePtr moduleIdPtr = moduleHeader();
- CurModuleIdPtr = moduleIdPtr;
- CurRoutineIdPtr = moduleIdPtr;
- //---------------------
- // Error synchronize...
- synchronize(followHeaderList, declarationStartList, statementStartList);
- if (curToken == TKN_SEMICOLON)
- getToken();
- else if (tokenIn(declarationStartList) || tokenIn(statementStartList))
- syntaxError(ABL_ERR_SYNTAX_MISSING_SEMICOLON);
- //-------------------------------------------------------------
- // Parse the module's block. Use to call block(), now we do the
- // stuff right here...
- //block(moduleIdPtr);
- declarations(moduleIdPtr, true);
- if ((moduleIdPtr->defn.info.routine.flags & ROUTINE_FLAG_FSM) == 0) {
- synchronize(followModuleDeclsList, NULL, NULL);
- if (curToken != TKN_CODE)
- syntaxError(ABL_ERR_SYNTAX_MISSING_CODE);
- crunchToken();
- blockType = BLOCK_MODULE;
- blockFlag = true;
- getToken();
- TokenCodeType endToken = TKN_END_MODULE;
- if (CurLibrary)
- endToken = TKN_END_LIBRARY;
- if (curToken != endToken)
- do {
- statement();
- while (curToken == TKN_SEMICOLON)
- getToken();
- if (curToken == endToken)
- break;
-
- //------------------------------------
- // Synchronize after possible error...
- synchronize(statementStartList, NULL, NULL);
- } while (tokenIn(statementStartList));
- }
- if (CurLibrary)
- ifTokenGetElseError(TKN_END_LIBRARY, ABL_ERR_SYNTAX_MISSING_END_LIBRARY);
- else if (moduleIdPtr->defn.info.routine.flags & ROUTINE_FLAG_FSM)
- ifTokenGetElseError(TKN_END_FSM, ABL_ERR_SYNTAX_MISSING_END_FSM);
- else
- ifTokenGetElseError(TKN_END_MODULE, ABL_ERR_SYNTAX_MISSING_END_MODULE);
- blockFlag = false;
- moduleIdPtr->defn.info.routine.localSymTable = exitScope();
- moduleIdPtr->defn.info.routine.codeSegment = createCodeSegment(moduleIdPtr->defn.info.routine.codeSegmentSize);
- analyzeBlock(moduleIdPtr->defn.info.routine.codeSegment);
- ifTokenGetElseError(TKN_PERIOD, ABL_ERR_SYNTAX_MISSING_PERIOD);
- while (curToken != TKN_EOF) {
- syntaxError(TKN_UNEXPECTED_TOKEN);
- getToken();
- }
- //------------------------------------------
- // Done with the source file, so close it...
- closeSourceFile();
- //extractSymTable(&SymTableDisplay[0], moduleIdPtr);
- //--------------------------------------------------
- // Register the new module in the ABL environment...
- ModuleRegistry[NumModulesRegistered].fileName = (char*)ABLStackMallocCallback(strlen(sourceFileName) + 1);
- if (!ModuleRegistry[NumModulesRegistered].fileName)
- ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc module filename ");
- strcpy(ModuleRegistry[NumModulesRegistered].fileName, strlwr(sourceFileName));
- ModuleRegistry[NumModulesRegistered].moduleIdPtr = moduleIdPtr;
- ModuleRegistry[NumModulesRegistered].numSourceFiles = NumSourceFiles;
- ModuleRegistry[NumModulesRegistered].sourceFiles = (char**)ABLStackMallocCallback(NumSourceFiles * sizeof(char*));
- if (!ModuleRegistry[NumModulesRegistered].sourceFiles)
- ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc sourceFiles ");
- for (i = 0; i < NumSourceFiles; i++) {
- ModuleRegistry[NumModulesRegistered].sourceFiles[i] = (char*)ABLStackMallocCallback(strlen(SourceFiles[i]) + 1);
- strcpy(ModuleRegistry[NumModulesRegistered].sourceFiles[i], SourceFiles[i]);
- }
- if (NumLibrariesUsed > 0) {
- ModuleRegistry[NumModulesRegistered].numLibrariesUsed = NumLibrariesUsed;
- ModuleRegistry[NumModulesRegistered].librariesUsed = (ABLModulePtr*)ABLStackMallocCallback(NumLibrariesUsed * sizeof(SymTableNodePtr));
- if (!ModuleRegistry[NumModulesRegistered].librariesUsed)
- ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc librariesUsed ");
- for (i = 0; i < NumLibrariesUsed; i++)
- ModuleRegistry[NumModulesRegistered].librariesUsed[i] = LibrariesUsed[i];
- }
- ModuleRegistry[NumModulesRegistered].numStaticVars = NumStaticVariables;
- ModuleRegistry[NumModulesRegistered].sizeStaticVars = NULL;
- ModuleRegistry[NumModulesRegistered].totalSizeStaticVars = 0;
- if (NumStaticVariables) {
- ModuleRegistry[NumModulesRegistered].sizeStaticVars = (long*)ABLStackMallocCallback(sizeof(long) * NumStaticVariables);
- if (!ModuleRegistry[NumModulesRegistered].sizeStaticVars)
- ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc module sizeStaticVars ");
- memcpy(ModuleRegistry[NumModulesRegistered].sizeStaticVars, StaticVariablesSizes, sizeof(long) * NumStaticVariables);
- ModuleRegistry[NumModulesRegistered].totalSizeStaticVars = sizeof(long) * NumStaticVariables;
- for (long i = 0; i < ModuleRegistry[NumModulesRegistered].numStaticVars; i++)
- ModuleRegistry[NumModulesRegistered].totalSizeStaticVars += ModuleRegistry[NumModulesRegistered].sizeStaticVars[i];
- }
- ModuleRegistry[NumModulesRegistered].numOrderCalls = NumOrderCalls;
- ModuleRegistry[NumModulesRegistered].numInstances = 0;
- ModuleRegistry[NumModulesRegistered].numStateHandles = NumStateHandles;
- if (NumStateHandles > 1) {
- ModuleRegistry[NumModulesRegistered].stateHandles = (StateHandleInfoPtr)ABLStackMallocCallback(sizeof(StateHandleInfo) * NumStateHandles);
- memcpy(ModuleRegistry[NumModulesRegistered].stateHandles, StateHandleList, sizeof(StateHandleInfo) * NumStateHandles);
- }
-
- NumModulesRegistered++;
- //---------------------------------------------------------------
- // Now, exit with the number of source lines processed, if any...
- if (numLinesProcessed)
- *numLinesProcessed = lineNumber;
- if (numFilesProcessed)
- *numFilesProcessed = FileNumber;
- if (numErrors)
- *numErrors = errorCount;
- return(NumModulesRegistered - 1);
- }
- //***************************************************************************
- long ABLi_execute (SymTableNodePtr moduleIdPtr, SymTableNodePtr functionIdPtr, ABLParamPtr paramList, StackItemPtr returnVal) {
- //insertSymTable(&SymTableDisplay[0], moduleIdPtr);
- //--------------------------
- // Execute the ABL module...
- //----------------------------------------------------------------------------------
- // NOTE: Ultimately, we want the ABL virtual machine to be set up once, and then
- // ABL modules/routines can be called multiple times from within a program. For now,
- // to test, let's just assume every time we run a module, it is a self-contained
- // ABL program.
- //---------------------------------
- // Init some important variables...
- //lineNumber = 0;
- //printFlag = true;
- //blockFlag = false;
- //blockType = BLOCK_MODULE;
- CurModuleIdPtr = NULL;
- CurRoutineIdPtr = NULL;
- //bufferOffset = 0;
- //bufferp = sourceBuffer;
- //tokenp = tokenString;
- //digitCount = 0;
- //countError = false;
- errorCount = 0;
- execStatementCount = 0;
- NumExecutions++;
- //------------------
- // Init the stack...
- stackFrameBasePtr = tos = (stack + eternalOffset);
- //---------------------------------------
- // Initialize the module's stack frame...
- level = 1;
- CallStackLevel = 0;
- stackFrameBasePtr = tos + 1;
-
- //-------------------------
- // Function return value...
- pushInteger(0);
- //---------------
- // Static Link...
- pushAddress(NULL);
- //----------------
- // Dynamic Link...
- pushAddress(NULL);
- //------------------
- // Return Address...
- pushAddress(NULL);
- //initDebugger();
- //----------
- // Run it...
- if (paramList) {
- //------------------------------------------------------------------------------
- // NOTE: Currently, parameter passing of arrays is not functioning. This MUST be
- // done...
- long curParam = 0;
- for (SymTableNodePtr formalIdPtr = (SymTableNodePtr)(moduleIdPtr->defn.info.routine.params);
- formalIdPtr != NULL;
- formalIdPtr = formalIdPtr->next) {
- TypePtr formalTypePtr = (TypePtr)(formalIdPtr->typePtr);
- if (formalIdPtr->defn.key == DFN_VALPARAM) {
- if (formalTypePtr == RealTypePtr) {
- if (paramList[curParam].type == ABL_PARAM_INTEGER) {
- //---------------------------------------------
- // Real formal parameter, but integer actual...
- pushReal((float)(paramList[curParam].integer));
- }
- else if (paramList[curParam].type == ABL_PARAM_REAL)
- pushReal(paramList[curParam].real);
- }
- else if (formalTypePtr == IntegerTypePtr) {
- if (paramList[curParam].type== ABL_PARAM_INTEGER)
- pushInteger(paramList[curParam].integer);
- else
- return(0);
- }
- //----------------------------------------------------------
- // 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...
- long size = formalTypePtr->size;
- char* dest = (char*)ABLStackMallocCallback((size_t)size);
- if (!dest)
- ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc module formal array param ");
- char* src = tos->address;
- char* savePtr = dest;
- memcpy(dest, src, size);
- tos->address = savePtr;
- }
- }
- else {
- //-------------------------------
- // pass by reference parameter...
- if (formalTypePtr == RealTypePtr)
- pushAddress((Address)&(paramList[curParam].real));
- else if (formalTypePtr == IntegerTypePtr)
- pushAddress((Address)&(paramList[curParam].integer));
- else
- return(0);
- //SymTableNodePtr idPtr = getCodeSymTableNodePtr();
- //execVariable(idPtr, USE_REFPARAM);
- }
- curParam++;
- }
- }
- execute(moduleIdPtr);
- if (returnVal)
- memcpy(returnVal, &returnValue, sizeof(StackItem));
- //extractSymTable(&SymTableDisplay[0], moduleIdPtr);
- //-----------
- // Summary...
- return(execStatementCount);
- }
- //***************************************************************************
- long ABLi_deleteModule (SymTableNodePtr moduleIdPtr) {
- return(ABL_NO_ERR);
- }
- //***************************************************************************
- void ABLi_close (void) {
- if (!codeBuffer)
- return;
- UserFile::cleanup();
- destroyModuleRegistry();
- destroyLibraryRegistry();
- if (StaticVariablesSizes) {
- ABLStackFreeCallback(StaticVariablesSizes);
- StaticVariablesSizes = NULL;
- }
- if (EternalVariablesSizes) {
- ABLStackFreeCallback(EternalVariablesSizes);
- EternalVariablesSizes = NULL;
- }
-
- if (codeBuffer) {
- ABLCodeFreeCallback(codeBuffer);
- codeBuffer = NULL;
- }
- if (stack) {
- ABLStackFreeCallback(stack);
- stack = NULL;
- }
- if (debugger) {
- delete debugger;
- debugger = NULL;
- }
- ABL_CloseProfileLog();
- ABLenabled = false;
- }
- //***************************************************************************
- ABLModulePtr ABLi_loadLibrary (char* sourceFileName, long* numErrors, long* numLinesProcessed, long* numFilesProcessed, bool printLines, bool createInstance) {
- //--------------------------------------------------------------------
- // Create an instance of it so it may be used from other modules. Note
- // that we need this when preprocessing since all identifiers in the
- // library should point to this module...
- ABLModulePtr library = new ABLModule;
- if (!library)
- ABL_Fatal(0, "ABL: no RAM for library");
- CurLibrary = library;
- //-------------------------------------------------------------
- // Preprocess the library. Note that a library should be loaded
- // just once.
- long libraryHandle = ABLi_preProcess(sourceFileName, numErrors, numLinesProcessed, numFilesProcessed, printLines);
- if (libraryHandle < (NumModulesRegistered - 1)) {
- //------------------
- // Already loaded...
- delete library;
- library = NULL;
- CurLibrary = NULL;
- return(NULL);
- }
- CurLibrary = NULL;
- LibraryInstanceRegistry[numLibrariesLoaded] = library;
- numLibrariesLoaded++;
- if (!createInstance) {
- CurLibrary = NULL;
- return(library);
- }
- long err = library->init(libraryHandle);
- ABL_Assert(err == ABL_NO_ERR, err, " Error Loading ABL Library ");
- library->setName(sourceFileName);
- return(library);
- }
- //***************************************************************************
- ABLParamPtr ABLi_createParamList (long numParameters) {
- if (numParameters) {
- ABLParamPtr paramList = (ABLParamPtr)ABLStackMallocCallback(sizeof(ABLParam) * (numParameters + 1));
- if (!paramList)
- ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc paramList ");
- memset(paramList, 0, sizeof(ABLParam) * (numParameters + 1));
- return(paramList);
- }
- return(NULL);
- }
- //***************************************************************************
- void ABLi_setIntegerParam (ABLParamPtr paramList, long index, long value) {
- if (paramList) {
- paramList[index].type = ABL_PARAM_INTEGER;
- paramList[index].integer = value;
- }
- }
- //***************************************************************************
- void ABLi_setRealParam (ABLParamPtr paramList, long index, float value) {
- if (paramList) {
- paramList[index].type = ABL_PARAM_REAL;
- paramList[index].real = value;
- }
- }
- //***************************************************************************
- void ABLi_deleteParamList (ABLParamPtr paramList) {
- if (paramList)
- ABLStackFreeCallback(paramList);
- }
- //***************************************************************************
- ABLModulePtr ABLi_getModule (long id) {
- if ((id >= 0) && (id < NumModules))
- return(ModuleInstanceRegistry[id]);
- return(NULL);
- }
- //***************************************************************************
- bool ABLi_enabled (void) {
- return(ABLenabled);
- }
- //***************************************************************************
- void ABLi_addFunction (char* name,
- bool isOrder,
- char* paramList,
- char* returnType,
- void (*codeCallback)(void)) {
- enterStandardRoutine(name, -1, isOrder, paramList, returnType, codeCallback);
- }
- //***************************************************************************
- long ABLi_registerInteger (char* name, long* address, long numElements) {
- if (strlen(name) >= MAXLEN_TOKENSTRING)
- ABL_Fatal(0, " ABLi_registerInteger: variable name too long ");
- level = 0;
- strcpy(wordString, name);
- SymTableNodePtr idPtr = NULL;
- searchAndEnterThisTable (idPtr, SymTableDisplay[0]);
- if (numElements == 1) {
- idPtr->library = NULL;
- idPtr->defn.key = DFN_VAR;
- idPtr->labelIndex = 0;
- idPtr->typePtr = setType(IntegerTypePtr);
- idPtr->defn.info.data.varType = VAR_TYPE_REGISTERED;
- idPtr->defn.info.data.registeredData = address;
- }
- return(ABL_NO_ERR);
- }
- //***************************************************************************
- long ABLi_registerReal (char* name, float* address, long numElements) {
- if (strlen(name) >= MAXLEN_TOKENSTRING)
- ABL_Fatal(0, " ABLi_registerInteger: variable name too long ");
- level = 0;
- strcpy(wordString, name);
- SymTableNodePtr idPtr = NULL;
- searchAndEnterThisTable (idPtr, SymTableDisplay[0]);
- idPtr->library = NULL;
- idPtr->defn.key = DFN_VAR;
- idPtr->labelIndex = 0;
- idPtr->typePtr = setType(RealTypePtr);
- idPtr->defn.info.data.varType = VAR_TYPE_REGISTERED;
- idPtr->defn.info.data.registeredData = address;
- return(ABL_NO_ERR);
- }
- //***************************************************************************
- bool ABLi_getSkipOrder (void) {
- return(SkipOrder);
- }
- //***************************************************************************
- void ABLi_resetOrders (void) {
- CurModule->resetOrderCallFlags();
- }
- //***************************************************************************
- long ABLi_getCurrentState (void) {
- if (CurFSM)
- return(CurFSM->getStateHandle());
- return(NULL);
- }
- //***************************************************************************
- void ABLi_transState (long newStateHandle) {
- if (CurFSM && (newStateHandle > 0) && (newStateHandle < ModuleRegistry[CurFSM->getHandle()].numStateHandles))
- transState(ModuleRegistry[CurFSM->getHandle()].stateHandles[newStateHandle].state);
- }
- //***************************************************************************
- // MODULE routines
- //***************************************************************************
- SymTableNodePtr moduleHeader (void) {
- SymTableNodePtr moduleIdPtr = NULL;
- bool isFSM = false;
- if (CurLibrary)
- ifTokenGetElseError(TKN_LIBRARY, ABL_ERR_SYNTAX_MISSING_LIBRARY);
- else if (curToken == TKN_FSM) {
- isFSM = true;
- getToken();
- }
- else
- ifTokenGetElseError(TKN_MODULE, ABL_ERR_SYNTAX_MISSING_MODULE);
- //------------------------------------------------------------
- // NOTE: If a module is a library, its library pointer will be
- // non-NULL.
-
- if (curToken == TKN_IDENTIFIER) {
- searchAndEnterLocalSymTable(moduleIdPtr);
- moduleIdPtr->defn.key = DFN_MODULE;
- moduleIdPtr->defn.info.routine.key = RTN_DECLARED;
- moduleIdPtr->defn.info.routine.flags = (isFSM ? ROUTINE_FLAG_FSM : 0);
- moduleIdPtr->defn.info.routine.orderCallIndex = 0;
- moduleIdPtr->defn.info.routine.numOrderCalls = 0;
- moduleIdPtr->defn.info.routine.paramCount = 0;
- moduleIdPtr->defn.info.routine.totalParamSize = 0;
- moduleIdPtr->defn.info.routine.totalLocalSize = 0;
- moduleIdPtr->defn.info.routine.params = NULL;
- moduleIdPtr->defn.info.routine.locals = NULL;
- moduleIdPtr->defn.info.routine.localSymTable = NULL;
- moduleIdPtr->defn.info.routine.codeSegment = NULL;
- moduleIdPtr->library = CurLibrary;
- moduleIdPtr->typePtr = &DummyType;
- moduleIdPtr->labelIndex = 0;
- getToken();
- }
- else
- syntaxError(ABL_ERR_SYNTAX_MISSING_IDENTIFIER);
- //--------------------------------------------
- // For now, modules do not have param lists...
- synchronize(followModuleIdList, declarationStartList, statementStartList);
- enterScope(NULL);
- if (curToken == TKN_LPAREN) {
- long paramCount;
- long totalParamSize;
- SymTableNodePtr paramListPtr = formalParamList(¶mCount, &totalParamSize);
- //if (forwardFlag)
- // syntaxError(ABL_ERR_SYNTAX_ALREADY_FORWARDED);
- //else {
- moduleIdPtr->defn.info.routine.paramCount = (unsigned char)paramCount;
- moduleIdPtr->defn.info.routine.totalParamSize = (unsigned char)totalParamSize;
- moduleIdPtr->defn.info.routine.params = paramListPtr;
- //}
- }
- //else if (!forwardFlag) {
- // functionIdPtr->defn.info.routine.paramCount = 0;
- // functionIdPtr->defn.info.routine.totalParamSize = 0;
- // functionIdPtr->defn.info.routine.params = NULL;
- //}
- //-----------------------------
- // Now, check if return type...
- moduleIdPtr->typePtr = NULL;
- SymTableNodePtr typeIdPtr = NULL;
- if (curToken == TKN_COLON) {
- getToken();
- if (curToken == TKN_IDENTIFIER) {
- searchAndFindAllSymTables(typeIdPtr);
-
- if (typeIdPtr->defn.key != DFN_TYPE)
- syntaxError(ABL_ERR_SYNTAX_INVALID_TYPE);
- //if (!forwardFlag)
- moduleIdPtr->typePtr = typeIdPtr->typePtr;
- getToken();
- }
- else {
- syntaxError(ABL_ERR_SYNTAX_MISSING_IDENTIFIER);
- moduleIdPtr->typePtr = &DummyType;
- }
- //if (forwardFlag)
- // syntaxError(ABL_ERR_SYNTAX_ALREADY_FORWARDED);
- }
- return(moduleIdPtr);
- }
- //***************************************************************************
- // ROUTINE/FUNCTION routines
- //***************************************************************************
- void routine (void) {
- SymTableNodePtr routineIdPtr = NULL;
-
- //------------------------------------------------------------------------
- // Do we want to have "procedures", or do functions handle both cases (with
- // and without return values)? For now, functions handle both...
- routineIdPtr = functionHeader();
- //------------------------------------------------------------------
- // We need to save a pointer to the current routine we're parsing...
- SymTableNodePtr prevRoutineIdPtr = CurRoutineIdPtr;
- CurRoutineIdPtr = routineIdPtr;
- //---------------------
- // Error synchronize...
- synchronize(followHeaderList, declarationStartList, statementStartList);
- if (curToken == TKN_SEMICOLON)
- getToken();
- else if (tokenIn(declarationStartList) || tokenIn(statementStartList))
- syntaxError(ABL_ERR_SYNTAX_MISSING_SEMICOLON);
- if (strcmp(wordString, "forward") != 0) {
- routineIdPtr->defn.info.routine.key = RTN_DECLARED;
- //analyzeRoutineHeader(routineIdPtr);
- routineIdPtr->defn.info.routine.locals = NULL;
- declarations(routineIdPtr, false);
- synchronize(followRoutineDeclsList, NULL, NULL);
- if (curToken != TKN_CODE)
- syntaxError(ABL_ERR_SYNTAX_MISSING_CODE);
- crunchToken();
- blockType = BLOCK_ROUTINE;
- blockFlag = true;
- routineIdPtr->defn.info.routine.orderCallIndex = (unsigned short)NumOrderCalls;
- //compoundStatement();
- getToken();
- TokenCodeType endToken = TKN_END_FUNCTION;
- if (routineIdPtr->defn.info.routine.flags & ROUTINE_FLAG_STATE)
- endToken = TKN_END_STATE;
- else if (routineIdPtr->defn.info.routine.flags & ROUTINE_FLAG_ORDER)
- endToken = TKN_END_ORDER;
- if (curToken != endToken)
- do {
- statement();
- while (curToken == TKN_SEMICOLON)
- getToken();
- if (curToken == endToken)
- break;
-
- //------------------------------------
- // Synchronize after possible error...
- synchronize(statementStartList, NULL, NULL);
- } while (tokenIn(statementStartList));
- ifTokenGetElseError(endToken, ABL_ERR_SYNTAX_MISSING_END_FUNCTION);
- blockFlag = false;
- routineIdPtr->defn.info.routine.numOrderCalls = (unsigned short)NumOrderCalls - routineIdPtr->defn.info.routine.orderCallIndex;
- routineIdPtr->defn.info.routine.codeSegment = createCodeSegment(routineIdPtr->defn.info.routine.codeSegmentSize);
- analyzeBlock(routineIdPtr->defn.info.routine.codeSegment);
- }
- else {
- getToken();
- routineIdPtr->defn.info.routine.key = RTN_FORWARD;
- analyzeRoutineHeader(routineIdPtr);
- }
- if (routineIdPtr->defn.info.routine.flags & ROUTINE_FLAG_STATE) {
- //-----------------------------------
- // Add it to the state handle list...
- if (NumStateHandles == MAX_STATE_HANDLES_PER_MODULE)
- ABL_Fatal(0, "ABL: too many states in fsm [19 max]");
- strcpy(StateHandleList[NumStateHandles].name, routineIdPtr->name);
- StateHandleList[NumStateHandles].state = routineIdPtr;
- NumStateHandles++;
- }
- routineIdPtr->defn.info.routine.localSymTable = exitScope();
- CurRoutineIdPtr = prevRoutineIdPtr;
- }
- //***************************************************************************
- SymTableNodePtr forwardState (char* stateName) {
- SymTableNodePtr stateSymbol = searchSymTableForState(stateName, SymTableDisplay[1]);
- if (stateSymbol)
- ABL_Fatal(0, " ABL.forwardState: State symbol should not exist ");
- stateSymbol = enterSymTable(stateName, &SymTableDisplay[1]);
- stateSymbol->defn.key = DFN_FUNCTION;
- stateSymbol->defn.info.routine.key = RTN_FORWARD;
- stateSymbol->defn.info.routine.paramCount = 0;
- stateSymbol->defn.info.routine.flags = ROUTINE_FLAG_STATE;
- stateSymbol->defn.info.routine.orderCallIndex = 0;
- stateSymbol->defn.info.routine.numOrderCalls = 0;
- stateSymbol->defn.info.routine.totalParamSize = 0;
- stateSymbol->defn.info.routine.totalLocalSize = 0;
- stateSymbol->defn.info.routine.params = NULL;
- stateSymbol->defn.info.routine.locals = NULL;
- stateSymbol->defn.info.routine.localSymTable = NULL;
- stateSymbol->defn.info.routine.codeSegment = NULL;
- stateSymbol->library = CurLibrary;
- stateSymbol->typePtr = NULL;
- stateSymbol->labelIndex = 0;
- //-------------------
- // Force the level...
- stateSymbol->level = 1;
- return(stateSymbol);
- }
- //***************************************************************************
- SymTableNodePtr functionHeader (void) {
- bool isState = false;
- bool isOrder = false;
- if (curToken == TKN_STATE)
- isState = true;
- else if (curToken == TKN_ORDER)
- isOrder = true;
- getToken();
- SymTableNodePtr functionIdPtr = NULL;
- SymTableNodePtr typeIdPtr = NULL;
- bool forwardFlag = false;
- if (curToken == TKN_IDENTIFIER) {
- functionIdPtr = searchSymTableForFunction(wordString, SymTableDisplay[level]);
- if (!functionIdPtr) {
- enterLocalSymTable(functionIdPtr);
- functionIdPtr->defn.key = DFN_FUNCTION;
- functionIdPtr->defn.info.routine.key = RTN_DECLARED;
- functionIdPtr->defn.info.routine.paramCount = 0;
- functionIdPtr->defn.info.routine.flags = 0;
- functionIdPtr->defn.info.routine.orderCallIndex = 0;
- functionIdPtr->defn.info.routine.numOrderCalls = 0;
- functionIdPtr->defn.info.routine.totalParamSize = 0;
- functionIdPtr->defn.info.routine.totalLocalSize = 0;
- functionIdPtr->defn.info.routine.params = NULL;
- functionIdPtr->defn.info.routine.locals = NULL;
- functionIdPtr->defn.info.routine.localSymTable = NULL;
- functionIdPtr->defn.info.routine.codeSegment = NULL;
- if (isOrder)
- functionIdPtr->defn.info.routine.flags |= ROUTINE_FLAG_ORDER;
- if (isState)
- functionIdPtr->defn.info.routine.flags |= ROUTINE_FLAG_STATE;
- functionIdPtr->library = CurLibrary;
- functionIdPtr->typePtr = &DummyType;
- functionIdPtr->labelIndex = 0;
- }
- else if ((functionIdPtr->defn.key == DFN_FUNCTION) &&
- (functionIdPtr->defn.info.routine.key == RTN_FORWARD))
- forwardFlag = true;
- else
- syntaxError(ABL_ERR_SYNTAX_REDEFINED_IDENTIFIER);
- getToken();
- }
- //---------------------
- // Error synchronize...
- synchronize(followFunctionIdList, declarationStartList, statementStartList);
- enterScope(NULL);
- if (curToken == TKN_LPAREN) {
- long paramCount;
- long totalParamSize;
- SymTableNodePtr paramListPtr = formalParamList(¶mCount, &totalParamSize);
- if (forwardFlag)
- syntaxError(ABL_ERR_SYNTAX_ALREADY_FORWARDED);
- else {
- functionIdPtr->defn.info.routine.paramCount = (unsigned char)paramCount;
- functionIdPtr->defn.info.routine.totalParamSize = (unsigned char)totalParamSize;
- functionIdPtr->defn.info.routine.params = paramListPtr;
- }
- }
- else if (!forwardFlag) {
- functionIdPtr->defn.info.routine.paramCount = 0;
- functionIdPtr->defn.info.routine.totalParamSize = 0;
- functionIdPtr->defn.info.routine.params = NULL;
- }
- //--------------------------------------------
- // Now, check if return type and/or forward...
- functionIdPtr->typePtr = NULL;
- bool hasIntegerReturnValue = false;
- if (curToken == TKN_COLON) {
- getToken();
- if (curToken == TKN_IDENTIFIER) {
- searchAndFindAllSymTables(typeIdPtr);
-
- if (typeIdPtr->defn.key != DFN_TYPE)
- syntaxError(ABL_ERR_SYNTAX_INVALID_TYPE);
- hasIntegerReturnValue = (typeIdPtr->typePtr == IntegerTypePtr);
- if (!forwardFlag)
- functionIdPtr->typePtr = typeIdPtr->typePtr;
- getToken();
- }
- else {
- syntaxError(ABL_ERR_SYNTAX_MISSING_IDENTIFIER);
- functionIdPtr->typePtr = &DummyType;
- }
- if (forwardFlag)
- syntaxError(ABL_ERR_SYNTAX_ALREADY_FORWARDED);
- }
- if (isOrder && !hasIntegerReturnValue)
- syntaxError(ABL_ERR_SYNTAX_ORDER_RETURNTYPE);
- return(functionIdPtr);
- }
- //***************************************************************************
- SymTableNodePtr formalParamList (long* count, long* totalSize) {
- SymTableNodePtr paramIdPtr;
- SymTableNodePtr firstIdPtr;
- SymTableNodePtr lastIdPtr = NULL;
- SymTableNodePtr paramListPtr = NULL;
- SymTableNodePtr typeIdPtr;
- TypePtr paramTypePtr;
- DefinitionType paramDefn;
- long paramCount = 0;
- long paramOffset = STACK_FRAME_HEADER_SIZE;
- getToken();
- while ((curToken == TKN_IDENTIFIER) || (curToken == TKN_REF)) {
- firstIdPtr = NULL;
- if (curToken == TKN_REF) {
- paramDefn = DFN_REFPARAM;
- getToken();
- }
- else
- paramDefn = DFN_VALPARAM;
- //-----------------------------------
- // Grab the type of this parameter...
- if (curToken == TKN_IDENTIFIER) {
- searchAndFindAllSymTables(typeIdPtr);
- if (typeIdPtr->defn.key != DFN_TYPE)
- syntaxError(ABL_ERR_SYNTAX_INVALID_TYPE);
- paramTypePtr = (TypePtr)(typeIdPtr->typePtr);
- getToken();
- }
- else {
- syntaxError(ABL_ERR_SYNTAX_MISSING_IDENTIFIER);
- paramTypePtr = &DummyType;
- }
- //------------------------------------------------------------
- // Is this an array parameter? If so, parse the dimensions and
- // whether it's an open array...
- if (curToken == TKN_LBRACKET) {
- }
-
- //-----------------------------------------------
- // Now grab the variable id for this parameter...
- if (curToken == TKN_IDENTIFIER) {
- searchAndEnterLocalSymTable(paramIdPtr);
- paramIdPtr->defn.key = paramDefn;
- paramIdPtr->labelIndex = 0;
- paramIdPtr->typePtr = paramTypePtr;
- paramIdPtr->defn.info.data.offset = paramOffset++;
-
- paramCount++;
- if (paramListPtr == NULL)
- paramListPtr = paramIdPtr;
- if (lastIdPtr != NULL)
- lastIdPtr->next = paramIdPtr;
- lastIdPtr = paramIdPtr;
- //if (firstIdPtr == NULL)
- // firstIdPtr = lastIdPtr = paramIdPtr;
- //else {
- // lastIdPtr->next = paramIdPtr;
- // lastIdPtr = paramIdPtr;
- //}
- getToken();
- //ifTokenGet(TKN_COMMA);
- }
- else {
- syntaxError(ABL_ERR_SYNTAX_MISSING_IDENTIFIER);
- //--------------------------------
- // Do we need to synchronize here?
- }
- //------------------------------------------------------------------
- // Assign the offset and the type to all param ids in the sublist...
- //for (paramIdPtr = firstIdPtr; paramIdPtr != NULL; paramIdPtr = paramIdPtr->next) {
- // paramIdPtr->typePtr = paramTypePtr;
- // paramIdPtr->defn.info.data.offset = paramOffset++;
- //}
- //-----------------------------------------------
- // Link this list to the list of all param ids...
- //if (prevLastIdPtr != NULL)
- // prevLastIdPtr->next = firstIdPtr;
- //prevLastIdPtr = lastIdPtr;
- //-------------------------------
- // Error synch... should be ; or )
- synchronize(followParamsList, NULL, NULL);
- ifTokenGet(TKN_COMMA);
- }
- ifTokenGetElseError(TKN_RPAREN, ABL_ERR_SYNTAX_MISSING_RPAREN);
- *count = paramCount;
- *totalSize = paramOffset - STACK_FRAME_HEADER_SIZE;
- if (paramCount > 255)
- syntaxError(ABL_ERR_SYNTAX_TOO_MANY_FORMAL_PARAMETERS);
- return(paramListPtr);
- }
- //***************************************************************************
- TypePtr routineCall (SymTableNodePtr routineIdPtr, long paramCheckFlag) {
- SymTableNodePtr thisRoutineIdPtr = CurRoutineIdPtr;
- TypePtr resultType = NULL;
- if ((routineIdPtr->defn.info.routine.key == RTN_DECLARED) ||
- (routineIdPtr->defn.info.routine.key == RTN_FORWARD) ||
- !paramCheckFlag)
- resultType = declaredRoutineCall(routineIdPtr, paramCheckFlag);
- else
- resultType = standardRoutineCall(routineIdPtr);
- CurRoutineIdPtr = thisRoutineIdPtr;
- return(resultType);
- }
- //***************************************************************************
- TypePtr declaredRoutineCall (SymTableNodePtr routineIdPtr, long paramCheckFlag) {
- actualParamList(routineIdPtr, paramCheckFlag);
- return(/*routineIdPtr->defn.key == DFN_PROCEDURE ? NULL :*/ (TypePtr)(routineIdPtr->typePtr));
- }
- //***************************************************************************
- void actualParamList (SymTableNodePtr routineIdPtr, long paramCheckFlag) {
- SymTableNodePtr formalParamIdPtr = NULL;
- DefinitionType formalParamDefn = (DefinitionType)0;
- TypePtr formalParamTypePtr = NULL;
- TypePtr actualParamTypePtr = NULL;
- if (paramCheckFlag)
- formalParamIdPtr = (SymTableNodePtr)(routineIdPtr->defn.info.routine.params);
- if (curToken == TKN_LPAREN) {
- //-----------------------------------------------
- // Loop to process actual parameter expression...
- do {
- //----------------------------------------------------
- // Obtain info about the corresponding formal param...
- if (paramCheckFlag && (formalParamIdPtr != NULL)) {
- formalParamDefn = formalParamIdPtr->defn.key;
- formalParamTypePtr = (TypePtr)(formalParamIdPtr->typePtr);
- }
- getToken();
- if ((formalParamIdPtr == NULL) || (formalParamDefn == DFN_VALPARAM) || !paramCheckFlag) {
- //--------------
- // VAL Params...
- actualParamTypePtr = expression();
- if (paramCheckFlag && (formalParamIdPtr != NULL) && !isAssignTypeCompatible(formalParamTypePtr, actualParamTypePtr))
- syntaxError(ABL_ERR_SYNTAX_INCOMPATIBLE_TYPES);
- }
- else {
- //--------------
- // VAR params...
- if (curToken == TKN_IDENTIFIER) {
- SymTableNodePtr idPtr;
- searchAndFindAllSymTables(idPtr);
- actualParamTypePtr = variable(idPtr);
- if (formalParamTypePtr != actualParamTypePtr)
- syntaxError(ABL_ERR_SYNTAX_INCOMPATIBLE_TYPES);
- }
- else {
- //------------------------------------------------------------------
- // Not a variable--parse the expression anyway for error recovery...
- actualParamTypePtr = expression();
- syntaxError(ABL_ERR_SYNTAX_INVALID_REF_PARAM);
- }
- }
- //---------------------------------------
- // More actual params than formal params?
- if (paramCheckFlag) {
- if (formalParamIdPtr == NULL)
- syntaxError(ABL_ERR_SYNTAX_WRONG_NUMBER_OF_PARAMS);
- else
- formalParamIdPtr = formalParamIdPtr->next;
- }
- //---------------
- // Error synch...
- synchronize(followParamList, statementEndList, NULL);
- } while (curToken == TKN_COMMA);
- ifTokenGetElseError(TKN_RPAREN, ABL_ERR_SYNTAX_MISSING_RPAREN);
- }
- //----------------------------------------
- // Fewer actual params than formal params?
- if (paramCheckFlag && (formalParamIdPtr != NULL))
- syntaxError(ABL_ERR_SYNTAX_WRONG_NUMBER_OF_PARAMS);
- }
- //***************************************************************************
- extern char SetStateDebugStr[256];
- void transState (SymTableNodePtr newState) {
- if (CurFSM) {
- CurFSM->setPrevState(CurFSM->getState());
- CurFSM->setState(newState);
- sprintf(SetStateDebugStr, "%s:%s, line %d", CurModule->getFileName(), newState->name, execLineNumber);
- NewStateSet = true;
- }
- }
- //***************************************************************************
|