Abldecl.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. //===========================================================================//
  2. // Copyright (C) Microsoft Corporation. All rights reserved. //
  3. //===========================================================================//
  4. //***************************************************************************
  5. //
  6. // ABLDECL.CPP
  7. //
  8. //***************************************************************************
  9. #include <string.h>
  10. #include <stdio.h>
  11. #include <stdlib.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. //***************************************************************************
  31. extern TokenCodeType curToken;
  32. extern char wordString[];
  33. extern Literal curLiteral;
  34. extern SymTableNodePtr SymTableDisplay[];
  35. extern long level;
  36. extern TypePtr IntegerTypePtr;
  37. extern TypePtr CharTypePtr;
  38. extern TypePtr RealTypePtr;
  39. extern TypePtr BooleanTypePtr;
  40. extern TokenCodeType declarationStartList[];
  41. extern TokenCodeType statementStartList[];
  42. extern long eternalOffset;
  43. extern long NumStaticVariables;
  44. extern long MaxStaticVariables;
  45. extern long* StaticVariablesSizes;
  46. extern long* EternalVariablesSizes;
  47. extern ABLModulePtr CurLibrary;
  48. //***************************************************************************
  49. TokenCodeType followRoutineList[] = {
  50. TKN_SEMICOLON,
  51. TKN_EOF,
  52. TKN_NONE
  53. };
  54. TokenCodeType followDeclarationList[] = {
  55. TKN_SEMICOLON,
  56. TKN_IDENTIFIER,
  57. TKN_EOF,
  58. TKN_NONE
  59. };
  60. TokenCodeType followVariablesList[] = {
  61. TKN_SEMICOLON,
  62. TKN_IDENTIFIER,
  63. TKN_EOF,
  64. TKN_NONE
  65. };
  66. TokenCodeType followVarBlockList[] = {
  67. TKN_FUNCTION,
  68. TKN_ORDER,
  69. TKN_STATE,
  70. TKN_CODE,
  71. TKN_EOF,
  72. TKN_NONE
  73. };
  74. TokenCodeType followDimensionList[] = {
  75. TKN_COMMA,
  76. TKN_RBRACKET,
  77. TKN_EOF,
  78. TKN_NONE
  79. };
  80. TokenCodeType indexTypeStartList[] = {
  81. TKN_IDENTIFIER,
  82. TKN_NUMBER,
  83. TKN_NONE
  84. };
  85. TokenCodeType followIndexesList[] = {
  86. TKN_OF,
  87. TKN_IDENTIFIER,
  88. TKN_LPAREN,
  89. TKN_PLUS,
  90. TKN_MINUS,
  91. TKN_NUMBER,
  92. TKN_SEMICOLON,
  93. TKN_EOF,
  94. TKN_NONE
  95. };
  96. //***************************************************************************
  97. // MISC. routines
  98. //***************************************************************************
  99. void ifTokenGet(TokenCodeType tokenCode) {
  100. if (curToken == tokenCode)
  101. getToken();
  102. }
  103. //***************************************************************************
  104. void ifTokenGetElseError (TokenCodeType tokenCode, SyntaxErrorType errorCode) {
  105. if (curToken == tokenCode)
  106. getToken();
  107. else
  108. syntaxError(errorCode);
  109. }
  110. //***************************************************************************
  111. // DECLARATIONS routines
  112. //***************************************************************************
  113. void declarations (SymTableNodePtr routineIdPtr, bool allowFunctions) {
  114. if (curToken == TKN_CONST) {
  115. getToken();
  116. constDefinitions();
  117. }
  118. if (curToken == TKN_TYPE) {
  119. getToken();
  120. typeDefinitions();
  121. }
  122. if (curToken == TKN_VAR) {
  123. getToken();
  124. varDeclarations(routineIdPtr);
  125. }
  126. //---------------------------------------------------
  127. // Loop to process all of the function definitions...
  128. if (allowFunctions)
  129. while ((curToken == TKN_FUNCTION) || (curToken == TKN_ORDER) || (curToken == TKN_STATE)){
  130. routine();
  131. //---------------------
  132. // Error synchronize...
  133. synchronize(followRoutineList, declarationStartList, statementStartList);
  134. if (curToken == TKN_SEMICOLON)
  135. getToken();
  136. else if (tokenIn(declarationStartList) || tokenIn(statementStartList))
  137. syntaxError(ABL_ERR_SYNTAX_MISSING_SEMICOLON);
  138. }
  139. else if ((curToken == TKN_FUNCTION) || (curToken == TKN_ORDER) || (curToken == TKN_STATE))
  140. syntaxError(ABL_ERR_SYNTAX_NO_FUNCTION_NESTING);
  141. }
  142. //***************************************************************************
  143. // CONST routines
  144. //***************************************************************************
  145. void constDefinitions (void) {
  146. //-------------------------------------------------------
  147. // Loop to process definitions separated by semicolons...
  148. while (curToken == TKN_IDENTIFIER) {
  149. SymTableNodePtr constantIdPtr;
  150. searchAndEnterLocalSymTable(constantIdPtr);
  151. constantIdPtr->defn.key = DFN_CONST;
  152. constantIdPtr->library = CurLibrary;
  153. getToken();
  154. ifTokenGetElseError(TKN_EQUAL, ABL_ERR_SYNTAX_MISSING_EQUAL);
  155. doConst(constantIdPtr);
  156. analyzeConstDefn(constantIdPtr);
  157. //---------------------------------
  158. // Error synchronize: should be a ;
  159. synchronize(followDeclarationList, declarationStartList, statementStartList);
  160. if (curToken == TKN_SEMICOLON)
  161. getToken();
  162. else if (tokenIn(declarationStartList) || tokenIn(statementStartList))
  163. syntaxError(ABL_ERR_SYNTAX_MISSING_SEMICOLON);
  164. }
  165. }
  166. //***************************************************************************
  167. TypePtr makeStringType (long length) {
  168. TypePtr stringTypePtr = createType();
  169. if (!stringTypePtr)
  170. ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc stringType ");
  171. stringTypePtr->form = FRM_ARRAY;
  172. stringTypePtr->size = length;
  173. stringTypePtr->typeIdPtr = NULL;
  174. stringTypePtr->info.array.indexTypePtr = IntegerTypePtr;
  175. stringTypePtr->info.array.elementTypePtr = CharTypePtr;
  176. stringTypePtr->info.array.elementCount = length + 1;
  177. return(stringTypePtr);
  178. }
  179. //***************************************************************************
  180. void doConst (SymTableNodePtr constantIdPtr) {
  181. TokenCodeType sign = TKN_PLUS;
  182. bool sawSign = false;
  183. if ((curToken == TKN_PLUS) || (curToken == TKN_MINUS)) {
  184. sign = curToken;
  185. sawSign = true;
  186. getToken();
  187. }
  188. //----------------------------------
  189. // Numeric constant: real or integer
  190. if (curToken == TKN_NUMBER) {
  191. if (curLiteral.type == LIT_INTEGER) {
  192. if (sign == TKN_PLUS)
  193. constantIdPtr->defn.info.constant.value.integer = curLiteral.value.integer;
  194. else
  195. constantIdPtr->defn.info.constant.value.integer = -(curLiteral.value.integer);
  196. constantIdPtr->typePtr = setType(IntegerTypePtr);
  197. }
  198. else {
  199. if (sign == TKN_PLUS)
  200. constantIdPtr->defn.info.constant.value.real = curLiteral.value.real;
  201. else
  202. constantIdPtr->defn.info.constant.value.real = -(curLiteral.value.real);
  203. constantIdPtr->typePtr = setType(RealTypePtr);
  204. }
  205. }
  206. else if (curToken == TKN_IDENTIFIER) {
  207. SymTableNodePtr idPtr = NULL;
  208. searchAllSymTables(idPtr);
  209. if (!idPtr)
  210. syntaxError(ABL_ERR_SYNTAX_UNDEFINED_IDENTIFIER);
  211. else if (idPtr->defn.key != DFN_CONST)
  212. syntaxError(ABL_ERR_SYNTAX_NOT_A_CONSTANT_IDENTIFIER);
  213. else if (idPtr->typePtr == IntegerTypePtr) {
  214. if (sign == TKN_PLUS)
  215. constantIdPtr->defn.info.constant.value.integer = idPtr->defn.info.constant.value.integer;
  216. else
  217. constantIdPtr->defn.info.constant.value.integer = -(idPtr->defn.info.constant.value.integer);
  218. constantIdPtr->typePtr = setType(IntegerTypePtr);
  219. }
  220. else if (idPtr->typePtr == CharTypePtr) {
  221. if (sawSign)
  222. syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT);
  223. constantIdPtr->defn.info.constant.value.character = idPtr->defn.info.constant.value.character;
  224. constantIdPtr->typePtr = setType(CharTypePtr);
  225. }
  226. else if (idPtr->typePtr == RealTypePtr) {
  227. if (sign == TKN_PLUS)
  228. constantIdPtr->defn.info.constant.value.real = idPtr->defn.info.constant.value.real;
  229. else
  230. constantIdPtr->defn.info.constant.value.real = -(idPtr->defn.info.constant.value.real);
  231. constantIdPtr->typePtr = setType(RealTypePtr);
  232. }
  233. else if (((Type*)(idPtr->typePtr))->form == FRM_ENUM) {
  234. if (sawSign)
  235. syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT);
  236. constantIdPtr->defn.info.constant.value.integer = idPtr->defn.info.constant.value.integer;
  237. constantIdPtr->typePtr = setType(idPtr->typePtr);
  238. }
  239. else if (((TypePtr)(idPtr->typePtr))->form == FRM_ARRAY) {
  240. if (sawSign)
  241. syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT);
  242. constantIdPtr->defn.info.constant.value.stringPtr = idPtr->defn.info.constant.value.stringPtr;
  243. constantIdPtr->typePtr = setType(idPtr->typePtr);
  244. }
  245. }
  246. else if (curToken == TKN_STRING) {
  247. if (sawSign)
  248. syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT);
  249. if (strlen(curLiteral.value.string) == 1) {
  250. constantIdPtr->defn.info.constant.value.character = curLiteral.value.string[0];
  251. constantIdPtr->typePtr = setType(CharTypePtr);
  252. }
  253. else {
  254. long length = strlen(curLiteral.value.string);
  255. constantIdPtr->defn.info.constant.value.stringPtr = (char*)ABLSymbolMallocCallback(length + 1);
  256. if (!constantIdPtr->defn.info.constant.value.stringPtr)
  257. ABL_Fatal(0, " ABL: Unable to AblSymbolHeap->malloc array string constant ");
  258. strcpy(constantIdPtr->defn.info.constant.value.stringPtr, curLiteral.value.string);
  259. constantIdPtr->typePtr = makeStringType(length);
  260. }
  261. }
  262. else {
  263. constantIdPtr->typePtr = NULL;
  264. syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT);
  265. }
  266. getToken();
  267. }
  268. //***************************************************************************
  269. // TYPE routines
  270. //***************************************************************************
  271. //---------------------------------------------------------------------------
  272. // Need to implement type routines if we allow user-defined types, and/or the
  273. // PASCAL style array types (otherwise, arrays should be implemented in the
  274. // var routines...
  275. void typeDefinitions (void) {
  276. while (curToken == TKN_IDENTIFIER) {
  277. SymTableNodePtr typeIdPtr;
  278. searchAndEnterLocalSymTable(typeIdPtr);
  279. typeIdPtr->defn.key = DFN_TYPE;
  280. typeIdPtr->library = CurLibrary;
  281. getToken();
  282. ifTokenGetElseError(TKN_EQUAL, ABL_ERR_SYNTAX_MISSING_EQUAL);
  283. //----------------------------------
  284. // Process the type specification...
  285. typeIdPtr->typePtr = doType();
  286. if (typeIdPtr->typePtr->typeIdPtr == NULL)
  287. typeIdPtr->typePtr->typeIdPtr = typeIdPtr;
  288. analyzeTypeDefn(typeIdPtr);
  289. //---------------
  290. // Error synch...
  291. synchronize(followDeclarationList, declarationStartList, statementStartList);
  292. if (curToken == TKN_SEMICOLON)
  293. getToken();
  294. else if (tokenIn(declarationStartList) || tokenIn(statementStartList))
  295. syntaxError(ABL_ERR_SYNTAX_MISSING_SEMICOLON);
  296. }
  297. }
  298. //***************************************************************************
  299. TypePtr doType (void) {
  300. switch (curToken) {
  301. case TKN_IDENTIFIER: {
  302. SymTableNodePtr idPtr;
  303. searchAllSymTables(idPtr);
  304. if (!idPtr) {
  305. syntaxError(ABL_ERR_SYNTAX_UNDEFINED_IDENTIFIER);
  306. return(NULL);
  307. }
  308. else if (idPtr->defn.key == DFN_TYPE) {
  309. //----------------------------------------------------------
  310. // NOTE: Array types should be parsed in this case if a left
  311. // bracket follows the type identifier.
  312. TypePtr elementType = setType(identifierType(idPtr));
  313. if (curToken == TKN_LBRACKET) {
  314. //--------------
  315. // Array type...
  316. TypePtr typePtr = createType();
  317. if (!typePtr)
  318. ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc array type ");
  319. TypePtr elementTypePtr = typePtr;
  320. do {
  321. getToken();
  322. if (tokenIn(indexTypeStartList)) {
  323. elementTypePtr->form = FRM_ARRAY;
  324. elementTypePtr->size = 0;
  325. elementTypePtr->typeIdPtr = NULL;
  326. //----------------------------------------------
  327. // All array indices must be integer, for now...
  328. elementTypePtr->info.array.indexTypePtr = setType(IntegerTypePtr);
  329. //------------------------
  330. // Read the index count...
  331. switch (curToken) {
  332. case TKN_NUMBER:
  333. if (curLiteral.type == LIT_INTEGER)
  334. elementTypePtr->info.array.elementCount = curLiteral.value.integer;
  335. else {
  336. elementTypePtr->form = FRM_NONE;
  337. elementTypePtr->size = 0;
  338. elementTypePtr->typeIdPtr = NULL;
  339. elementTypePtr->info.array.indexTypePtr = NULL;
  340. syntaxError(ABL_ERR_SYNTAX_INVALID_INDEX_TYPE);
  341. }
  342. getToken();
  343. break;
  344. case TKN_IDENTIFIER: {
  345. SymTableNodePtr idPtr;
  346. searchAllSymTables(idPtr);
  347. if (idPtr == NULL)
  348. syntaxError(ABL_ERR_SYNTAX_UNDEFINED_IDENTIFIER);
  349. else if (idPtr->defn.key == DFN_CONST) {
  350. if (idPtr->typePtr == IntegerTypePtr)
  351. elementTypePtr->info.array.elementCount = idPtr->defn.info.constant.value.integer;
  352. else {
  353. elementTypePtr->form = FRM_NONE;
  354. elementTypePtr->size = 0;
  355. elementTypePtr->typeIdPtr = NULL;
  356. elementTypePtr->info.array.indexTypePtr = NULL;
  357. syntaxError(ABL_ERR_SYNTAX_INVALID_INDEX_TYPE);
  358. }
  359. }
  360. else {
  361. elementTypePtr->form = FRM_NONE;
  362. elementTypePtr->size = 0;
  363. elementTypePtr->typeIdPtr = NULL;
  364. elementTypePtr->info.array.indexTypePtr = NULL;
  365. syntaxError(ABL_ERR_SYNTAX_INVALID_INDEX_TYPE);
  366. }
  367. getToken();
  368. }
  369. break;
  370. default:
  371. elementTypePtr->form = FRM_NONE;
  372. elementTypePtr->size = 0;
  373. elementTypePtr->typeIdPtr = NULL;
  374. elementTypePtr->info.array.indexTypePtr = NULL;
  375. syntaxError(ABL_ERR_SYNTAX_INVALID_INDEX_TYPE);
  376. getToken();
  377. }
  378. }
  379. else {
  380. elementTypePtr->form = FRM_NONE;
  381. elementTypePtr->size = 0;
  382. elementTypePtr->typeIdPtr = NULL;
  383. elementTypePtr->info.array.indexTypePtr = NULL;
  384. syntaxError(ABL_ERR_SYNTAX_INVALID_INDEX_TYPE);
  385. getToken();
  386. }
  387. synchronize(followDimensionList, NULL, NULL);
  388. //--------------------------------
  389. // Create an array element type...
  390. if (curToken == TKN_COMMA) {
  391. elementTypePtr = elementTypePtr->info.array.elementTypePtr = createType();
  392. if (!elementTypePtr)
  393. ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc array element Type ");
  394. }
  395. } while (curToken == TKN_COMMA);
  396. ifTokenGetElseError(TKN_RBRACKET, ABL_ERR_SYNTAX_MISSING_RBRACKET);
  397. elementTypePtr->info.array.elementTypePtr = elementType;
  398. typePtr->size = arraySize(typePtr);
  399. elementType = typePtr;
  400. }
  401. return(elementType);
  402. }
  403. else {
  404. syntaxError(ABL_ERR_SYNTAX_NOT_A_TYPE_IDENTIFIER);
  405. return(NULL);
  406. }
  407. }
  408. break;
  409. case TKN_LPAREN:
  410. return(enumerationType());
  411. default:
  412. syntaxError(ABL_ERR_SYNTAX_INVALID_TYPE);
  413. return(NULL);
  414. }
  415. }
  416. //***************************************************************************
  417. TypePtr identifierType (SymTableNodePtr idPtr) {
  418. TypePtr typePtr = (TypePtr)idPtr->typePtr;
  419. getToken();
  420. return(typePtr);
  421. }
  422. //***************************************************************************
  423. TypePtr enumerationType (void) {
  424. SymTableNodePtr constantIdPtr = NULL;
  425. SymTableNodePtr lastIdPtr = NULL;
  426. TypePtr typePtr = createType();
  427. if (!typePtr)
  428. ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc enumeration type ");
  429. long constantValue = -1;
  430. typePtr->form = FRM_ENUM;
  431. typePtr->size = sizeof(long);
  432. typePtr->typeIdPtr = NULL;
  433. getToken();
  434. //------------------------------------------------------------
  435. // Process list of identifiers in this new enumeration type...
  436. while (curToken == TKN_IDENTIFIER) {
  437. searchAndEnterLocalSymTable(constantIdPtr);
  438. constantIdPtr->defn.key = DFN_CONST;
  439. constantIdPtr->defn.info.constant.value.integer = ++constantValue;
  440. constantIdPtr->typePtr = typePtr;
  441. constantIdPtr->library = CurLibrary;
  442. if (lastIdPtr == NULL)
  443. typePtr->info.enumeration.constIdPtr = lastIdPtr = constantIdPtr;
  444. else {
  445. lastIdPtr->next = constantIdPtr;
  446. lastIdPtr = constantIdPtr;
  447. }
  448. getToken();
  449. ifTokenGet(TKN_COMMA);
  450. }
  451. ifTokenGetElseError(TKN_RPAREN, ABL_ERR_SYNTAX_MISSING_RPAREN);
  452. typePtr->info.enumeration.max = constantValue;
  453. return(typePtr);
  454. }
  455. //***************************************************************************
  456. long arraySize (TypePtr typePtr) {
  457. if (typePtr->info.array.elementTypePtr->size == 0)
  458. typePtr->info.array.elementTypePtr->size = arraySize(typePtr->info.array.elementTypePtr);
  459. if (typePtr->info.array.elementCount == -1) {
  460. //--------------------------------------------------------------
  461. // Open array, so just return the size of its element. Remember,
  462. // open arrays must be open at the end...
  463. typePtr->size = typePtr->info.array.elementTypePtr->size;
  464. }
  465. else
  466. typePtr->size = typePtr->info.array.elementCount * typePtr->info.array.elementTypePtr->size;
  467. return(typePtr->size);
  468. }
  469. //***************************************************************************
  470. // VAR routines
  471. //***************************************************************************
  472. void varDeclarations (SymTableNodePtr routineIdPtr) {
  473. varOrFieldDeclarations(routineIdPtr,
  474. STACK_FRAME_HEADER_SIZE + routineIdPtr->defn.info.routine.paramCount);
  475. }
  476. //***************************************************************************
  477. void varOrFieldDeclarations (SymTableNodePtr routineIdPtr, long offset) {
  478. bool varFlag = (routineIdPtr != NULL);
  479. SymTableNodePtr idPtr = NULL;
  480. SymTableNodePtr firstIdPtr = NULL;
  481. SymTableNodePtr lastIdPtr = NULL;
  482. SymTableNodePtr prevLastIdPtr = NULL;
  483. long totalSize = 0;
  484. while ((curToken == TKN_IDENTIFIER) || (curToken == TKN_ETERNAL) || (curToken == TKN_STATIC)) {
  485. VariableType varType = VAR_TYPE_NORMAL;
  486. if ((curToken == TKN_ETERNAL) || (curToken == TKN_STATIC)) {
  487. if (curToken == TKN_ETERNAL)
  488. varType = VAR_TYPE_ETERNAL;
  489. else
  490. varType = VAR_TYPE_STATIC;
  491. getToken();
  492. if (curToken != TKN_IDENTIFIER)
  493. syntaxError(ABL_ERR_SYNTAX_MISSING_IDENTIFIER);
  494. }
  495. firstIdPtr = NULL;
  496. //------------------------------
  497. // Process the variable type...
  498. TypePtr typePtr = doType();
  499. //------------------------------------------------------------------
  500. // Since we haven't really assigned it here, decrement its
  501. // numInstances. Every variable in this list will set it properly...
  502. typePtr->numInstances--;
  503. long size = typePtr->size;
  504. //-------------------------------------------------------
  505. // Now that we've read the type, read in the variable (or
  506. // possibly list of variables) declared of this type.
  507. // Loop to process every variable (and field, if records
  508. // are being implemented:) in sublist...
  509. while (curToken == TKN_IDENTIFIER) {
  510. if (varFlag) {
  511. //---------------------------------------------
  512. // We're working with a variable declaration...
  513. if (varType == VAR_TYPE_ETERNAL) {
  514. long curLevel = level;
  515. level = 0;
  516. searchAndEnterThisTable (idPtr, SymTableDisplay[0]);
  517. level = curLevel;
  518. }
  519. else
  520. searchAndEnterLocalSymTable(idPtr);
  521. idPtr->library = CurLibrary;
  522. idPtr->defn.key = DFN_VAR;
  523. }
  524. else
  525. syntaxError(ABL_ERR_SYNTAX_NO_RECORD_TYPES);
  526. idPtr->labelIndex = 0;
  527. //------------------------------------------
  528. // Now, link Id's together into a sublist...
  529. if (!firstIdPtr) {
  530. firstIdPtr = lastIdPtr = idPtr;
  531. if (varFlag && (varType != VAR_TYPE_ETERNAL) && (routineIdPtr->defn.info.routine.locals == NULL))
  532. routineIdPtr->defn.info.routine.locals = idPtr;
  533. }
  534. else {
  535. lastIdPtr->next = idPtr;
  536. lastIdPtr = idPtr;
  537. }
  538. getToken();
  539. ifTokenGet(TKN_COMMA);
  540. }
  541. //--------------------------------------------------------------------------
  542. // Assign the offset and the type to all variable or field Ids in sublist...
  543. for (idPtr = firstIdPtr; idPtr != NULL; idPtr = idPtr->next) {
  544. idPtr->typePtr = setType(typePtr);
  545. if (varFlag) {
  546. idPtr->defn.info.data.varType = varType;
  547. switch (varType) {
  548. case VAR_TYPE_NORMAL:
  549. totalSize += size;
  550. idPtr->defn.info.data.offset = offset++;
  551. break;
  552. case VAR_TYPE_ETERNAL: {
  553. idPtr->defn.info.data.offset = eternalOffset;
  554. //-----------------------------------
  555. // Initialize the variable to zero...
  556. StackItemPtr dataPtr = (StackItemPtr)stack + eternalOffset;
  557. if (typePtr->form == FRM_ARRAY) {
  558. dataPtr->address = (Address)ABLStackMallocCallback((size_t)size);
  559. if (!dataPtr->address)
  560. ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc eternal array ");
  561. memset(dataPtr->address, 0, size);
  562. EternalVariablesSizes[eternalOffset] = size;
  563. }
  564. else {
  565. dataPtr->integer = 0;
  566. EternalVariablesSizes[eternalOffset] = 0;
  567. }
  568. eternalOffset++;
  569. }
  570. break;
  571. case VAR_TYPE_STATIC: {
  572. if (NumStaticVariables == MaxStaticVariables)
  573. syntaxError(ABL_ERR_SYNTAX_TOO_MANY_STATIC_VARS);
  574. idPtr->defn.info.data.offset = NumStaticVariables;
  575. if (typePtr->form == FRM_ARRAY)
  576. StaticVariablesSizes[NumStaticVariables] = size;
  577. else
  578. StaticVariablesSizes[NumStaticVariables] = 0;
  579. NumStaticVariables++;
  580. }
  581. break;
  582. }
  583. analyzeVarDecl(idPtr);
  584. }
  585. else {
  586. //----------------
  587. // record field...
  588. idPtr->defn.info.data.varType = VAR_TYPE_NORMAL;
  589. idPtr->defn.info.data.offset = offset;
  590. offset += size;
  591. }
  592. }
  593. //--------------------------------------------------
  594. // Now, link this sublist to the previous sublist...
  595. if (varType != VAR_TYPE_ETERNAL) {
  596. if (prevLastIdPtr != NULL)
  597. prevLastIdPtr->next = firstIdPtr;
  598. prevLastIdPtr = lastIdPtr;
  599. }
  600. //---------------------
  601. // Error synchronize...
  602. if (varFlag)
  603. synchronize(followVariablesList, declarationStartList, statementStartList);
  604. if (curToken == TKN_SEMICOLON)
  605. getToken();
  606. else if (varFlag && (tokenIn(declarationStartList) || tokenIn(statementStartList)))
  607. syntaxError(ABL_ERR_SYNTAX_MISSING_SEMICOLON);
  608. }
  609. synchronize(followVarBlockList, NULL, NULL);
  610. if (varFlag) {
  611. //----------------------------------------------------------------
  612. // If the following error occurs too frequently, simply make the
  613. // totalLocalSize field an unsigned long instead, and dramatically
  614. // increase the totalSize limit here...
  615. if (totalSize > 32000)
  616. syntaxError(ABL_ERR_SYNTAX_TOO_MANY_LOCAL_VARIABLES);
  617. routineIdPtr->defn.info.routine.totalLocalSize = (unsigned short)totalSize;
  618. }
  619. }
  620. //***************************************************************************