int32_t Debugger::setWatch(int32_t states) { getToken(); switch(curToken) { case TKN_SEMICOLON: print("Variables currently watched:\n"); //------------------------------------------------------------- // No variable, so default watch action--display all watches... watchManager->print(); break; case TKN_IDENTIFIER: SymTableNodePtr idPtr = nullptr; searchAndFindAllSymTables(idPtr); getToken(); //----------------- // STORE setting... bool breakToDebug = ((states & WATCH_BREAK) != 0); if(states & WATCH_STORE_OFF) watchManager->setStore(idPtr, false, breakToDebug); else if(states & WATCH_STORE_ON) watchManager->setStore(idPtr, true, breakToDebug); //----------------- // FETCH setting... if(states & WATCH_FETCH_OFF) watchManager->setFetch(idPtr, false, breakToDebug); else if(states & WATCH_FETCH_ON) watchManager->setFetch(idPtr, true, breakToDebug); break; } return(ABL_NO_ERR); }
void Debugger::assignVariable(void) { getToken(); #if 0 if(curToken == TKN_SEMICOLON) print("Need a variable.\n"); else if(curToken == TKN_IDENTIFIER) { //---------------------------------- // Parse the assignment statement... SymTableNodePtr idPtr = nullptr; searchAndFindAllSymTables(idPtr); assigmentStatement(idPtr); if(errorCount > 0) return; //------------------- // Now, execute it... PSTR savedCodeSegmentPtr = codeSegmentPtr; int32_t savedCodeToken = codeToken; codeSegmentPtr = codeBuffer + 1; getCodeToken(); idPtr = getSymTableCodePtr(); execAssignmentStatement(idPtr); //---------------------------- // Restore the code segment... codeSegmentPtr = savedCodeSegmentPtr; codeToken = savedCodeToken; } #endif }
void forStatement (void) { getToken(); char* loopEndLocation = crunchAddressMarker(NULL); TypePtr forType = NULL; if (curToken == TKN_IDENTIFIER) { SymTableNodePtr forIdPtr = NULL; searchAndFindAllSymTables(forIdPtr); crunchSymTableNodePtr(forIdPtr); if (/*(forIdPtr->level != level) ||*/ (forIdPtr->defn.key != DFN_VAR)) syntaxError(ABL_ERR_SYNTAX_INVALID_FOR_CONTROL); forType = forIdPtr->typePtr; getToken(); //------------------------------------------------------------------ // If we end up adding a CHAR type, this line needs to be changed... if ((forType != IntegerTypePtr) && /*(forType != CharTypePtr) &&*/ (forType->form != FRM_ENUM)) syntaxError(ABL_ERR_SYNTAX_INCOMPATIBLE_TYPES); } else { syntaxError(ABL_ERR_SYNTAX_MISSING_IDENTIFIER); forType = &DummyType; } ifTokenGetElseError(TKN_EQUAL, ABL_ERR_SYNTAX_MISSING_EQUAL); TypePtr exprType = expression(); if (!isAssignTypeCompatible(forType, exprType)) syntaxError(ABL_ERR_SYNTAX_INCOMPATIBLE_TYPES); if (curToken == TKN_TO) getToken(); else syntaxError(ABL_ERR_SYNTAX_MISSING_TO); exprType = expression(); if (!isAssignTypeCompatible(forType, exprType)) syntaxError(ABL_ERR_SYNTAX_INCOMPATIBLE_TYPES); //----------------------------------------- // For now, let's use the DO keyword... ifTokenGetElseError(TKN_DO, ABL_ERR_SYNTAX_MISSING_DO); if (curToken != TKN_END_FOR) do { statement(); while (curToken == TKN_SEMICOLON) getToken(); if (curToken == TKN_END_FOR) break; } while (tokenIn(statementStartList)); ifTokenGetElseError(TKN_END_FOR, ABL_ERR_SYNTAX_MISSING_END_FOR); fixupAddressMarker(loopEndLocation); }
TypePtr factor (void) { TypePtr thisType = NULL; switch (curToken) { case TKN_IDENTIFIER: { SymTableNodePtr IdPtr = NULL; searchAndFindAllSymTables(IdPtr); switch (IdPtr->defn.key) { case DFN_FUNCTION: crunchSymTableNodePtr(IdPtr); getToken(); thisType = routineCall(IdPtr, 1); break; case DFN_CONST: crunchSymTableNodePtr(IdPtr); getToken(); thisType = (TypePtr)(IdPtr->typePtr); break; default: thisType = (TypePtr)variable(IdPtr); break; } } break; case TKN_NUMBER: { SymTableNodePtr thisNode = searchSymTable(tokenString, SymTableDisplay[1]); if (!thisNode) thisNode = enterSymTable(tokenString, &SymTableDisplay[1]); if (curLiteral.type == LIT_INTEGER) { thisNode->typePtr = IntegerTypePtr; thisType = (TypePtr)(thisNode->typePtr); thisNode->defn.info.constant.value.integer = curLiteral.value.integer; } else { thisNode->typePtr = RealTypePtr; thisType = (TypePtr)(thisNode->typePtr); thisNode->defn.info.constant.value.real = curLiteral.value.real; } crunchSymTableNodePtr(thisNode); getToken(); } break; case TKN_STRING: { long length = strlen(curLiteral.value.string); if (EnterStateSymbol) { SymTableNodePtr stateSymbol = searchSymTableForState(curLiteral.value.string, SymTableDisplay[1]); if (!stateSymbol) forwardState(curLiteral.value.string); } SymTableNodePtr thisNode = searchSymTableForString(tokenString, SymTableDisplay[1]); if (!thisNode)// { thisNode = enterSymTable(tokenString, &SymTableDisplay[1]); if (length == 1) { thisNode->defn.info.constant.value.character = curLiteral.value.string[0]; thisType = CharTypePtr; } else { thisNode->typePtr = thisType = makeStringType(length); thisNode->info = (char*)ABLSymbolMallocCallback(length + 1); if (!thisNode->info) ABL_Fatal(0, " ABL: Unable to AblSymTableHeap->malloc string literal "); strcpy(thisNode->info, curLiteral.value.string); } //} crunchSymTableNodePtr(thisNode); getToken(); } break; case TKN_NOT: getToken(); thisType = factor(); break; case TKN_LPAREN: getToken(); thisType = expression(); ifTokenGetElseError(TKN_RPAREN, ABL_ERR_SYNTAX_MISSING_RPAREN); break; default: syntaxError(ABL_ERR_SYNTAX_INVALID_EXPRESSION); thisType = &DummyType; break; } return(thisType); }
void statement (void) { //------------------------------------------------------------------- // NOTE: Since we currently don't support generic BEGIN/END (compound // statement) blocks... if ((curToken != TKN_CODE) /*&& (curToken != TKN_BEGIN)*/) crunchStatementMarker(); switch (curToken) { case TKN_IDENTIFIER: { SymTableNodePtr IdPtr = NULL; //-------------------------------------------------------------- // First, do we have an assignment statement or a function call? searchAndFindAllSymTables(IdPtr); if ((IdPtr->defn.key == DFN_FUNCTION)/* || (IdPtr->defn.key == DFN_MODULE)*/) { RoutineKey key = IdPtr->defn.info.routine.key; if ((key == RTN_ASSERT) || (key == RTN_PRINT) || (key == RTN_CONCAT)) { bool uncrunch = ((key == RTN_ASSERT) && !AssertEnabled) || ((key == RTN_PRINT) && !PrintEnabled) || ((key == RTN_CONCAT) && !StringFunctionsEnabled); if (uncrunch) { uncrunchStatementMarker(); Crunch = false; } } crunchSymTableNodePtr(IdPtr); if (IdPtr->defn.info.routine.flags & ROUTINE_FLAG_ORDER) { if (NumOrderCalls == MAX_ORDERS) syntaxError(ABL_ERR_SYNTAX_TOO_MANY_ORDERS); crunchByte((unsigned char)(NumOrderCalls / 32)); crunchByte((unsigned char)(NumOrderCalls % 32)); NumOrderCalls++; } getToken(); SymTableNodePtr thisRoutineIdPtr = CurRoutineIdPtr; routineCall(IdPtr, 1); CurRoutineIdPtr = thisRoutineIdPtr; Crunch = true; } else assignmentStatement(IdPtr); } break; case TKN_REPEAT: repeatStatement(); break; case TKN_WHILE: whileStatement(); break; case TKN_IF: ifStatement(); break; case TKN_FOR: forStatement(); break; case TKN_SWITCH: switchStatement(); break; case TKN_TRANS: transStatement(); break; case TKN_TRANS_BACK: transBackStatement(); break; } //--------------------------------------------------------------------- // Now, make sure the statement is closed off with the proper block end // statement, if necessary (which is usually the case :). synchronize(statementEndList, NULL, NULL); if (tokenIn(statementStartList)) syntaxError(ABL_ERR_SYNTAX_MISSING_SEMICOLON); }