void allocLocal(TypePtr typePtr)
{
	if(typePtr == IntegerTypePtr)
		pushInteger(0);
	else if(typePtr == RealTypePtr)
		pushReal((float)0.0);
	else if(typePtr == BooleanTypePtr)
		pushByte(0);
	else if(typePtr == CharTypePtr)
		pushByte(0);
	else
		switch(typePtr->form)
		{
			case FRM_ENUM:
				pushInteger(0);
				break;
// NOTE: We currently are not supporting sub ranges, until
// we really want 'em...
//			case FRM_SUBRANGE:
//				allocLocal(typePtr->info.subrange.rangeTypePtr);
//				break;
			case FRM_ARRAY:
				PSTR ptr = (PSTR)ABLStackMallocCallback(typePtr->size);
				if(!ptr)
					ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc local array ");
				pushAddress((Address)ptr);
				break;
		}
}
int32_t WatchManager::init(int32_t max)
{
	maxWatches = max;
	numWatches = 0;
	watches = (WatchPtr)ABLStackMallocCallback(max * sizeof(Watch));
	if(!watches)
		return(-1);
	return(ABL_NO_ERR);
}
int32_t BreakPointManager::init(int32_t max)
{
	maxBreakPoints = max;
	numBreakPoints = 0;
	breakPoints = (int32_t*)ABLStackMallocCallback(max * sizeof(int32_t));
	if(!breakPoints)
		return(-1);
	return(ABL_NO_ERR);
}
Exemple #4
0
void initModuleRegistry(int32_t maxModules)
{
    //---------------------------------------------------------------------
    // First, set the max number of modules that may be loaded into the ABL
    // environment at a time...
    MaxModules = maxModules;
    //------------------------------
    // Create the module registry...
    ModuleRegistry = (ModuleEntryPtr)ABLStackMallocCallback(sizeof(ModuleEntry) * MaxModules);
    if(!ModuleRegistry)
        ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc Module Registry ");
    memset(ModuleRegistry, 0, sizeof(ModuleEntry) * MaxModules);
    //-------------------------------------------------
    // Create the active (ABLModule) module registry...
    ModuleInstanceRegistry = (ABLModulePtr*)ABLStackMallocCallback(sizeof(ABLModulePtr) * MaxModules);
    if(!ModuleInstanceRegistry)
        ABL_Fatal(0, " ABL: Unable to malloc AblStackHeap->Module Instance Registry ");
    memset(ModuleInstanceRegistry, 0, sizeof(ABLModulePtr) * MaxModules);
}
Exemple #5
0
long BreakPointManager::init (long max) {

	maxBreakPoints = max;
	numBreakPoints = 0;

	breakPoints = (long*)ABLStackMallocCallback(max * sizeof(long));
	if (!breakPoints)
		return(-1);

	return(ABL_NO_ERR);
}
Exemple #6
0
void initLibraryRegistry(int32_t maxLibraries)
{
    //-----------------------------------------------------------------------
    // First, set the max number of libraries that may be loaded into the ABL
    // environment at a time...
    MaxLibraries = maxLibraries;
    //--------------------------------------------------
    // Create the active (ABLModule) library registry...
    LibraryInstanceRegistry = (ABLModulePtr*)ABLStackMallocCallback(sizeof(ABLModulePtr) * MaxLibraries);
    if(!LibraryInstanceRegistry)
        ABL_Fatal(0, " ABL: Unable to malloc AblStackHeap->Library Instance Registry ");
    memset(LibraryInstanceRegistry, 0, sizeof(ABLModulePtr) * MaxLibraries);
}
void execActualParams(SymTableNodePtr routineIdPtr)
{
	//--------------------------
	// Execute the parameters...
	for(SymTableNodePtr formalIdPtr = (SymTableNodePtr)(routineIdPtr->defn.info.routine.params);
			formalIdPtr != nullptr;
			formalIdPtr = formalIdPtr->next)
	{
		TypePtr formalTypePtr = (TypePtr)(formalIdPtr->typePtr);
		getCodeToken();
		if(formalIdPtr->defn.key == DFN_VALPARAM)
		{
			//-------------------
			// pass by value parameter...
			TypePtr actualTypePtr = execExpression();
			if((formalTypePtr == RealTypePtr) && (actualTypePtr == IntegerTypePtr))
			{
				//---------------------------------------------
				// Real formal parameter, but integer actual...
				tos->real = (float)(tos->integer);
			}
			//----------------------------------------------------------
			// Formal parameter is an array or record, so make a copy...
			if((formalTypePtr->form == FRM_ARRAY)/* || (formalTypePtr->form == FRM_RECORD)*/)
			{
				//------------------------------------------------------------------------------
				// The following is a little inefficient, but is kept this way to keep it clear.
				// Once it's verified to work, optimize...
				int32_t size = formalTypePtr->size;
				PSTR src = tos->address;
				PSTR dest = (PSTR)ABLStackMallocCallback((size_t)size);
				if(!dest)
				{
					char err[255];
					sprintf(err, " ABL: Unable to AblStackHeap->malloc actual array param in module %s)", CurModule->getName());
					ABL_Fatal(0, err);
				}
				PSTR savePtr = dest;
				memcpy(dest, src, size);
				tos->address = savePtr;
			}
		}
		else
		{
			//-------------------------------
			// pass by reference parameter...
			SymTableNodePtr idPtr = getCodeSymTableNodePtr();
			execVariable(idPtr, USE_REFPARAM);
		}
	}
}
Exemple #8
0
int32_t ABLModule::execute(ABLParamPtr moduleParamList, SymTableNodePtr functionIdPtr)
{
    CurModule = this;
    if(debugger)
        debugger->setModule(this);
    //--------------------------
    // Execute the ABL module...
    SymTableNodePtr moduleIdPtr = ModuleRegistry[handle].moduleIdPtr;
    if(moduleIdPtr->defn.info.routine.flags & ROUTINE_FLAG_FSM)
        CurFSM = this;
    else
        CurFSM = nullptr;
    NumStateTransitions = 0;
    //--------------------------------------------
    // Point to this module's static data space...
    StaticDataPtr = staticData;
    OrderCompletionFlags = orderCallFlags;
    //---------------------------------
    // Init some important variables...
    CurModuleIdPtr = nullptr;
    CurRoutineIdPtr = nullptr;
    FileNumber = -1;
    errorCount = 0;
    execStatementCount = 0;
    NumExecutions++;
    NewStateSet = false;
    //------------------
    // Init the stack...
    stackFrameBasePtr = tos = (stack + eternalOffset);
    //---------------------------------------
    // Initialize the module's stack frame...
    level = 1;
    CallStackLevel = 0;
    stackFrameBasePtr = tos + 1;
    //-------------------------
    // Function return value...
    pushInteger(0);
    //---------------
    // Static Link...
    pushAddress(nullptr);
    //----------------
    // Dynamic Link...
    pushAddress(nullptr);
    //------------------
    // Return Address...
    pushAddress(nullptr);
    //initDebugger();
    //----------
    // Run it...
    if(moduleParamList)
    {
        //------------------------------------------------------------------------------
        // NOTE: Currently, parameter passing of arrays is not functioning. This MUST be
        // done...
        int32_t curParam = 0;
        for(SymTableNodePtr formalIdPtr = (SymTableNodePtr)(moduleIdPtr->defn.info.routine.params);
                formalIdPtr != nullptr;
                formalIdPtr = formalIdPtr->next)
        {
            TypePtr formalTypePtr = (TypePtr)(formalIdPtr->typePtr);
            if(formalIdPtr->defn.key == DFN_VALPARAM)
            {
                if(formalTypePtr == RealTypePtr)
                {
                    if(moduleParamList[curParam].type == ABL_PARAM_INTEGER)
                    {
                        //---------------------------------------------
                        // Real formal parameter, but integer actual...
                        pushReal((float)(moduleParamList[curParam].integer));
                    }
                    else if(moduleParamList[curParam].type == ABL_PARAM_REAL)
                        pushReal(moduleParamList[curParam].real);
                }
                else if(formalTypePtr == IntegerTypePtr)
                {
                    if(moduleParamList[curParam].type == ABL_PARAM_INTEGER)
                        pushInteger(moduleParamList[curParam].integer);
                    else
                        return(0);
                }
                //----------------------------------------------------------
                // Formal parameter is an array or record, so make a copy...
                if((formalTypePtr->form == FRM_ARRAY)/* || (formalTypePtr->form == FRM_RECORD)*/)
                {
                    //------------------------------------------------------------------------------
                    // The following is a little inefficient, but is kept this way to keep it clear.
                    // Once it's verified to work, optimize...
                    int32_t size = formalTypePtr->size;
                    PSTR dest = (PSTR)ABLStackMallocCallback((size_t)size);
                    if(!dest)
                    {
                        char err[255];
                        sprintf(err, "ABL: Unable to AblStackHeap->malloc array parameter [Module %d]", id);
                        ABL_Fatal(0, err);
                    }
                    PSTR src = tos->address;
                    PSTR savePtr = dest;
                    memcpy(dest, src, size);
                    tos->address = savePtr;
                }
            }
            else
            {
                //-------------------------------
                // pass by reference parameter...
                if(formalTypePtr == RealTypePtr)
                    pushAddress((Address) & (moduleParamList[curParam].real));
                else if(formalTypePtr == IntegerTypePtr)
                    pushAddress((Address) & (moduleParamList[curParam].integer));
                else
                    return(0);
            }
            curParam++;
        }
    }
    CurModuleHandle = handle;
    CallModuleInit = !initCalled;
    initCalled = true;
    ::executeChild(moduleIdPtr, functionIdPtr);
    memcpy(&returnVal, &returnValue, sizeof(StackItem));
    //-----------
    // Summary...
    return(execStatementCount);
}
Exemple #9
0
void ABLModule::read(ABLFile* moduleFile)
{
    //----------------------------------------------------------------------------
    // If this is called on a newly init'd module, then it will do all appropriate
    // memory alloc, etc. If it's being called on a module that's already been
    // setup (via a call to init(moduleHandle)), then it simply loads the
    // module's data...
    bool fresh = (id == -1);
    if(fresh)
    {
        id = NumModules++;
        moduleFile->readString((puint8_t)name);
        handle = moduleFile->readLong();
        staticData = nullptr;
    }
    else
    {
        char tempName[1024];
        moduleFile->readString((puint8_t)tempName);
        //int32_t ignore = moduleFile->readLong();
    }
    char stateName[256];
    memset(stateName, 0, 256);
    moduleFile->readString((puint8_t)stateName);
    prevState = nullptr;
    if(strcmp(stateName, "NULLPrevState"))
        prevState = findState(stateName);
    memset(stateName, 0, 256);
    moduleFile->readString((puint8_t)stateName);
    state = nullptr;
    if(strcmp(stateName, "NULLState"))
        state = findState(stateName);
    bool savedInitCalled = (moduleFile->readLong() == 1);
    int32_t numStatics = ModuleRegistry[handle].numStaticVars;
    if(numStatics)
    {
        if(fresh)
        {
            staticData = (StackItemPtr)ABLStackMallocCallback(sizeof(StackItem) * numStatics);
            if(!staticData)
            {
                char err[255];
                sprintf(err, "ABL: Unable to AblStackHeap->malloc staticData [Module %d]", id);
                ABL_Fatal(0, err);
            }
        }
        int32_t* sizeList = ModuleRegistry[handle].sizeStaticVars;
        for(size_t i = 0; i < numStatics; i++)
            if(sizeList[i] > 0)
            {
                if(fresh)
                {
                    staticData[i].address = (PSTR)ABLStackMallocCallback(sizeList[i]);
                    if(!staticData)
                    {
                        char err[255];
                        sprintf(err, "ABL: Unable to AblStackHeap->malloc staticData address [Module %d]", id);
                        ABL_Fatal(0, err);
                    }
                }
                int32_t result = moduleFile->read((puint8_t)staticData[i].address, sizeList[i]);
                if(!result)
                {
                    char err[255];
                    sprintf(err, "ABL: Unable to read staticData.address [Module %d]", id);
                    ABL_Fatal(0, err);
                }
            }
            else
            {
                staticData[i].integer = 0;
                int32_t result = moduleFile->read((puint8_t)&staticData[i], sizeof(StackItem));
                if(!result)
                {
                    char err[255];
                    sprintf(err, "ABL: Unable to read staticData [Module %d]", id);
                    ABL_Fatal(0, err);
                }
            }
    }
    if(ModuleRegistry[handle].numOrderCalls)
    {
        int32_t numLongs = 1 + ModuleRegistry[handle].numOrderCalls / 32;
        orderCallFlags = (uint32_t*)ABLStackMallocCallback(sizeof(uint32_t) * numLongs);
        if(!orderCallFlags)
        {
            char err[255];
            sprintf(err, "ABLModule.read: Unable to AblStackHeap->malloc orderCallFlags [Module %d]", id);
            ABL_Fatal(0, err);
        }
        for(size_t i = 0; i < numLongs; i++)
            orderCallFlags[i] = 0;
    }
    if(fresh)
    {
        ModuleRegistry[handle].numInstances++;
        initCalled = savedInitCalled;
        //------------------------------------------------------
        // This Active Module is now on the instance registry...
        ModuleInstanceRegistry[NumModuleInstances++] = this;
        if(debugger)
        {
            watchManager = new WatchManager;
            if(!watchManager)
                ABL_Fatal(0, " Unable to AblStackHeap->malloc WatchManager ");
            int32_t result = watchManager->init(MaxWatchesPerModule);
            if(result != ABL_NO_ERR)
                ABL_Fatal(0, " Unable to AblStackHeap->malloc WatchManager ");
            breakPointManager = new BreakPointManager;
            if(!breakPointManager)
                ABL_Fatal(0, " Unable to AblStackHeap->malloc BreakPointManager ");
            result = breakPointManager->init(MaxBreakPointsPerModule);
            if(result != ABL_NO_ERR)
                ABL_Fatal(0, " Unable to AblStackHeap->malloc BreakPointManager ");
        }
    }
}
Exemple #10
0
int32_t ABLModule::init(int32_t moduleHandle)
{
    if(moduleHandle == -1)
    {
        //----------
        // Clean up!
        return(-1);
    }
    id = NumModules++;
    handle = moduleHandle;
    staticData = nullptr;
    int32_t numStatics = ModuleRegistry[handle].numStaticVars;
    if(numStatics)
    {
        staticData = (StackItemPtr)ABLStackMallocCallback(sizeof(StackItem) * numStatics);
        if(!staticData)
        {
            char err[255];
            sprintf(err, "ABL: Unable to AblStackHeap->malloc staticData [Module %d]", id);
            ABL_Fatal(0, err);
        }
        int32_t* sizeList = ModuleRegistry[handle].sizeStaticVars;
        for(size_t i = 0; i < numStatics; i++)
            if(sizeList[i] > 0)
            {
                staticData[i].address = (PSTR)ABLStackMallocCallback(sizeList[i]);
                if(!staticData)
                {
                    char err[255];
                    sprintf(err, "ABL: Unable to AblStackHeap->malloc staticData address [Module %d]", id);
                    ABL_Fatal(0, err);
                }
            }
            else
                staticData[i].integer = 0;
    }
    if(ModuleRegistry[handle].numOrderCalls)
    {
        int32_t numLongs = 1 + ModuleRegistry[handle].numOrderCalls / 32;
        orderCallFlags = (uint32_t*)ABLStackMallocCallback(sizeof(uint32_t) * numLongs);
        if(!orderCallFlags)
        {
            char err[255];
            sprintf(err, "ABL: Unable to AblStackHeap->malloc orderCallFlags [Module %d]", id);
            ABL_Fatal(0, err);
        }
        for(size_t i = 0; i < numLongs; i++)
            orderCallFlags[i] = 0;
    }
    ModuleRegistry[handle].numInstances++;
    initCalled = false;
    //------------------------------------------------------
    // This Active Module is now on the instance registry...
    ModuleInstanceRegistry[NumModuleInstances++] = this;
    if(debugger)
    {
        watchManager = new WatchManager;
        if(!watchManager)
            ABL_Fatal(0, " Unable to AblStackHeap->malloc WatchManager ");
        int32_t result = watchManager->init(MaxWatchesPerModule);
        if(result != ABL_NO_ERR)
            ABL_Fatal(0, " Unable to AblStackHeap->malloc WatchManager ");
        breakPointManager = new BreakPointManager;
        if(!breakPointManager)
            ABL_Fatal(0, " Unable to AblStackHeap->malloc BreakPointManager ");
        result = breakPointManager->init(MaxBreakPointsPerModule);
        if(result != ABL_NO_ERR)
            ABL_Fatal(0, " Unable to AblStackHeap->malloc BreakPointManager ");
    }
    if(ModuleRegistry[handle].moduleIdPtr->defn.info.routine.flags & ROUTINE_FLAG_FSM)
    {
        //--------------------------------
        // Always starts in START state...
        SymTableNodePtr startState = searchSymTable("start", ModuleRegistry[handle].moduleIdPtr->defn.info.routine.localSymTable);
        if(!startState)
        {
            char err[255];
            sprintf(err, "ABL: FSM has no Start state [%s]", CurModule->getName());
            ABL_Fatal(0, err);
        }
        prevState = nullptr;
        state = startState;
    }
    //--------------------
    // Can this ever fail?
    return(ABL_NO_ERR);
}
Exemple #11
0
PVOID Debugger::operator new(size_t mySize)
{
	void* result = ABLStackMallocCallback(mySize);
	return(result);
}
Exemple #12
0
PVOID BreakPointManager::operator new(size_t mySize)
{
	void* result = ABLStackMallocCallback(mySize);
	return(result);
}
Exemple #13
0
TypePtr caseLabel (CaseItemPtr& caseItemHead, CaseItemPtr& caseItemTail, long& caseLabelCount) {

	CaseItemPtr newCaseItem = (CaseItemPtr)ABLStackMallocCallback(sizeof(CaseItem));
	if (!newCaseItem)
		ABL_Fatal(0, " ABL: Unable to AblStackHeap->malloc case item ");
	if (caseItemHead) {
		caseItemTail->next = newCaseItem;
		caseItemTail = newCaseItem;
		}
	else
		caseItemHead = caseItemTail = newCaseItem;
	newCaseItem->next = NULL;
	caseLabelCount++;

	TokenCodeType sign = TKN_PLUS;
	bool sawSign = false;
	if ((curToken == TKN_PLUS) || (curToken == TKN_MINUS)) {
		sign = curToken;
		sawSign = true;
		getToken();
	}

	if (curToken == TKN_NUMBER) {
		SymTableNodePtr thisNode = searchSymTable(tokenString, SymTableDisplay[1]);
		if (!thisNode)
			thisNode = enterSymTable(tokenString, &SymTableDisplay[1]);
		crunchSymTableNodePtr(thisNode);
		if (curLiteral.type == LIT_INTEGER)
			newCaseItem->labelValue = (sign == TKN_PLUS) ? curLiteral.value.integer : -curLiteral.value.integer;
		else
			syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT);
		return(IntegerTypePtr);
		}
	else if (curToken == TKN_IDENTIFIER) {
		SymTableNodePtr idPtr;
		searchAllSymTables(idPtr);
		crunchSymTableNodePtr(idPtr);
		if (!idPtr) {
			syntaxError(ABL_ERR_SYNTAX_UNDEFINED_IDENTIFIER);
			return(&DummyType);
			}
		else if (idPtr->defn.key != DFN_CONST) {
			syntaxError(ABL_ERR_SYNTAX_NOT_A_CONSTANT_IDENTIFIER);
			return(&DummyType);
			}
		else if (idPtr->typePtr == IntegerTypePtr) {
			newCaseItem->labelValue = (sign == TKN_PLUS ? idPtr->defn.info.constant.value.integer : -idPtr->defn.info.constant.value.integer);
			return(IntegerTypePtr);
			}
		else if (idPtr->typePtr == CharTypePtr) {
			if (sawSign)
				syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT);
			newCaseItem->labelValue = idPtr->defn.info.constant.value.character;
			return(CharTypePtr);
			}
		else if (idPtr->typePtr->form == FRM_ENUM) {
			if (sawSign)
				syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT);
			newCaseItem->labelValue = idPtr->defn.info.constant.value.integer;
			return(idPtr->typePtr);
			}
		else
			return(&DummyType);
		}
	else if (curToken == TKN_STRING) {
		// STRING/CHAR TYPE...
		}
	else {
		syntaxError(ABL_ERR_SYNTAX_INVALID_CONSTANT);
		return(&DummyType);
	}
	return(&DummyType);
}
Exemple #14
0
void* WatchManager::operator new (size_t mySize) {

	void *result = ABLStackMallocCallback(mySize);
	return(result);
}
Exemple #15
0
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;
	}
}