Ablrtn.cpp 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691
  1. //===========================================================================//
  2. // Copyright (C) Microsoft Corporation. All rights reserved. //
  3. //===========================================================================//
  4. //***************************************************************************
  5. //
  6. // ABLRTN.CPP
  7. //
  8. //***************************************************************************
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #ifndef ABLGEN_H
  13. #include "ablgen.h"
  14. #endif
  15. #ifndef ABLERR_H
  16. #include "ablerr.h"
  17. #endif
  18. #ifndef ABLSCAN_H
  19. #include "ablscan.h"
  20. #endif
  21. #ifndef ABLSYMT_H
  22. #include "ablsymt.h"
  23. #endif
  24. #ifndef ABLPARSE_H
  25. #include "ablparse.h"
  26. #endif
  27. #ifndef ABLEXEC_H
  28. #include "ablexec.h"
  29. #endif
  30. #ifndef ABLENV_H
  31. #include "ablenv.h"
  32. #endif
  33. #ifndef ABL_H
  34. #include "abl.h"
  35. #endif
  36. #ifndef ABLDBUG_H
  37. #include "abldbug.h"
  38. #endif
  39. //***************************************************************************
  40. extern long MaxBreaks;
  41. extern long MaxWatches;
  42. extern DebuggerPtr debugger;
  43. extern long NumModules;
  44. extern ModuleEntryPtr ModuleRegistry;
  45. extern ABLModulePtr* ModuleInstanceRegistry;
  46. extern long MaxModules;
  47. extern ABLModulePtr* LibraryInstanceRegistry;
  48. extern long MaxLibraries;
  49. extern long NumModulesRegistered;
  50. extern long NumModuleInstances;
  51. extern long MaxWatchesPerModule;
  52. extern long MaxBreakPointsPerModule;
  53. extern long MaxCodeBufferSize;
  54. extern ABLModulePtr CurModule;
  55. extern ABLModulePtr CurLibrary;
  56. extern char* codeBuffer;
  57. extern char* codeBufferPtr;
  58. extern char* codeSegmentPtr;
  59. extern char* codeSegmentLimit;
  60. extern char* statementStartPtr;
  61. extern StackItem* stack;
  62. extern StackItemPtr tos;
  63. extern StackItemPtr stackFrameBasePtr;
  64. extern StackItemPtr StaticDataPtr;
  65. extern long* StaticVariablesSizes;
  66. extern long* EternalVariablesSizes;
  67. extern long MaxEternalVariables;
  68. extern long eternalOffset;
  69. extern long MaxStaticVariables;
  70. extern long NumStaticVariables;
  71. extern long NumOrderCalls;
  72. extern StateHandleInfo StateHandleList[MAX_STATE_HANDLES_PER_MODULE];
  73. extern long NumStateHandles;
  74. extern long CurModuleHandle;
  75. extern bool CallModuleInit;
  76. extern bool AutoReturnFromOrders;
  77. extern long MaxLoopIterations;
  78. extern bool AssertEnabled;
  79. extern bool IncludeDebugInfo;
  80. extern bool ProfileABL;
  81. extern bool Crunch;
  82. extern long level;
  83. extern long lineNumber;
  84. extern long FileNumber;
  85. extern ABLFile* sourceFile;
  86. extern bool printFlag;
  87. extern bool blockFlag;
  88. extern BlockType blockType;
  89. extern SymTableNodePtr CurModuleIdPtr;
  90. extern SymTableNodePtr CurRoutineIdPtr;
  91. extern bool DumbGetCharOn;
  92. extern long NumOpenFiles;
  93. extern long NumSourceFiles;
  94. extern long NumLibrariesUsed;
  95. extern ABLModulePtr LibrariesUsed[MAX_LIBRARIES_USED];
  96. extern long bufferOffset;
  97. extern char* bufferp;
  98. extern char* tokenp;
  99. extern long digitCount;
  100. extern bool countError;
  101. extern long pageNumber;
  102. extern long lineCount;
  103. extern long CurAlarm;
  104. extern bool eofFlag;
  105. extern bool ExitWithReturn;
  106. extern bool ExitFromTacOrder;
  107. extern long dummyCount;
  108. extern long lineNumber;
  109. extern long FileNumber;
  110. extern long errorCount;
  111. extern long execStatementCount;
  112. extern long NumSourceFiles;
  113. extern char SourceFiles[MAX_SOURCE_FILES][MAXLEN_FILENAME];
  114. extern TokenCodeType curToken;
  115. extern char wordString[];
  116. extern SymTableNodePtr symTableDisplay[];
  117. extern long level;
  118. extern bool blockFlag;
  119. extern BlockType blockType;
  120. extern bool printFlag;
  121. extern SymTableNodePtr CurRoutineIdPtr;
  122. extern Type DummyType;
  123. extern StackItem* stack;
  124. //extern StackItem* eternalStack;
  125. extern StackItemPtr tos;
  126. extern StackItemPtr stackFrameBasePtr;
  127. extern long eternalOffset;
  128. extern TokenCodeType statementStartList[];
  129. extern TokenCodeType statementEndList[];
  130. extern TokenCodeType declarationStartList[];
  131. extern char tokenString[MAXLEN_TOKENSTRING];
  132. extern CharCodeType charTable[256];
  133. extern char sourceBuffer[MAXLEN_SOURCELINE];
  134. extern long bufferOffset;
  135. extern char* bufferp;
  136. extern char* tokenp;
  137. extern long digitCount;
  138. extern bool countError;
  139. extern bool eofFlag;
  140. extern long pageNumber;
  141. extern SymTableNodePtr SymTableDisplay[MAX_NESTING_LEVEL];
  142. extern TypePtr IntegerTypePtr;
  143. extern TypePtr RealTypePtr;
  144. extern TypePtr BooleanTypePtr;
  145. extern StackItemPtr StaticDataPtr;
  146. extern StackItem returnValue;
  147. extern ModuleEntryPtr ModuleRegistry;
  148. extern long MaxModules;
  149. extern long NumModulesRegistered;
  150. extern long MaxStaticVariables;
  151. extern long NumStaticVariables;
  152. extern long NumSourceFiles;
  153. extern bool IncludeDebugInfo;
  154. extern bool AssertEnabled;
  155. extern bool PrintEnabled;
  156. extern bool StringFunctionsEnabled;
  157. extern bool DebugCodeEnabled;
  158. extern DebuggerPtr debugger;
  159. bool ABLenabled = false;
  160. char buffer[MAXLEN_PRINTLINE];
  161. extern long CallStackLevel;
  162. extern bool SkipOrder;
  163. extern ABLModulePtr CurFSM;
  164. extern bool NewStateSet;
  165. extern void transState (SymTableNodePtr newState);
  166. long numLibrariesLoaded = 0;
  167. long NumExecutions = 0;
  168. void* (*ABLSystemMallocCallback) (unsigned long memSize) = NULL;
  169. void* (*ABLStackMallocCallback) (unsigned long memSize) = NULL;
  170. void* (*ABLCodeMallocCallback) (unsigned long memSize) = NULL;
  171. void* (*ABLSymbolMallocCallback) (unsigned long memSize) = NULL;
  172. void (*ABLSystemFreeCallback) (void* memBlock) = NULL;
  173. void (*ABLStackFreeCallback) (void* memBlock) = NULL;
  174. void (*ABLCodeFreeCallback) (void* memBlock) = NULL;
  175. void (*ABLSymbolFreeCallback) (void* memBlock) = NULL;
  176. void (*ABLDebugPrintCallback) (char* s) = NULL;
  177. long (*ABLRandomCallback) (long range) = NULL;
  178. void (*ABLSeedRandomCallback) (unsigned long range) = NULL;
  179. unsigned long (*ABLGetTimeCallback) (void) = NULL;
  180. void (*ABLFatalCallback) (long code, char* s) = NULL;
  181. void (*ABLEndlessStateCallback) (UserFile* log) = NULL;
  182. //***************************************************************************
  183. TokenCodeType followHeaderList[] = {
  184. TKN_SEMICOLON,
  185. TKN_EOF,
  186. TKN_NONE
  187. };
  188. TokenCodeType followModuleIdList[] = {
  189. TKN_LPAREN,
  190. TKN_COLON,
  191. TKN_SEMICOLON,
  192. TKN_EOF,
  193. TKN_NONE
  194. };
  195. TokenCodeType followFunctionIdList[] = {
  196. TKN_LPAREN,
  197. TKN_COLON,
  198. TKN_SEMICOLON,
  199. TKN_EOF,
  200. TKN_NONE
  201. };
  202. TokenCodeType followParamsList[] = {
  203. TKN_RPAREN,
  204. TKN_COMMA,
  205. TKN_EOF,
  206. TKN_NONE
  207. };
  208. TokenCodeType followParamList[] = {
  209. TKN_COMMA,
  210. TKN_RPAREN,
  211. TKN_NONE
  212. };
  213. TokenCodeType followModuleDeclsList[] = {
  214. TKN_SEMICOLON,
  215. TKN_CODE,
  216. TKN_EOF,
  217. TKN_NONE
  218. };
  219. TokenCodeType followRoutineDeclsList[] = {
  220. TKN_SEMICOLON,
  221. TKN_CODE,
  222. TKN_EOF,
  223. TKN_NONE
  224. };
  225. TokenCodeType followDeclsList[] = {
  226. TKN_SEMICOLON,
  227. TKN_EOF,
  228. TKN_NONE
  229. };
  230. void ABL_CloseProfileLog (void);
  231. void ABL_OpenProfileLog (void);
  232. void ABL_AddToProfileLog (char* profileString);
  233. //***************************************************************************
  234. // ABL library interface routines
  235. //***************************************************************************
  236. long DefaultRandom (long range) {
  237. return(0);
  238. }
  239. //---------------------------------------------------------------------------
  240. void DefaultSeedRandom (unsigned long seed) {
  241. }
  242. //---------------------------------------------------------------------------
  243. void DefaultDebugPrintCallback (char* s) {
  244. }
  245. //---------------------------------------------------------------------------
  246. unsigned long DefaultGetTimeCallback (void) {
  247. return(0);
  248. }
  249. //---------------------------------------------------------------------------
  250. void ABLi_setRandomCallbacks (void (*seedRandomCallback) (unsigned long seed),
  251. long (*randomCallback) (long range)) {
  252. ABLSeedRandomCallback = seedRandomCallback;
  253. ABLRandomCallback = randomCallback;
  254. }
  255. //---------------------------------------------------------------------------
  256. void ABLi_setDebugPrintCallback (void (*debugPrintCallback) (char* s)) {
  257. ABLDebugPrintCallback = debugPrintCallback;
  258. }
  259. //---------------------------------------------------------------------------
  260. void ABLi_setGetTimeCallback (unsigned long (*getTimeCallback) (void)) {
  261. ABLGetTimeCallback = getTimeCallback;
  262. }
  263. //---------------------------------------------------------------------------
  264. void ABLi_setEndlessStateCallback (void (*endlessStateCallback) (UserFile* log)) {
  265. ABLEndlessStateCallback = endlessStateCallback;
  266. }
  267. //---------------------------------------------------------------------------
  268. void ABLi_init (unsigned long runtimeStackSize,
  269. unsigned long maxCodeBufferSize,
  270. unsigned long maxRegisteredModules,
  271. unsigned long maxStaticVariables,
  272. void* (*systemMallocCallback) (unsigned long memSize),
  273. void* (*stackMallocCallback) (unsigned long memSize),
  274. void* (*codeMallocCallback) (unsigned long memSize),
  275. void* (*symbolMallocCallback) (unsigned long memSize),
  276. void (*systemFreeCallback) (void* memBlock),
  277. void (*stackFreeCallback) (void* memBlock),
  278. void (*codeFreeCallback) (void* memBlock),
  279. void (*symbolFreeCallback) (void* memBlock),
  280. long (*fileCreateCB) (void** file, char* fName),
  281. long (*fileOpenCB) (void** file, char* fName),
  282. long (*fileCloseCB) (void** file),
  283. bool (*fileEofCB) (void* file),
  284. long (*fileReadCB) (void* file, unsigned char* buffer, long length),
  285. long (*fileReadLongCB) (void* file),
  286. long (*fileReadStringCB) (void* file, unsigned char* buffer),
  287. long (*fileReadLineExCB) (void* file, unsigned char* buffer, long maxLength),
  288. long (*fileWriteCB) (void* file, unsigned char* buffer, long length),
  289. long (*fileWriteByteCB) (void* file, unsigned char byte),
  290. long (*fileWriteLongCB) (void* file, long value),
  291. long (*fileWriteStringCB) (void* file, char* buffer),
  292. void (*debuggerPrintCallback) (char* s),
  293. void (*fatalCallback) (long code, char* s),
  294. bool debugInfo,
  295. bool debug,
  296. bool profile) {
  297. // HACK, for testing...
  298. #ifdef _DEBUG
  299. profile = true;
  300. #endif
  301. //
  302. //-------------------------------------------------------------------
  303. // Let's make sure we have not created too many built-in ABL routines
  304. // for the lovely user...
  305. if (NUM_ABL_ROUTINES > 254)
  306. ABL_Fatal(0, " MAJOR ABL ERROR: Too Many ABL Routines ");
  307. ABLSystemMallocCallback = systemMallocCallback;
  308. ABLStackMallocCallback = stackMallocCallback;
  309. ABLCodeMallocCallback = codeMallocCallback;
  310. ABLSymbolMallocCallback = symbolMallocCallback;
  311. ABLSystemFreeCallback = systemFreeCallback;
  312. ABLStackFreeCallback = stackFreeCallback;
  313. ABLCodeFreeCallback = codeFreeCallback;
  314. ABLSymbolFreeCallback = symbolFreeCallback;
  315. ABLDebugPrintCallback = DefaultDebugPrintCallback;
  316. ABLRandomCallback = DefaultRandom;
  317. ABLSeedRandomCallback = DefaultSeedRandom;
  318. ABLGetTimeCallback = DefaultGetTimeCallback;
  319. ABLFatalCallback = fatalCallback;
  320. ABLFile::createCB = fileCreateCB;
  321. ABLFile::openCB = fileOpenCB;
  322. ABLFile::closeCB = fileCloseCB;
  323. ABLFile::eofCB = fileEofCB;
  324. ABLFile::readCB = fileReadCB;
  325. ABLFile::readLongCB = fileReadLongCB;
  326. ABLFile::readStringCB = fileReadStringCB;
  327. ABLFile::readLineExCB = fileReadLineExCB;
  328. ABLFile::writeCB = fileWriteCB;
  329. ABLFile::writeByteCB = fileWriteByteCB;
  330. ABLFile::writeLongCB = fileWriteLongCB;
  331. ABLFile::writeStringCB = fileWriteStringCB;
  332. NumStandardFunctions = NUM_ABL_ROUTINES;
  333. ABLenabled = true;
  334. MaxBreaks = 50;
  335. MaxWatches = 50;
  336. debugger = NULL;
  337. NumModules = 0;
  338. ModuleRegistry = NULL;
  339. ModuleInstanceRegistry = NULL;
  340. LibraryInstanceRegistry = NULL;
  341. MaxModules = 0;
  342. MaxLibraries = 0;
  343. NumModulesRegistered = 0;
  344. NumModuleInstances = 0;
  345. MaxWatchesPerModule = 20;
  346. MaxBreakPointsPerModule = 20;
  347. CurModule = NULL;
  348. errorCount = 0;
  349. codeBuffer = NULL;
  350. codeBufferPtr = NULL;
  351. codeSegmentPtr = NULL;
  352. codeSegmentLimit = NULL;
  353. statementStartPtr = NULL;
  354. execStatementCount = 0;
  355. stack = NULL;
  356. tos = NULL;
  357. stackFrameBasePtr = NULL;
  358. StaticDataPtr = NULL;
  359. StaticVariablesSizes = NULL;
  360. EternalVariablesSizes = NULL;
  361. MaxEternalVariables = 5000;
  362. eternalOffset = 0;
  363. MaxStaticVariables = 0;
  364. NumStaticVariables = 0;
  365. NumOrderCalls = 0;
  366. NumStateHandles = 1;
  367. CurModuleHandle = 0;
  368. CallModuleInit = false;
  369. AutoReturnFromOrders = false;
  370. MaxLoopIterations = 100001;
  371. AssertEnabled = false;
  372. PrintEnabled = false;
  373. StringFunctionsEnabled = true;
  374. IncludeDebugInfo = true;
  375. ProfileABL = profile;
  376. Crunch = true;
  377. level = 0;
  378. lineNumber = 0;
  379. FileNumber = 0;
  380. sourceFile = NULL;
  381. printFlag = true;
  382. blockFlag = false;
  383. blockType = BLOCK_MODULE;
  384. CurModuleIdPtr = NULL;
  385. CurRoutineIdPtr = NULL;
  386. DumbGetCharOn = false;
  387. NumOpenFiles = 0;
  388. NumSourceFiles = 0;
  389. bufferOffset = 0;
  390. bufferp = sourceBuffer;
  391. tokenp = tokenString;
  392. digitCount = 0;
  393. countError = false;
  394. pageNumber = 0;
  395. lineCount = MAX_LINES_PER_PAGE;
  396. eofFlag = false;
  397. ExitWithReturn = false;
  398. ExitFromTacOrder = false;
  399. dummyCount = 0;
  400. numLibrariesLoaded = 0;
  401. //----------------------------------
  402. // Initialize the character table...
  403. for (long curCh = 0; curCh < 256; curCh++)
  404. charTable[curCh] = CHR_SPECIAL;
  405. for (curCh = '0'; curCh <= '9'; curCh++)
  406. charTable[curCh] = CHR_DIGIT;
  407. for (curCh = 'A'; curCh <= 'Z'; curCh++)
  408. charTable[curCh] = CHR_LETTER;
  409. for (curCh = 'a'; curCh <= 'z'; curCh++)
  410. charTable[curCh] = CHR_LETTER;
  411. charTable['\"'] = CHR_DQUOTE;
  412. charTable[CHAR_EOF] = CHR_EOF;
  413. //--------------------------------------------------------------------
  414. // Allocate the code buffer used during pre-processing/interpreting...
  415. MaxCodeBufferSize = maxCodeBufferSize;
  416. codeBuffer = (char*)ABLCodeMallocCallback(maxCodeBufferSize);
  417. if (!codeBuffer)
  418. ABL_Fatal(0, " ABL: Unable to AblCodeHeap->malloc preprocess code buffer ");
  419. //----------------------------------------------------------------------
  420. // Alloc the static variable data block. Ultimately, we may want to just
  421. // implement the static data construction with a linked list, rather
  422. // than a set max size...
  423. MaxStaticVariables = maxStaticVariables;
  424. NumStaticVariables = 0;
  425. NumOrderCalls = 0;
  426. NumStateHandles = 1;
  427. StaticDataPtr = NULL;
  428. StaticVariablesSizes = NULL;
  429. if (MaxStaticVariables > 0) {
  430. StaticVariablesSizes = (long*)ABLStackMallocCallback(sizeof(long) * MaxStaticVariables);
  431. if (!StaticVariablesSizes)
  432. ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc StaticVariablesSizes ");
  433. }
  434. //------------------------------
  435. // Allocate the runtime stack...
  436. stack = (StackItemPtr)ABLStackMallocCallback(sizeof(StackItem) * (runtimeStackSize / sizeof(StackItem)));
  437. if (!stack)
  438. ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc stack ");
  439. //-----------------------------------
  440. // Allocate Eternal Vars Size List...
  441. if (MaxEternalVariables > 0) {
  442. EternalVariablesSizes = (long*)ABLStackMallocCallback(sizeof(long) * MaxEternalVariables);
  443. if (!EternalVariablesSizes)
  444. ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc EternalVariablesSizes ");
  445. }
  446. //-------------------------
  447. // Prep the symbol table...
  448. initSymTable();
  449. initModuleRegistry(maxRegisteredModules);
  450. initLibraryRegistry(10);
  451. //--------------------------------
  452. // Init the debugger, if needed...
  453. IncludeDebugInfo = debugInfo;
  454. if (debug) {
  455. IncludeDebugInfo = true;
  456. debugger = new Debugger;
  457. if (!debugger)
  458. ABL_Fatal(0, " Unable to initialize ABL Debugger. ");
  459. debugger->init(debuggerPrintCallback, NULL);
  460. }
  461. UserFile::setup();
  462. if (ProfileABL)
  463. ABL_OpenProfileLog();
  464. #ifdef TEST_ABLFILE
  465. ABLFile* aFile = new ABLFile;
  466. aFile->create("ablFile.txt");
  467. aFile->writeString("Testing writeString");
  468. aFile->writeByte(NULL);
  469. aFile->writeLong(100);
  470. aFile->close();
  471. delete aFile;
  472. aFile = NULL;
  473. unsigned char s[100];
  474. ABLFile* bFile = new ABLFile;
  475. bFile->open("ablFile.txt");
  476. bFile->readString(s);
  477. long val = bFile->readLong();
  478. bFile->close();
  479. delete bFile;
  480. bFile = NULL;
  481. #endif
  482. }
  483. //***************************************************************************
  484. long ABLi_preProcess (char* sourceFileName, long* numErrors, long* numLinesProcessed, long* numFilesProcessed, bool printLines) {
  485. //--------------------------------------------------------------------------------
  486. // First, check if this module has already been registered into the environment...
  487. for (long i = 0; i < NumModulesRegistered; i++)
  488. if (strcmp(strlwr(sourceFileName), ModuleRegistry[i].fileName) == 0)
  489. return(i);
  490. //---------------------------------
  491. // Init some important variables...
  492. level = 0;
  493. lineNumber = 0;
  494. FileNumber = 0;
  495. AssertEnabled = (debugger != NULL);
  496. PrintEnabled = (debugger != NULL);
  497. StringFunctionsEnabled = true;
  498. DebugCodeEnabled = (debugger != NULL);
  499. NumSourceFiles = 0;
  500. NumLibrariesUsed = 0;
  501. sourceFile = NULL;
  502. printFlag = printLines;
  503. blockFlag = false;
  504. blockType = BLOCK_MODULE;
  505. bufferOffset = 0;
  506. bufferp = sourceBuffer;
  507. tokenp = tokenString;
  508. digitCount = 0;
  509. countError = false;
  510. pageNumber = 0;
  511. errorCount = 0;
  512. execStatementCount = 0;
  513. eofFlag = false;
  514. NumStaticVariables = 0;
  515. NumOrderCalls = 0;
  516. NumStateHandles = 1;
  517. for (i = 0; i < MAX_STATE_HANDLES_PER_MODULE; i++) {
  518. StateHandleList[i].name[0] = NULL;
  519. StateHandleList[i].state = NULL;
  520. }
  521. if (numErrors)
  522. *numErrors = 0;
  523. if (numLinesProcessed)
  524. *numLinesProcessed = 0;
  525. //---------------------------------------
  526. // Now, let's open the ABL source file...
  527. long openErr = ABL_NO_ERR;
  528. if ((openErr = openSourceFile(sourceFileName)) != ABL_NO_ERR)
  529. return(openErr);
  530. //------------------------
  531. // Set up the code buffer.
  532. codeBufferPtr = codeBuffer;
  533. //------------------
  534. // Get it rolling...
  535. getToken();
  536. SymTableNodePtr moduleIdPtr = moduleHeader();
  537. CurModuleIdPtr = moduleIdPtr;
  538. CurRoutineIdPtr = moduleIdPtr;
  539. //---------------------
  540. // Error synchronize...
  541. synchronize(followHeaderList, declarationStartList, statementStartList);
  542. if (curToken == TKN_SEMICOLON)
  543. getToken();
  544. else if (tokenIn(declarationStartList) || tokenIn(statementStartList))
  545. syntaxError(ABL_ERR_SYNTAX_MISSING_SEMICOLON);
  546. //-------------------------------------------------------------
  547. // Parse the module's block. Use to call block(), now we do the
  548. // stuff right here...
  549. //block(moduleIdPtr);
  550. declarations(moduleIdPtr, true);
  551. if ((moduleIdPtr->defn.info.routine.flags & ROUTINE_FLAG_FSM) == 0) {
  552. synchronize(followModuleDeclsList, NULL, NULL);
  553. if (curToken != TKN_CODE)
  554. syntaxError(ABL_ERR_SYNTAX_MISSING_CODE);
  555. crunchToken();
  556. blockType = BLOCK_MODULE;
  557. blockFlag = true;
  558. getToken();
  559. TokenCodeType endToken = TKN_END_MODULE;
  560. if (CurLibrary)
  561. endToken = TKN_END_LIBRARY;
  562. if (curToken != endToken)
  563. do {
  564. statement();
  565. while (curToken == TKN_SEMICOLON)
  566. getToken();
  567. if (curToken == endToken)
  568. break;
  569. //------------------------------------
  570. // Synchronize after possible error...
  571. synchronize(statementStartList, NULL, NULL);
  572. } while (tokenIn(statementStartList));
  573. }
  574. if (CurLibrary)
  575. ifTokenGetElseError(TKN_END_LIBRARY, ABL_ERR_SYNTAX_MISSING_END_LIBRARY);
  576. else if (moduleIdPtr->defn.info.routine.flags & ROUTINE_FLAG_FSM)
  577. ifTokenGetElseError(TKN_END_FSM, ABL_ERR_SYNTAX_MISSING_END_FSM);
  578. else
  579. ifTokenGetElseError(TKN_END_MODULE, ABL_ERR_SYNTAX_MISSING_END_MODULE);
  580. blockFlag = false;
  581. moduleIdPtr->defn.info.routine.localSymTable = exitScope();
  582. moduleIdPtr->defn.info.routine.codeSegment = createCodeSegment(moduleIdPtr->defn.info.routine.codeSegmentSize);
  583. analyzeBlock(moduleIdPtr->defn.info.routine.codeSegment);
  584. ifTokenGetElseError(TKN_PERIOD, ABL_ERR_SYNTAX_MISSING_PERIOD);
  585. while (curToken != TKN_EOF) {
  586. syntaxError(TKN_UNEXPECTED_TOKEN);
  587. getToken();
  588. }
  589. //------------------------------------------
  590. // Done with the source file, so close it...
  591. closeSourceFile();
  592. //extractSymTable(&SymTableDisplay[0], moduleIdPtr);
  593. //--------------------------------------------------
  594. // Register the new module in the ABL environment...
  595. ModuleRegistry[NumModulesRegistered].fileName = (char*)ABLStackMallocCallback(strlen(sourceFileName) + 1);
  596. if (!ModuleRegistry[NumModulesRegistered].fileName)
  597. ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc module filename ");
  598. strcpy(ModuleRegistry[NumModulesRegistered].fileName, strlwr(sourceFileName));
  599. ModuleRegistry[NumModulesRegistered].moduleIdPtr = moduleIdPtr;
  600. ModuleRegistry[NumModulesRegistered].numSourceFiles = NumSourceFiles;
  601. ModuleRegistry[NumModulesRegistered].sourceFiles = (char**)ABLStackMallocCallback(NumSourceFiles * sizeof(char*));
  602. if (!ModuleRegistry[NumModulesRegistered].sourceFiles)
  603. ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc sourceFiles ");
  604. for (i = 0; i < NumSourceFiles; i++) {
  605. ModuleRegistry[NumModulesRegistered].sourceFiles[i] = (char*)ABLStackMallocCallback(strlen(SourceFiles[i]) + 1);
  606. strcpy(ModuleRegistry[NumModulesRegistered].sourceFiles[i], SourceFiles[i]);
  607. }
  608. if (NumLibrariesUsed > 0) {
  609. ModuleRegistry[NumModulesRegistered].numLibrariesUsed = NumLibrariesUsed;
  610. ModuleRegistry[NumModulesRegistered].librariesUsed = (ABLModulePtr*)ABLStackMallocCallback(NumLibrariesUsed * sizeof(SymTableNodePtr));
  611. if (!ModuleRegistry[NumModulesRegistered].librariesUsed)
  612. ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc librariesUsed ");
  613. for (i = 0; i < NumLibrariesUsed; i++)
  614. ModuleRegistry[NumModulesRegistered].librariesUsed[i] = LibrariesUsed[i];
  615. }
  616. ModuleRegistry[NumModulesRegistered].numStaticVars = NumStaticVariables;
  617. ModuleRegistry[NumModulesRegistered].sizeStaticVars = NULL;
  618. ModuleRegistry[NumModulesRegistered].totalSizeStaticVars = 0;
  619. if (NumStaticVariables) {
  620. ModuleRegistry[NumModulesRegistered].sizeStaticVars = (long*)ABLStackMallocCallback(sizeof(long) * NumStaticVariables);
  621. if (!ModuleRegistry[NumModulesRegistered].sizeStaticVars)
  622. ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc module sizeStaticVars ");
  623. memcpy(ModuleRegistry[NumModulesRegistered].sizeStaticVars, StaticVariablesSizes, sizeof(long) * NumStaticVariables);
  624. ModuleRegistry[NumModulesRegistered].totalSizeStaticVars = sizeof(long) * NumStaticVariables;
  625. for (long i = 0; i < ModuleRegistry[NumModulesRegistered].numStaticVars; i++)
  626. ModuleRegistry[NumModulesRegistered].totalSizeStaticVars += ModuleRegistry[NumModulesRegistered].sizeStaticVars[i];
  627. }
  628. ModuleRegistry[NumModulesRegistered].numOrderCalls = NumOrderCalls;
  629. ModuleRegistry[NumModulesRegistered].numInstances = 0;
  630. ModuleRegistry[NumModulesRegistered].numStateHandles = NumStateHandles;
  631. if (NumStateHandles > 1) {
  632. ModuleRegistry[NumModulesRegistered].stateHandles = (StateHandleInfoPtr)ABLStackMallocCallback(sizeof(StateHandleInfo) * NumStateHandles);
  633. memcpy(ModuleRegistry[NumModulesRegistered].stateHandles, StateHandleList, sizeof(StateHandleInfo) * NumStateHandles);
  634. }
  635. NumModulesRegistered++;
  636. //---------------------------------------------------------------
  637. // Now, exit with the number of source lines processed, if any...
  638. if (numLinesProcessed)
  639. *numLinesProcessed = lineNumber;
  640. if (numFilesProcessed)
  641. *numFilesProcessed = FileNumber;
  642. if (numErrors)
  643. *numErrors = errorCount;
  644. return(NumModulesRegistered - 1);
  645. }
  646. //***************************************************************************
  647. long ABLi_execute (SymTableNodePtr moduleIdPtr, SymTableNodePtr functionIdPtr, ABLParamPtr paramList, StackItemPtr returnVal) {
  648. //insertSymTable(&SymTableDisplay[0], moduleIdPtr);
  649. //--------------------------
  650. // Execute the ABL module...
  651. //----------------------------------------------------------------------------------
  652. // NOTE: Ultimately, we want the ABL virtual machine to be set up once, and then
  653. // ABL modules/routines can be called multiple times from within a program. For now,
  654. // to test, let's just assume every time we run a module, it is a self-contained
  655. // ABL program.
  656. //---------------------------------
  657. // Init some important variables...
  658. //lineNumber = 0;
  659. //printFlag = true;
  660. //blockFlag = false;
  661. //blockType = BLOCK_MODULE;
  662. CurModuleIdPtr = NULL;
  663. CurRoutineIdPtr = NULL;
  664. //bufferOffset = 0;
  665. //bufferp = sourceBuffer;
  666. //tokenp = tokenString;
  667. //digitCount = 0;
  668. //countError = false;
  669. errorCount = 0;
  670. execStatementCount = 0;
  671. NumExecutions++;
  672. //------------------
  673. // Init the stack...
  674. stackFrameBasePtr = tos = (stack + eternalOffset);
  675. //---------------------------------------
  676. // Initialize the module's stack frame...
  677. level = 1;
  678. CallStackLevel = 0;
  679. stackFrameBasePtr = tos + 1;
  680. //-------------------------
  681. // Function return value...
  682. pushInteger(0);
  683. //---------------
  684. // Static Link...
  685. pushAddress(NULL);
  686. //----------------
  687. // Dynamic Link...
  688. pushAddress(NULL);
  689. //------------------
  690. // Return Address...
  691. pushAddress(NULL);
  692. //initDebugger();
  693. //----------
  694. // Run it...
  695. if (paramList) {
  696. //------------------------------------------------------------------------------
  697. // NOTE: Currently, parameter passing of arrays is not functioning. This MUST be
  698. // done...
  699. long curParam = 0;
  700. for (SymTableNodePtr formalIdPtr = (SymTableNodePtr)(moduleIdPtr->defn.info.routine.params);
  701. formalIdPtr != NULL;
  702. formalIdPtr = formalIdPtr->next) {
  703. TypePtr formalTypePtr = (TypePtr)(formalIdPtr->typePtr);
  704. if (formalIdPtr->defn.key == DFN_VALPARAM) {
  705. if (formalTypePtr == RealTypePtr) {
  706. if (paramList[curParam].type == ABL_PARAM_INTEGER) {
  707. //---------------------------------------------
  708. // Real formal parameter, but integer actual...
  709. pushReal((float)(paramList[curParam].integer));
  710. }
  711. else if (paramList[curParam].type == ABL_PARAM_REAL)
  712. pushReal(paramList[curParam].real);
  713. }
  714. else if (formalTypePtr == IntegerTypePtr) {
  715. if (paramList[curParam].type== ABL_PARAM_INTEGER)
  716. pushInteger(paramList[curParam].integer);
  717. else
  718. return(0);
  719. }
  720. //----------------------------------------------------------
  721. // Formal parameter is an array or record, so make a copy...
  722. if ((formalTypePtr->form == FRM_ARRAY)/* || (formalTypePtr->form == FRM_RECORD)*/) {
  723. //------------------------------------------------------------------------------
  724. // The following is a little inefficient, but is kept this way to keep it clear.
  725. // Once it's verified to work, optimize...
  726. long size = formalTypePtr->size;
  727. char* dest = (char*)ABLStackMallocCallback((size_t)size);
  728. if (!dest)
  729. ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc module formal array param ");
  730. char* src = tos->address;
  731. char* savePtr = dest;
  732. memcpy(dest, src, size);
  733. tos->address = savePtr;
  734. }
  735. }
  736. else {
  737. //-------------------------------
  738. // pass by reference parameter...
  739. if (formalTypePtr == RealTypePtr)
  740. pushAddress((Address)&(paramList[curParam].real));
  741. else if (formalTypePtr == IntegerTypePtr)
  742. pushAddress((Address)&(paramList[curParam].integer));
  743. else
  744. return(0);
  745. //SymTableNodePtr idPtr = getCodeSymTableNodePtr();
  746. //execVariable(idPtr, USE_REFPARAM);
  747. }
  748. curParam++;
  749. }
  750. }
  751. execute(moduleIdPtr);
  752. if (returnVal)
  753. memcpy(returnVal, &returnValue, sizeof(StackItem));
  754. //extractSymTable(&SymTableDisplay[0], moduleIdPtr);
  755. //-----------
  756. // Summary...
  757. return(execStatementCount);
  758. }
  759. //***************************************************************************
  760. long ABLi_deleteModule (SymTableNodePtr moduleIdPtr) {
  761. return(ABL_NO_ERR);
  762. }
  763. //***************************************************************************
  764. void ABLi_close (void) {
  765. if (!codeBuffer)
  766. return;
  767. UserFile::cleanup();
  768. destroyModuleRegistry();
  769. destroyLibraryRegistry();
  770. if (StaticVariablesSizes) {
  771. ABLStackFreeCallback(StaticVariablesSizes);
  772. StaticVariablesSizes = NULL;
  773. }
  774. if (EternalVariablesSizes) {
  775. ABLStackFreeCallback(EternalVariablesSizes);
  776. EternalVariablesSizes = NULL;
  777. }
  778. if (codeBuffer) {
  779. ABLCodeFreeCallback(codeBuffer);
  780. codeBuffer = NULL;
  781. }
  782. if (stack) {
  783. ABLStackFreeCallback(stack);
  784. stack = NULL;
  785. }
  786. if (debugger) {
  787. delete debugger;
  788. debugger = NULL;
  789. }
  790. ABL_CloseProfileLog();
  791. ABLenabled = false;
  792. }
  793. //***************************************************************************
  794. ABLModulePtr ABLi_loadLibrary (char* sourceFileName, long* numErrors, long* numLinesProcessed, long* numFilesProcessed, bool printLines, bool createInstance) {
  795. //--------------------------------------------------------------------
  796. // Create an instance of it so it may be used from other modules. Note
  797. // that we need this when preprocessing since all identifiers in the
  798. // library should point to this module...
  799. ABLModulePtr library = new ABLModule;
  800. if (!library)
  801. ABL_Fatal(0, "ABL: no RAM for library");
  802. CurLibrary = library;
  803. //-------------------------------------------------------------
  804. // Preprocess the library. Note that a library should be loaded
  805. // just once.
  806. long libraryHandle = ABLi_preProcess(sourceFileName, numErrors, numLinesProcessed, numFilesProcessed, printLines);
  807. if (libraryHandle < (NumModulesRegistered - 1)) {
  808. //------------------
  809. // Already loaded...
  810. delete library;
  811. library = NULL;
  812. CurLibrary = NULL;
  813. return(NULL);
  814. }
  815. CurLibrary = NULL;
  816. LibraryInstanceRegistry[numLibrariesLoaded] = library;
  817. numLibrariesLoaded++;
  818. if (!createInstance) {
  819. CurLibrary = NULL;
  820. return(library);
  821. }
  822. long err = library->init(libraryHandle);
  823. ABL_Assert(err == ABL_NO_ERR, err, " Error Loading ABL Library ");
  824. library->setName(sourceFileName);
  825. return(library);
  826. }
  827. //***************************************************************************
  828. ABLParamPtr ABLi_createParamList (long numParameters) {
  829. if (numParameters) {
  830. ABLParamPtr paramList = (ABLParamPtr)ABLStackMallocCallback(sizeof(ABLParam) * (numParameters + 1));
  831. if (!paramList)
  832. ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc paramList ");
  833. memset(paramList, 0, sizeof(ABLParam) * (numParameters + 1));
  834. return(paramList);
  835. }
  836. return(NULL);
  837. }
  838. //***************************************************************************
  839. void ABLi_setIntegerParam (ABLParamPtr paramList, long index, long value) {
  840. if (paramList) {
  841. paramList[index].type = ABL_PARAM_INTEGER;
  842. paramList[index].integer = value;
  843. }
  844. }
  845. //***************************************************************************
  846. void ABLi_setRealParam (ABLParamPtr paramList, long index, float value) {
  847. if (paramList) {
  848. paramList[index].type = ABL_PARAM_REAL;
  849. paramList[index].real = value;
  850. }
  851. }
  852. //***************************************************************************
  853. void ABLi_deleteParamList (ABLParamPtr paramList) {
  854. if (paramList)
  855. ABLStackFreeCallback(paramList);
  856. }
  857. //***************************************************************************
  858. ABLModulePtr ABLi_getModule (long id) {
  859. if ((id >= 0) && (id < NumModules))
  860. return(ModuleInstanceRegistry[id]);
  861. return(NULL);
  862. }
  863. //***************************************************************************
  864. bool ABLi_enabled (void) {
  865. return(ABLenabled);
  866. }
  867. //***************************************************************************
  868. void ABLi_addFunction (char* name,
  869. bool isOrder,
  870. char* paramList,
  871. char* returnType,
  872. void (*codeCallback)(void)) {
  873. enterStandardRoutine(name, -1, isOrder, paramList, returnType, codeCallback);
  874. }
  875. //***************************************************************************
  876. long ABLi_registerInteger (char* name, long* address, long numElements) {
  877. if (strlen(name) >= MAXLEN_TOKENSTRING)
  878. ABL_Fatal(0, " ABLi_registerInteger: variable name too long ");
  879. level = 0;
  880. strcpy(wordString, name);
  881. SymTableNodePtr idPtr = NULL;
  882. searchAndEnterThisTable (idPtr, SymTableDisplay[0]);
  883. if (numElements == 1) {
  884. idPtr->library = NULL;
  885. idPtr->defn.key = DFN_VAR;
  886. idPtr->labelIndex = 0;
  887. idPtr->typePtr = setType(IntegerTypePtr);
  888. idPtr->defn.info.data.varType = VAR_TYPE_REGISTERED;
  889. idPtr->defn.info.data.registeredData = address;
  890. }
  891. return(ABL_NO_ERR);
  892. }
  893. //***************************************************************************
  894. long ABLi_registerReal (char* name, float* address, long numElements) {
  895. if (strlen(name) >= MAXLEN_TOKENSTRING)
  896. ABL_Fatal(0, " ABLi_registerInteger: variable name too long ");
  897. level = 0;
  898. strcpy(wordString, name);
  899. SymTableNodePtr idPtr = NULL;
  900. searchAndEnterThisTable (idPtr, SymTableDisplay[0]);
  901. idPtr->library = NULL;
  902. idPtr->defn.key = DFN_VAR;
  903. idPtr->labelIndex = 0;
  904. idPtr->typePtr = setType(RealTypePtr);
  905. idPtr->defn.info.data.varType = VAR_TYPE_REGISTERED;
  906. idPtr->defn.info.data.registeredData = address;
  907. return(ABL_NO_ERR);
  908. }
  909. //***************************************************************************
  910. bool ABLi_getSkipOrder (void) {
  911. return(SkipOrder);
  912. }
  913. //***************************************************************************
  914. void ABLi_resetOrders (void) {
  915. CurModule->resetOrderCallFlags();
  916. }
  917. //***************************************************************************
  918. long ABLi_getCurrentState (void) {
  919. if (CurFSM)
  920. return(CurFSM->getStateHandle());
  921. return(NULL);
  922. }
  923. //***************************************************************************
  924. void ABLi_transState (long newStateHandle) {
  925. if (CurFSM && (newStateHandle > 0) && (newStateHandle < ModuleRegistry[CurFSM->getHandle()].numStateHandles))
  926. transState(ModuleRegistry[CurFSM->getHandle()].stateHandles[newStateHandle].state);
  927. }
  928. //***************************************************************************
  929. // MODULE routines
  930. //***************************************************************************
  931. SymTableNodePtr moduleHeader (void) {
  932. SymTableNodePtr moduleIdPtr = NULL;
  933. bool isFSM = false;
  934. if (CurLibrary)
  935. ifTokenGetElseError(TKN_LIBRARY, ABL_ERR_SYNTAX_MISSING_LIBRARY);
  936. else if (curToken == TKN_FSM) {
  937. isFSM = true;
  938. getToken();
  939. }
  940. else
  941. ifTokenGetElseError(TKN_MODULE, ABL_ERR_SYNTAX_MISSING_MODULE);
  942. //------------------------------------------------------------
  943. // NOTE: If a module is a library, its library pointer will be
  944. // non-NULL.
  945. if (curToken == TKN_IDENTIFIER) {
  946. searchAndEnterLocalSymTable(moduleIdPtr);
  947. moduleIdPtr->defn.key = DFN_MODULE;
  948. moduleIdPtr->defn.info.routine.key = RTN_DECLARED;
  949. moduleIdPtr->defn.info.routine.flags = (isFSM ? ROUTINE_FLAG_FSM : 0);
  950. moduleIdPtr->defn.info.routine.orderCallIndex = 0;
  951. moduleIdPtr->defn.info.routine.numOrderCalls = 0;
  952. moduleIdPtr->defn.info.routine.paramCount = 0;
  953. moduleIdPtr->defn.info.routine.totalParamSize = 0;
  954. moduleIdPtr->defn.info.routine.totalLocalSize = 0;
  955. moduleIdPtr->defn.info.routine.params = NULL;
  956. moduleIdPtr->defn.info.routine.locals = NULL;
  957. moduleIdPtr->defn.info.routine.localSymTable = NULL;
  958. moduleIdPtr->defn.info.routine.codeSegment = NULL;
  959. moduleIdPtr->library = CurLibrary;
  960. moduleIdPtr->typePtr = &DummyType;
  961. moduleIdPtr->labelIndex = 0;
  962. getToken();
  963. }
  964. else
  965. syntaxError(ABL_ERR_SYNTAX_MISSING_IDENTIFIER);
  966. //--------------------------------------------
  967. // For now, modules do not have param lists...
  968. synchronize(followModuleIdList, declarationStartList, statementStartList);
  969. enterScope(NULL);
  970. if (curToken == TKN_LPAREN) {
  971. long paramCount;
  972. long totalParamSize;
  973. SymTableNodePtr paramListPtr = formalParamList(&paramCount, &totalParamSize);
  974. //if (forwardFlag)
  975. // syntaxError(ABL_ERR_SYNTAX_ALREADY_FORWARDED);
  976. //else {
  977. moduleIdPtr->defn.info.routine.paramCount = (unsigned char)paramCount;
  978. moduleIdPtr->defn.info.routine.totalParamSize = (unsigned char)totalParamSize;
  979. moduleIdPtr->defn.info.routine.params = paramListPtr;
  980. //}
  981. }
  982. //else if (!forwardFlag) {
  983. // functionIdPtr->defn.info.routine.paramCount = 0;
  984. // functionIdPtr->defn.info.routine.totalParamSize = 0;
  985. // functionIdPtr->defn.info.routine.params = NULL;
  986. //}
  987. //-----------------------------
  988. // Now, check if return type...
  989. moduleIdPtr->typePtr = NULL;
  990. SymTableNodePtr typeIdPtr = NULL;
  991. if (curToken == TKN_COLON) {
  992. getToken();
  993. if (curToken == TKN_IDENTIFIER) {
  994. searchAndFindAllSymTables(typeIdPtr);
  995. if (typeIdPtr->defn.key != DFN_TYPE)
  996. syntaxError(ABL_ERR_SYNTAX_INVALID_TYPE);
  997. //if (!forwardFlag)
  998. moduleIdPtr->typePtr = typeIdPtr->typePtr;
  999. getToken();
  1000. }
  1001. else {
  1002. syntaxError(ABL_ERR_SYNTAX_MISSING_IDENTIFIER);
  1003. moduleIdPtr->typePtr = &DummyType;
  1004. }
  1005. //if (forwardFlag)
  1006. // syntaxError(ABL_ERR_SYNTAX_ALREADY_FORWARDED);
  1007. }
  1008. return(moduleIdPtr);
  1009. }
  1010. //***************************************************************************
  1011. // ROUTINE/FUNCTION routines
  1012. //***************************************************************************
  1013. void routine (void) {
  1014. SymTableNodePtr routineIdPtr = NULL;
  1015. //------------------------------------------------------------------------
  1016. // Do we want to have "procedures", or do functions handle both cases (with
  1017. // and without return values)? For now, functions handle both...
  1018. routineIdPtr = functionHeader();
  1019. //------------------------------------------------------------------
  1020. // We need to save a pointer to the current routine we're parsing...
  1021. SymTableNodePtr prevRoutineIdPtr = CurRoutineIdPtr;
  1022. CurRoutineIdPtr = routineIdPtr;
  1023. //---------------------
  1024. // Error synchronize...
  1025. synchronize(followHeaderList, declarationStartList, statementStartList);
  1026. if (curToken == TKN_SEMICOLON)
  1027. getToken();
  1028. else if (tokenIn(declarationStartList) || tokenIn(statementStartList))
  1029. syntaxError(ABL_ERR_SYNTAX_MISSING_SEMICOLON);
  1030. if (strcmp(wordString, "forward") != 0) {
  1031. routineIdPtr->defn.info.routine.key = RTN_DECLARED;
  1032. //analyzeRoutineHeader(routineIdPtr);
  1033. routineIdPtr->defn.info.routine.locals = NULL;
  1034. declarations(routineIdPtr, false);
  1035. synchronize(followRoutineDeclsList, NULL, NULL);
  1036. if (curToken != TKN_CODE)
  1037. syntaxError(ABL_ERR_SYNTAX_MISSING_CODE);
  1038. crunchToken();
  1039. blockType = BLOCK_ROUTINE;
  1040. blockFlag = true;
  1041. routineIdPtr->defn.info.routine.orderCallIndex = (unsigned short)NumOrderCalls;
  1042. //compoundStatement();
  1043. getToken();
  1044. TokenCodeType endToken = TKN_END_FUNCTION;
  1045. if (routineIdPtr->defn.info.routine.flags & ROUTINE_FLAG_STATE)
  1046. endToken = TKN_END_STATE;
  1047. else if (routineIdPtr->defn.info.routine.flags & ROUTINE_FLAG_ORDER)
  1048. endToken = TKN_END_ORDER;
  1049. if (curToken != endToken)
  1050. do {
  1051. statement();
  1052. while (curToken == TKN_SEMICOLON)
  1053. getToken();
  1054. if (curToken == endToken)
  1055. break;
  1056. //------------------------------------
  1057. // Synchronize after possible error...
  1058. synchronize(statementStartList, NULL, NULL);
  1059. } while (tokenIn(statementStartList));
  1060. ifTokenGetElseError(endToken, ABL_ERR_SYNTAX_MISSING_END_FUNCTION);
  1061. blockFlag = false;
  1062. routineIdPtr->defn.info.routine.numOrderCalls = (unsigned short)NumOrderCalls - routineIdPtr->defn.info.routine.orderCallIndex;
  1063. routineIdPtr->defn.info.routine.codeSegment = createCodeSegment(routineIdPtr->defn.info.routine.codeSegmentSize);
  1064. analyzeBlock(routineIdPtr->defn.info.routine.codeSegment);
  1065. }
  1066. else {
  1067. getToken();
  1068. routineIdPtr->defn.info.routine.key = RTN_FORWARD;
  1069. analyzeRoutineHeader(routineIdPtr);
  1070. }
  1071. if (routineIdPtr->defn.info.routine.flags & ROUTINE_FLAG_STATE) {
  1072. //-----------------------------------
  1073. // Add it to the state handle list...
  1074. if (NumStateHandles == MAX_STATE_HANDLES_PER_MODULE)
  1075. ABL_Fatal(0, "ABL: too many states in fsm [19 max]");
  1076. strcpy(StateHandleList[NumStateHandles].name, routineIdPtr->name);
  1077. StateHandleList[NumStateHandles].state = routineIdPtr;
  1078. NumStateHandles++;
  1079. }
  1080. routineIdPtr->defn.info.routine.localSymTable = exitScope();
  1081. CurRoutineIdPtr = prevRoutineIdPtr;
  1082. }
  1083. //***************************************************************************
  1084. SymTableNodePtr forwardState (char* stateName) {
  1085. SymTableNodePtr stateSymbol = searchSymTableForState(stateName, SymTableDisplay[1]);
  1086. if (stateSymbol)
  1087. ABL_Fatal(0, " ABL.forwardState: State symbol should not exist ");
  1088. stateSymbol = enterSymTable(stateName, &SymTableDisplay[1]);
  1089. stateSymbol->defn.key = DFN_FUNCTION;
  1090. stateSymbol->defn.info.routine.key = RTN_FORWARD;
  1091. stateSymbol->defn.info.routine.paramCount = 0;
  1092. stateSymbol->defn.info.routine.flags = ROUTINE_FLAG_STATE;
  1093. stateSymbol->defn.info.routine.orderCallIndex = 0;
  1094. stateSymbol->defn.info.routine.numOrderCalls = 0;
  1095. stateSymbol->defn.info.routine.totalParamSize = 0;
  1096. stateSymbol->defn.info.routine.totalLocalSize = 0;
  1097. stateSymbol->defn.info.routine.params = NULL;
  1098. stateSymbol->defn.info.routine.locals = NULL;
  1099. stateSymbol->defn.info.routine.localSymTable = NULL;
  1100. stateSymbol->defn.info.routine.codeSegment = NULL;
  1101. stateSymbol->library = CurLibrary;
  1102. stateSymbol->typePtr = NULL;
  1103. stateSymbol->labelIndex = 0;
  1104. //-------------------
  1105. // Force the level...
  1106. stateSymbol->level = 1;
  1107. return(stateSymbol);
  1108. }
  1109. //***************************************************************************
  1110. SymTableNodePtr functionHeader (void) {
  1111. bool isState = false;
  1112. bool isOrder = false;
  1113. if (curToken == TKN_STATE)
  1114. isState = true;
  1115. else if (curToken == TKN_ORDER)
  1116. isOrder = true;
  1117. getToken();
  1118. SymTableNodePtr functionIdPtr = NULL;
  1119. SymTableNodePtr typeIdPtr = NULL;
  1120. bool forwardFlag = false;
  1121. if (curToken == TKN_IDENTIFIER) {
  1122. functionIdPtr = searchSymTableForFunction(wordString, SymTableDisplay[level]);
  1123. if (!functionIdPtr) {
  1124. enterLocalSymTable(functionIdPtr);
  1125. functionIdPtr->defn.key = DFN_FUNCTION;
  1126. functionIdPtr->defn.info.routine.key = RTN_DECLARED;
  1127. functionIdPtr->defn.info.routine.paramCount = 0;
  1128. functionIdPtr->defn.info.routine.flags = 0;
  1129. functionIdPtr->defn.info.routine.orderCallIndex = 0;
  1130. functionIdPtr->defn.info.routine.numOrderCalls = 0;
  1131. functionIdPtr->defn.info.routine.totalParamSize = 0;
  1132. functionIdPtr->defn.info.routine.totalLocalSize = 0;
  1133. functionIdPtr->defn.info.routine.params = NULL;
  1134. functionIdPtr->defn.info.routine.locals = NULL;
  1135. functionIdPtr->defn.info.routine.localSymTable = NULL;
  1136. functionIdPtr->defn.info.routine.codeSegment = NULL;
  1137. if (isOrder)
  1138. functionIdPtr->defn.info.routine.flags |= ROUTINE_FLAG_ORDER;
  1139. if (isState)
  1140. functionIdPtr->defn.info.routine.flags |= ROUTINE_FLAG_STATE;
  1141. functionIdPtr->library = CurLibrary;
  1142. functionIdPtr->typePtr = &DummyType;
  1143. functionIdPtr->labelIndex = 0;
  1144. }
  1145. else if ((functionIdPtr->defn.key == DFN_FUNCTION) &&
  1146. (functionIdPtr->defn.info.routine.key == RTN_FORWARD))
  1147. forwardFlag = true;
  1148. else
  1149. syntaxError(ABL_ERR_SYNTAX_REDEFINED_IDENTIFIER);
  1150. getToken();
  1151. }
  1152. //---------------------
  1153. // Error synchronize...
  1154. synchronize(followFunctionIdList, declarationStartList, statementStartList);
  1155. enterScope(NULL);
  1156. if (curToken == TKN_LPAREN) {
  1157. long paramCount;
  1158. long totalParamSize;
  1159. SymTableNodePtr paramListPtr = formalParamList(&paramCount, &totalParamSize);
  1160. if (forwardFlag)
  1161. syntaxError(ABL_ERR_SYNTAX_ALREADY_FORWARDED);
  1162. else {
  1163. functionIdPtr->defn.info.routine.paramCount = (unsigned char)paramCount;
  1164. functionIdPtr->defn.info.routine.totalParamSize = (unsigned char)totalParamSize;
  1165. functionIdPtr->defn.info.routine.params = paramListPtr;
  1166. }
  1167. }
  1168. else if (!forwardFlag) {
  1169. functionIdPtr->defn.info.routine.paramCount = 0;
  1170. functionIdPtr->defn.info.routine.totalParamSize = 0;
  1171. functionIdPtr->defn.info.routine.params = NULL;
  1172. }
  1173. //--------------------------------------------
  1174. // Now, check if return type and/or forward...
  1175. functionIdPtr->typePtr = NULL;
  1176. bool hasIntegerReturnValue = false;
  1177. if (curToken == TKN_COLON) {
  1178. getToken();
  1179. if (curToken == TKN_IDENTIFIER) {
  1180. searchAndFindAllSymTables(typeIdPtr);
  1181. if (typeIdPtr->defn.key != DFN_TYPE)
  1182. syntaxError(ABL_ERR_SYNTAX_INVALID_TYPE);
  1183. hasIntegerReturnValue = (typeIdPtr->typePtr == IntegerTypePtr);
  1184. if (!forwardFlag)
  1185. functionIdPtr->typePtr = typeIdPtr->typePtr;
  1186. getToken();
  1187. }
  1188. else {
  1189. syntaxError(ABL_ERR_SYNTAX_MISSING_IDENTIFIER);
  1190. functionIdPtr->typePtr = &DummyType;
  1191. }
  1192. if (forwardFlag)
  1193. syntaxError(ABL_ERR_SYNTAX_ALREADY_FORWARDED);
  1194. }
  1195. if (isOrder && !hasIntegerReturnValue)
  1196. syntaxError(ABL_ERR_SYNTAX_ORDER_RETURNTYPE);
  1197. return(functionIdPtr);
  1198. }
  1199. //***************************************************************************
  1200. SymTableNodePtr formalParamList (long* count, long* totalSize) {
  1201. SymTableNodePtr paramIdPtr;
  1202. SymTableNodePtr firstIdPtr;
  1203. SymTableNodePtr lastIdPtr = NULL;
  1204. SymTableNodePtr paramListPtr = NULL;
  1205. SymTableNodePtr typeIdPtr;
  1206. TypePtr paramTypePtr;
  1207. DefinitionType paramDefn;
  1208. long paramCount = 0;
  1209. long paramOffset = STACK_FRAME_HEADER_SIZE;
  1210. getToken();
  1211. while ((curToken == TKN_IDENTIFIER) || (curToken == TKN_REF)) {
  1212. firstIdPtr = NULL;
  1213. if (curToken == TKN_REF) {
  1214. paramDefn = DFN_REFPARAM;
  1215. getToken();
  1216. }
  1217. else
  1218. paramDefn = DFN_VALPARAM;
  1219. //-----------------------------------
  1220. // Grab the type of this parameter...
  1221. if (curToken == TKN_IDENTIFIER) {
  1222. searchAndFindAllSymTables(typeIdPtr);
  1223. if (typeIdPtr->defn.key != DFN_TYPE)
  1224. syntaxError(ABL_ERR_SYNTAX_INVALID_TYPE);
  1225. paramTypePtr = (TypePtr)(typeIdPtr->typePtr);
  1226. getToken();
  1227. }
  1228. else {
  1229. syntaxError(ABL_ERR_SYNTAX_MISSING_IDENTIFIER);
  1230. paramTypePtr = &DummyType;
  1231. }
  1232. //------------------------------------------------------------
  1233. // Is this an array parameter? If so, parse the dimensions and
  1234. // whether it's an open array...
  1235. if (curToken == TKN_LBRACKET) {
  1236. }
  1237. //-----------------------------------------------
  1238. // Now grab the variable id for this parameter...
  1239. if (curToken == TKN_IDENTIFIER) {
  1240. searchAndEnterLocalSymTable(paramIdPtr);
  1241. paramIdPtr->defn.key = paramDefn;
  1242. paramIdPtr->labelIndex = 0;
  1243. paramIdPtr->typePtr = paramTypePtr;
  1244. paramIdPtr->defn.info.data.offset = paramOffset++;
  1245. paramCount++;
  1246. if (paramListPtr == NULL)
  1247. paramListPtr = paramIdPtr;
  1248. if (lastIdPtr != NULL)
  1249. lastIdPtr->next = paramIdPtr;
  1250. lastIdPtr = paramIdPtr;
  1251. //if (firstIdPtr == NULL)
  1252. // firstIdPtr = lastIdPtr = paramIdPtr;
  1253. //else {
  1254. // lastIdPtr->next = paramIdPtr;
  1255. // lastIdPtr = paramIdPtr;
  1256. //}
  1257. getToken();
  1258. //ifTokenGet(TKN_COMMA);
  1259. }
  1260. else {
  1261. syntaxError(ABL_ERR_SYNTAX_MISSING_IDENTIFIER);
  1262. //--------------------------------
  1263. // Do we need to synchronize here?
  1264. }
  1265. //------------------------------------------------------------------
  1266. // Assign the offset and the type to all param ids in the sublist...
  1267. //for (paramIdPtr = firstIdPtr; paramIdPtr != NULL; paramIdPtr = paramIdPtr->next) {
  1268. // paramIdPtr->typePtr = paramTypePtr;
  1269. // paramIdPtr->defn.info.data.offset = paramOffset++;
  1270. //}
  1271. //-----------------------------------------------
  1272. // Link this list to the list of all param ids...
  1273. //if (prevLastIdPtr != NULL)
  1274. // prevLastIdPtr->next = firstIdPtr;
  1275. //prevLastIdPtr = lastIdPtr;
  1276. //-------------------------------
  1277. // Error synch... should be ; or )
  1278. synchronize(followParamsList, NULL, NULL);
  1279. ifTokenGet(TKN_COMMA);
  1280. }
  1281. ifTokenGetElseError(TKN_RPAREN, ABL_ERR_SYNTAX_MISSING_RPAREN);
  1282. *count = paramCount;
  1283. *totalSize = paramOffset - STACK_FRAME_HEADER_SIZE;
  1284. if (paramCount > 255)
  1285. syntaxError(ABL_ERR_SYNTAX_TOO_MANY_FORMAL_PARAMETERS);
  1286. return(paramListPtr);
  1287. }
  1288. //***************************************************************************
  1289. TypePtr routineCall (SymTableNodePtr routineIdPtr, long paramCheckFlag) {
  1290. SymTableNodePtr thisRoutineIdPtr = CurRoutineIdPtr;
  1291. TypePtr resultType = NULL;
  1292. if ((routineIdPtr->defn.info.routine.key == RTN_DECLARED) ||
  1293. (routineIdPtr->defn.info.routine.key == RTN_FORWARD) ||
  1294. !paramCheckFlag)
  1295. resultType = declaredRoutineCall(routineIdPtr, paramCheckFlag);
  1296. else
  1297. resultType = standardRoutineCall(routineIdPtr);
  1298. CurRoutineIdPtr = thisRoutineIdPtr;
  1299. return(resultType);
  1300. }
  1301. //***************************************************************************
  1302. TypePtr declaredRoutineCall (SymTableNodePtr routineIdPtr, long paramCheckFlag) {
  1303. actualParamList(routineIdPtr, paramCheckFlag);
  1304. return(/*routineIdPtr->defn.key == DFN_PROCEDURE ? NULL :*/ (TypePtr)(routineIdPtr->typePtr));
  1305. }
  1306. //***************************************************************************
  1307. void actualParamList (SymTableNodePtr routineIdPtr, long paramCheckFlag) {
  1308. SymTableNodePtr formalParamIdPtr = NULL;
  1309. DefinitionType formalParamDefn = (DefinitionType)0;
  1310. TypePtr formalParamTypePtr = NULL;
  1311. TypePtr actualParamTypePtr = NULL;
  1312. if (paramCheckFlag)
  1313. formalParamIdPtr = (SymTableNodePtr)(routineIdPtr->defn.info.routine.params);
  1314. if (curToken == TKN_LPAREN) {
  1315. //-----------------------------------------------
  1316. // Loop to process actual parameter expression...
  1317. do {
  1318. //----------------------------------------------------
  1319. // Obtain info about the corresponding formal param...
  1320. if (paramCheckFlag && (formalParamIdPtr != NULL)) {
  1321. formalParamDefn = formalParamIdPtr->defn.key;
  1322. formalParamTypePtr = (TypePtr)(formalParamIdPtr->typePtr);
  1323. }
  1324. getToken();
  1325. if ((formalParamIdPtr == NULL) || (formalParamDefn == DFN_VALPARAM) || !paramCheckFlag) {
  1326. //--------------
  1327. // VAL Params...
  1328. actualParamTypePtr = expression();
  1329. if (paramCheckFlag && (formalParamIdPtr != NULL) && !isAssignTypeCompatible(formalParamTypePtr, actualParamTypePtr))
  1330. syntaxError(ABL_ERR_SYNTAX_INCOMPATIBLE_TYPES);
  1331. }
  1332. else {
  1333. //--------------
  1334. // VAR params...
  1335. if (curToken == TKN_IDENTIFIER) {
  1336. SymTableNodePtr idPtr;
  1337. searchAndFindAllSymTables(idPtr);
  1338. actualParamTypePtr = variable(idPtr);
  1339. if (formalParamTypePtr != actualParamTypePtr)
  1340. syntaxError(ABL_ERR_SYNTAX_INCOMPATIBLE_TYPES);
  1341. }
  1342. else {
  1343. //------------------------------------------------------------------
  1344. // Not a variable--parse the expression anyway for error recovery...
  1345. actualParamTypePtr = expression();
  1346. syntaxError(ABL_ERR_SYNTAX_INVALID_REF_PARAM);
  1347. }
  1348. }
  1349. //---------------------------------------
  1350. // More actual params than formal params?
  1351. if (paramCheckFlag) {
  1352. if (formalParamIdPtr == NULL)
  1353. syntaxError(ABL_ERR_SYNTAX_WRONG_NUMBER_OF_PARAMS);
  1354. else
  1355. formalParamIdPtr = formalParamIdPtr->next;
  1356. }
  1357. //---------------
  1358. // Error synch...
  1359. synchronize(followParamList, statementEndList, NULL);
  1360. } while (curToken == TKN_COMMA);
  1361. ifTokenGetElseError(TKN_RPAREN, ABL_ERR_SYNTAX_MISSING_RPAREN);
  1362. }
  1363. //----------------------------------------
  1364. // Fewer actual params than formal params?
  1365. if (paramCheckFlag && (formalParamIdPtr != NULL))
  1366. syntaxError(ABL_ERR_SYNTAX_WRONG_NUMBER_OF_PARAMS);
  1367. }
  1368. //***************************************************************************
  1369. extern char SetStateDebugStr[256];
  1370. void transState (SymTableNodePtr newState) {
  1371. if (CurFSM) {
  1372. CurFSM->setPrevState(CurFSM->getState());
  1373. CurFSM->setState(newState);
  1374. sprintf(SetStateDebugStr, "%s:%s, line %d", CurModule->getFileName(), newState->name, execLineNumber);
  1375. NewStateSet = true;
  1376. }
  1377. }
  1378. //***************************************************************************