123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734 |
- //===========================================================================//
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- //===========================================================================//
- //***************************************************************************
- //
- // ABLDECL.CPP
- //
- //***************************************************************************
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.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
- //***************************************************************************
- extern TokenCodeType curToken;
- extern char wordString[];
- extern Literal curLiteral;
- extern SymTableNodePtr SymTableDisplay[];
- extern long level;
- extern TypePtr IntegerTypePtr;
- extern TypePtr CharTypePtr;
- extern TypePtr RealTypePtr;
- extern TypePtr BooleanTypePtr;
- extern TokenCodeType declarationStartList[];
- extern TokenCodeType statementStartList[];
- extern long eternalOffset;
- extern long NumStaticVariables;
- extern long MaxStaticVariables;
- extern long* StaticVariablesSizes;
- extern long* EternalVariablesSizes;
- extern ABLModulePtr CurLibrary;
- //***************************************************************************
- TokenCodeType followRoutineList[] = {
- TKN_SEMICOLON,
- TKN_EOF,
- TKN_NONE
- };
- TokenCodeType followDeclarationList[] = {
- TKN_SEMICOLON,
- TKN_IDENTIFIER,
- TKN_EOF,
- TKN_NONE
- };
- TokenCodeType followVariablesList[] = {
- TKN_SEMICOLON,
- TKN_IDENTIFIER,
- TKN_EOF,
- TKN_NONE
- };
- TokenCodeType followVarBlockList[] = {
- TKN_FUNCTION,
- TKN_ORDER,
- TKN_STATE,
- TKN_CODE,
- TKN_EOF,
- TKN_NONE
- };
- TokenCodeType followDimensionList[] = {
- TKN_COMMA,
- TKN_RBRACKET,
- TKN_EOF,
- TKN_NONE
- };
- TokenCodeType indexTypeStartList[] = {
- TKN_IDENTIFIER,
- TKN_NUMBER,
- TKN_NONE
- };
- TokenCodeType followIndexesList[] = {
- TKN_OF,
- TKN_IDENTIFIER,
- TKN_LPAREN,
- TKN_PLUS,
- TKN_MINUS,
- TKN_NUMBER,
- TKN_SEMICOLON,
- TKN_EOF,
- TKN_NONE
- };
- //***************************************************************************
- // MISC. routines
- //***************************************************************************
- void ifTokenGet(TokenCodeType tokenCode) {
- if (curToken == tokenCode)
- getToken();
- }
- //***************************************************************************
- void ifTokenGetElseError (TokenCodeType tokenCode, SyntaxErrorType errorCode) {
- if (curToken == tokenCode)
- getToken();
- else
- syntaxError(errorCode);
- }
- //***************************************************************************
- // DECLARATIONS routines
- //***************************************************************************
- void declarations (SymTableNodePtr routineIdPtr, bool allowFunctions) {
- if (curToken == TKN_CONST) {
- getToken();
- constDefinitions();
- }
- if (curToken == TKN_TYPE) {
- getToken();
- typeDefinitions();
- }
- if (curToken == TKN_VAR) {
- getToken();
- varDeclarations(routineIdPtr);
- }
- //---------------------------------------------------
- // Loop to process all of the function definitions...
- if (allowFunctions)
- while ((curToken == TKN_FUNCTION) || (curToken == TKN_ORDER) || (curToken == TKN_STATE)){
- routine();
- //---------------------
- // Error synchronize...
- synchronize(followRoutineList, declarationStartList, statementStartList);
- if (curToken == TKN_SEMICOLON)
- getToken();
- else if (tokenIn(declarationStartList) || tokenIn(statementStartList))
- syntaxError(ABL_ERR_SYNTAX_MISSING_SEMICOLON);
- }
- else if ((curToken == TKN_FUNCTION) || (curToken == TKN_ORDER) || (curToken == TKN_STATE))
- syntaxError(ABL_ERR_SYNTAX_NO_FUNCTION_NESTING);
- }
- //***************************************************************************
- // CONST routines
- //***************************************************************************
- void constDefinitions (void) {
- //-------------------------------------------------------
- // Loop to process definitions separated by semicolons...
- while (curToken == TKN_IDENTIFIER) {
- SymTableNodePtr constantIdPtr;
- searchAndEnterLocalSymTable(constantIdPtr);
- constantIdPtr->defn.key = DFN_CONST;
- constantIdPtr->library = CurLibrary;
- getToken();
- ifTokenGetElseError(TKN_EQUAL, ABL_ERR_SYNTAX_MISSING_EQUAL);
- doConst(constantIdPtr);
- analyzeConstDefn(constantIdPtr);
- //---------------------------------
- // Error synchronize: should be a ;
- synchronize(followDeclarationList, declarationStartList, statementStartList);
- if (curToken == TKN_SEMICOLON)
- getToken();
- else if (tokenIn(declarationStartList) || tokenIn(statementStartList))
- syntaxError(ABL_ERR_SYNTAX_MISSING_SEMICOLON);
- }
- }
- //***************************************************************************
- TypePtr makeStringType (long length) {
- TypePtr stringTypePtr = createType();
- if (!stringTypePtr)
- ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc stringType ");
- stringTypePtr->form = FRM_ARRAY;
- stringTypePtr->size = length;
- stringTypePtr->typeIdPtr = NULL;
- stringTypePtr->info.array.indexTypePtr = IntegerTypePtr;
- stringTypePtr->info.array.elementTypePtr = CharTypePtr;
- stringTypePtr->info.array.elementCount = length + 1;
- return(stringTypePtr);
- }
- //***************************************************************************
- void doConst (SymTableNodePtr constantIdPtr) {
- TokenCodeType sign = TKN_PLUS;
- bool sawSign = false;
- if ((curToken == TKN_PLUS) || (curToken == TKN_MINUS)) {
- sign = curToken;
- sawSign = true;
- getToken();
- }
- //----------------------------------
- // Numeric constant: real or integer
- if (curToken == TKN_NUMBER) {
- if (curLiteral.type == LIT_INTEGER) {
- if (sign == TKN_PLUS)
- constantIdPtr->defn.info.constant.value.integer = curLiteral.value.integer;
- else
- constantIdPtr->defn.info.constant.value.integer = -(curLiteral.value.integer);
- constantIdPtr->typePtr = setType(IntegerTypePtr);
- }
- else {
- if (sign == TKN_PLUS)
- constantIdPtr->defn.info.constant.value.real = curLiteral.value.real;
- else
- constantIdPtr->defn.info.constant.value.real = -(curLiteral.value.real);
- constantIdPtr->typePtr = setType(RealTypePtr);
- }
- }
- else if (curToken == TKN_IDENTIFIER) {
- SymTableNodePtr idPtr = NULL;
- searchAllSymTables(idPtr);
- if (!idPtr)
- syntaxError(ABL_ERR_SYNTAX_UNDEFINED_IDENTIFIER);
- else if (idPtr->defn.key != DFN_CONST)
- syntaxError(ABL_ERR_SYNTAX_NOT_A_CONSTANT_IDENTIFIER);
- else if (idPtr->typePtr == IntegerTypePtr) {
- if (sign == TKN_PLUS)
- constantIdPtr->defn.info.constant.value.integer = idPtr->defn.info.constant.value.integer;
- else
- constantIdPtr->defn.info.constant.value.integer = -(idPtr->defn.info.constant.value.integer);
- constantIdPtr->typePtr = setType(IntegerTypePtr);
- }
- else if (idPtr->typePtr == CharTypePtr) {
- if (sawSign)
- syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT);
- constantIdPtr->defn.info.constant.value.character = idPtr->defn.info.constant.value.character;
- constantIdPtr->typePtr = setType(CharTypePtr);
- }
- else if (idPtr->typePtr == RealTypePtr) {
- if (sign == TKN_PLUS)
- constantIdPtr->defn.info.constant.value.real = idPtr->defn.info.constant.value.real;
- else
- constantIdPtr->defn.info.constant.value.real = -(idPtr->defn.info.constant.value.real);
- constantIdPtr->typePtr = setType(RealTypePtr);
- }
- else if (((Type*)(idPtr->typePtr))->form == FRM_ENUM) {
- if (sawSign)
- syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT);
- constantIdPtr->defn.info.constant.value.integer = idPtr->defn.info.constant.value.integer;
- constantIdPtr->typePtr = setType(idPtr->typePtr);
- }
- else if (((TypePtr)(idPtr->typePtr))->form == FRM_ARRAY) {
- if (sawSign)
- syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT);
- constantIdPtr->defn.info.constant.value.stringPtr = idPtr->defn.info.constant.value.stringPtr;
- constantIdPtr->typePtr = setType(idPtr->typePtr);
- }
- }
- else if (curToken == TKN_STRING) {
- if (sawSign)
- syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT);
- if (strlen(curLiteral.value.string) == 1) {
- constantIdPtr->defn.info.constant.value.character = curLiteral.value.string[0];
- constantIdPtr->typePtr = setType(CharTypePtr);
- }
- else {
- long length = strlen(curLiteral.value.string);
- constantIdPtr->defn.info.constant.value.stringPtr = (char*)ABLSymbolMallocCallback(length + 1);
- if (!constantIdPtr->defn.info.constant.value.stringPtr)
- ABL_Fatal(0, " ABL: Unable to AblSymbolHeap->malloc array string constant ");
- strcpy(constantIdPtr->defn.info.constant.value.stringPtr, curLiteral.value.string);
- constantIdPtr->typePtr = makeStringType(length);
- }
- }
- else {
- constantIdPtr->typePtr = NULL;
- syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT);
- }
- getToken();
- }
- //***************************************************************************
- // TYPE routines
- //***************************************************************************
- //---------------------------------------------------------------------------
- // Need to implement type routines if we allow user-defined types, and/or the
- // PASCAL style array types (otherwise, arrays should be implemented in the
- // var routines...
- void typeDefinitions (void) {
- while (curToken == TKN_IDENTIFIER) {
- SymTableNodePtr typeIdPtr;
- searchAndEnterLocalSymTable(typeIdPtr);
- typeIdPtr->defn.key = DFN_TYPE;
- typeIdPtr->library = CurLibrary;
- getToken();
- ifTokenGetElseError(TKN_EQUAL, ABL_ERR_SYNTAX_MISSING_EQUAL);
- //----------------------------------
- // Process the type specification...
- typeIdPtr->typePtr = doType();
- if (typeIdPtr->typePtr->typeIdPtr == NULL)
- typeIdPtr->typePtr->typeIdPtr = typeIdPtr;
- analyzeTypeDefn(typeIdPtr);
- //---------------
- // Error synch...
- synchronize(followDeclarationList, declarationStartList, statementStartList);
- if (curToken == TKN_SEMICOLON)
- getToken();
- else if (tokenIn(declarationStartList) || tokenIn(statementStartList))
- syntaxError(ABL_ERR_SYNTAX_MISSING_SEMICOLON);
- }
- }
- //***************************************************************************
- TypePtr doType (void) {
- switch (curToken) {
- case TKN_IDENTIFIER: {
- SymTableNodePtr idPtr;
- searchAllSymTables(idPtr);
- if (!idPtr) {
- syntaxError(ABL_ERR_SYNTAX_UNDEFINED_IDENTIFIER);
- return(NULL);
- }
- else if (idPtr->defn.key == DFN_TYPE) {
- //----------------------------------------------------------
- // NOTE: Array types should be parsed in this case if a left
- // bracket follows the type identifier.
- TypePtr elementType = setType(identifierType(idPtr));
- if (curToken == TKN_LBRACKET) {
- //--------------
- // Array type...
- TypePtr typePtr = createType();
- if (!typePtr)
- ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc array type ");
- TypePtr elementTypePtr = typePtr;
- do {
- getToken();
- if (tokenIn(indexTypeStartList)) {
- elementTypePtr->form = FRM_ARRAY;
- elementTypePtr->size = 0;
- elementTypePtr->typeIdPtr = NULL;
- //----------------------------------------------
- // All array indices must be integer, for now...
- elementTypePtr->info.array.indexTypePtr = setType(IntegerTypePtr);
- //------------------------
- // Read the index count...
- switch (curToken) {
- case TKN_NUMBER:
- if (curLiteral.type == LIT_INTEGER)
- elementTypePtr->info.array.elementCount = curLiteral.value.integer;
- else {
- elementTypePtr->form = FRM_NONE;
- elementTypePtr->size = 0;
- elementTypePtr->typeIdPtr = NULL;
- elementTypePtr->info.array.indexTypePtr = NULL;
- syntaxError(ABL_ERR_SYNTAX_INVALID_INDEX_TYPE);
- }
- getToken();
- break;
- case TKN_IDENTIFIER: {
- SymTableNodePtr idPtr;
- searchAllSymTables(idPtr);
- if (idPtr == NULL)
- syntaxError(ABL_ERR_SYNTAX_UNDEFINED_IDENTIFIER);
- else if (idPtr->defn.key == DFN_CONST) {
- if (idPtr->typePtr == IntegerTypePtr)
- elementTypePtr->info.array.elementCount = idPtr->defn.info.constant.value.integer;
- else {
- elementTypePtr->form = FRM_NONE;
- elementTypePtr->size = 0;
- elementTypePtr->typeIdPtr = NULL;
- elementTypePtr->info.array.indexTypePtr = NULL;
- syntaxError(ABL_ERR_SYNTAX_INVALID_INDEX_TYPE);
- }
- }
- else {
- elementTypePtr->form = FRM_NONE;
- elementTypePtr->size = 0;
- elementTypePtr->typeIdPtr = NULL;
- elementTypePtr->info.array.indexTypePtr = NULL;
- syntaxError(ABL_ERR_SYNTAX_INVALID_INDEX_TYPE);
- }
- getToken();
- }
- break;
- default:
- elementTypePtr->form = FRM_NONE;
- elementTypePtr->size = 0;
- elementTypePtr->typeIdPtr = NULL;
- elementTypePtr->info.array.indexTypePtr = NULL;
- syntaxError(ABL_ERR_SYNTAX_INVALID_INDEX_TYPE);
- getToken();
- }
- }
- else {
- elementTypePtr->form = FRM_NONE;
- elementTypePtr->size = 0;
- elementTypePtr->typeIdPtr = NULL;
- elementTypePtr->info.array.indexTypePtr = NULL;
- syntaxError(ABL_ERR_SYNTAX_INVALID_INDEX_TYPE);
- getToken();
- }
- synchronize(followDimensionList, NULL, NULL);
- //--------------------------------
- // Create an array element type...
- if (curToken == TKN_COMMA) {
- elementTypePtr = elementTypePtr->info.array.elementTypePtr = createType();
- if (!elementTypePtr)
- ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc array element Type ");
- }
- } while (curToken == TKN_COMMA);
- ifTokenGetElseError(TKN_RBRACKET, ABL_ERR_SYNTAX_MISSING_RBRACKET);
- elementTypePtr->info.array.elementTypePtr = elementType;
- typePtr->size = arraySize(typePtr);
- elementType = typePtr;
- }
- return(elementType);
- }
- else {
- syntaxError(ABL_ERR_SYNTAX_NOT_A_TYPE_IDENTIFIER);
- return(NULL);
- }
- }
- break;
- case TKN_LPAREN:
- return(enumerationType());
- default:
- syntaxError(ABL_ERR_SYNTAX_INVALID_TYPE);
- return(NULL);
- }
- }
- //***************************************************************************
- TypePtr identifierType (SymTableNodePtr idPtr) {
- TypePtr typePtr = (TypePtr)idPtr->typePtr;
- getToken();
- return(typePtr);
- }
- //***************************************************************************
- TypePtr enumerationType (void) {
- SymTableNodePtr constantIdPtr = NULL;
- SymTableNodePtr lastIdPtr = NULL;
- TypePtr typePtr = createType();
- if (!typePtr)
- ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc enumeration type ");
- long constantValue = -1;
- typePtr->form = FRM_ENUM;
- typePtr->size = sizeof(long);
- typePtr->typeIdPtr = NULL;
- getToken();
- //------------------------------------------------------------
- // Process list of identifiers in this new enumeration type...
- while (curToken == TKN_IDENTIFIER) {
- searchAndEnterLocalSymTable(constantIdPtr);
- constantIdPtr->defn.key = DFN_CONST;
- constantIdPtr->defn.info.constant.value.integer = ++constantValue;
- constantIdPtr->typePtr = typePtr;
- constantIdPtr->library = CurLibrary;
- if (lastIdPtr == NULL)
- typePtr->info.enumeration.constIdPtr = lastIdPtr = constantIdPtr;
- else {
- lastIdPtr->next = constantIdPtr;
- lastIdPtr = constantIdPtr;
- }
- getToken();
- ifTokenGet(TKN_COMMA);
- }
- ifTokenGetElseError(TKN_RPAREN, ABL_ERR_SYNTAX_MISSING_RPAREN);
- typePtr->info.enumeration.max = constantValue;
- return(typePtr);
- }
- //***************************************************************************
- long arraySize (TypePtr typePtr) {
- if (typePtr->info.array.elementTypePtr->size == 0)
- typePtr->info.array.elementTypePtr->size = arraySize(typePtr->info.array.elementTypePtr);
- if (typePtr->info.array.elementCount == -1) {
- //--------------------------------------------------------------
- // Open array, so just return the size of its element. Remember,
- // open arrays must be open at the end...
- typePtr->size = typePtr->info.array.elementTypePtr->size;
- }
- else
- typePtr->size = typePtr->info.array.elementCount * typePtr->info.array.elementTypePtr->size;
- return(typePtr->size);
- }
- //***************************************************************************
- // VAR routines
- //***************************************************************************
- void varDeclarations (SymTableNodePtr routineIdPtr) {
- varOrFieldDeclarations(routineIdPtr,
- STACK_FRAME_HEADER_SIZE + routineIdPtr->defn.info.routine.paramCount);
- }
- //***************************************************************************
- void varOrFieldDeclarations (SymTableNodePtr routineIdPtr, long offset) {
- bool varFlag = (routineIdPtr != NULL);
- SymTableNodePtr idPtr = NULL;
- SymTableNodePtr firstIdPtr = NULL;
- SymTableNodePtr lastIdPtr = NULL;
- SymTableNodePtr prevLastIdPtr = NULL;
-
- long totalSize = 0;
- while ((curToken == TKN_IDENTIFIER) || (curToken == TKN_ETERNAL) || (curToken == TKN_STATIC)) {
- VariableType varType = VAR_TYPE_NORMAL;
- if ((curToken == TKN_ETERNAL) || (curToken == TKN_STATIC)) {
- if (curToken == TKN_ETERNAL)
- varType = VAR_TYPE_ETERNAL;
- else
- varType = VAR_TYPE_STATIC;
- getToken();
- if (curToken != TKN_IDENTIFIER)
- syntaxError(ABL_ERR_SYNTAX_MISSING_IDENTIFIER);
- }
- firstIdPtr = NULL;
- //------------------------------
- // Process the variable type...
- TypePtr typePtr = doType();
- //------------------------------------------------------------------
- // Since we haven't really assigned it here, decrement its
- // numInstances. Every variable in this list will set it properly...
- typePtr->numInstances--;
- long size = typePtr->size;
- //-------------------------------------------------------
- // Now that we've read the type, read in the variable (or
- // possibly list of variables) declared of this type.
- // Loop to process every variable (and field, if records
- // are being implemented:) in sublist...
- while (curToken == TKN_IDENTIFIER) {
- if (varFlag) {
- //---------------------------------------------
- // We're working with a variable declaration...
- if (varType == VAR_TYPE_ETERNAL) {
- long curLevel = level;
- level = 0;
- searchAndEnterThisTable (idPtr, SymTableDisplay[0]);
- level = curLevel;
- }
- else
- searchAndEnterLocalSymTable(idPtr);
- idPtr->library = CurLibrary;
- idPtr->defn.key = DFN_VAR;
- }
- else
- syntaxError(ABL_ERR_SYNTAX_NO_RECORD_TYPES);
- idPtr->labelIndex = 0;
- //------------------------------------------
- // Now, link Id's together into a sublist...
- if (!firstIdPtr) {
- firstIdPtr = lastIdPtr = idPtr;
- if (varFlag && (varType != VAR_TYPE_ETERNAL) && (routineIdPtr->defn.info.routine.locals == NULL))
- routineIdPtr->defn.info.routine.locals = idPtr;
- }
- else {
- lastIdPtr->next = idPtr;
- lastIdPtr = idPtr;
- }
- getToken();
- ifTokenGet(TKN_COMMA);
- }
- //--------------------------------------------------------------------------
- // Assign the offset and the type to all variable or field Ids in sublist...
- for (idPtr = firstIdPtr; idPtr != NULL; idPtr = idPtr->next) {
- idPtr->typePtr = setType(typePtr);
- if (varFlag) {
- idPtr->defn.info.data.varType = varType;
- switch (varType) {
- case VAR_TYPE_NORMAL:
- totalSize += size;
- idPtr->defn.info.data.offset = offset++;
- break;
- case VAR_TYPE_ETERNAL: {
- idPtr->defn.info.data.offset = eternalOffset;
- //-----------------------------------
- // Initialize the variable to zero...
- StackItemPtr dataPtr = (StackItemPtr)stack + eternalOffset;
- if (typePtr->form == FRM_ARRAY) {
- dataPtr->address = (Address)ABLStackMallocCallback((size_t)size);
- if (!dataPtr->address)
- ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc eternal array ");
- memset(dataPtr->address, 0, size);
- EternalVariablesSizes[eternalOffset] = size;
- }
- else {
- dataPtr->integer = 0;
- EternalVariablesSizes[eternalOffset] = 0;
- }
- eternalOffset++;
- }
- break;
- case VAR_TYPE_STATIC: {
- if (NumStaticVariables == MaxStaticVariables)
- syntaxError(ABL_ERR_SYNTAX_TOO_MANY_STATIC_VARS);
- idPtr->defn.info.data.offset = NumStaticVariables;
- if (typePtr->form == FRM_ARRAY)
- StaticVariablesSizes[NumStaticVariables] = size;
- else
- StaticVariablesSizes[NumStaticVariables] = 0;
- NumStaticVariables++;
- }
- break;
- }
- analyzeVarDecl(idPtr);
- }
- else {
- //----------------
- // record field...
- idPtr->defn.info.data.varType = VAR_TYPE_NORMAL;
- idPtr->defn.info.data.offset = offset;
- offset += size;
- }
- }
- //--------------------------------------------------
- // Now, link this sublist to the previous sublist...
- if (varType != VAR_TYPE_ETERNAL) {
- if (prevLastIdPtr != NULL)
- prevLastIdPtr->next = firstIdPtr;
- prevLastIdPtr = lastIdPtr;
- }
- //---------------------
- // Error synchronize...
- if (varFlag)
- synchronize(followVariablesList, declarationStartList, statementStartList);
- if (curToken == TKN_SEMICOLON)
- getToken();
- else if (varFlag && (tokenIn(declarationStartList) || tokenIn(statementStartList)))
- syntaxError(ABL_ERR_SYNTAX_MISSING_SEMICOLON);
- }
- synchronize(followVarBlockList, NULL, NULL);
- if (varFlag) {
- //----------------------------------------------------------------
- // If the following error occurs too frequently, simply make the
- // totalLocalSize field an unsigned long instead, and dramatically
- // increase the totalSize limit here...
- if (totalSize > 32000)
- syntaxError(ABL_ERR_SYNTAX_TOO_MANY_LOCAL_VARIABLES);
- routineIdPtr->defn.info.routine.totalLocalSize = (unsigned short)totalSize;
- }
- }
- //***************************************************************************
|