From 85daa1fc7e10dc07ac68bac9935c7b3dad4046b6 Mon Sep 17 00:00:00 2001 From: Thunder422 Date: Tue, 6 Nov 2012 21:19:25 -0500 Subject: [PATCH] translator: changed to Qt naming changed implementation of the equivalent and error status functions where the constant arrays were embedded into the functions also fixed argument name in a table search function missed previously and removed change comments that were only cluttering up the code --- commandhandlers.cpp | 103 ++-- table.cpp | 4 +- table.h | 2 +- test_ibcp.cpp | 20 +- tokenhandlers.cpp | 161 +++---- translator.cpp | 1099 +++++++++++++++++++------------------------ translator.h | 184 +++++--- 7 files changed, 741 insertions(+), 832 deletions(-) diff --git a/commandhandlers.cpp b/commandhandlers.cpp index fc54da9..90506fb 100644 --- a/commandhandlers.cpp +++ b/commandhandlers.cpp @@ -61,22 +61,22 @@ TokenStatus Assign_CmdHandler(Translator &t, CmdItem *cmd_item, Token *token) case EOL_Code: // check done stack is empty before calling process_final_operand() // to avoid bug error check for empty done stack in find_code() - if (t.done_stack.empty()) + if (t.m_doneStack.empty()) { // save expected type DataType datatype = cmd_item->token->dataType(); cmd_item->token = token; // point error to end-of-statement token - return Translator::errStatusExpected(datatype); + return Translator::expectedErrStatus(datatype); } // turnoff reference flag of assign token, no longer needed cmd_item->token->setReference(false); - return t.process_final_operand(cmd_item->token, NULL, 1); + return t.processFinalOperand(cmd_item->token, NULL, 1); default: // token was not expected command - switch (t.mode) + switch (t.m_mode) { case AssignmentList_TokenMode: // point error to unexpected token @@ -84,13 +84,13 @@ TokenStatus Assign_CmdHandler(Translator &t, CmdItem *cmd_item, Token *token) return ExpEqualOrComma_TokenStatus; case Expression_TokenMode: - if (t.state == Translator::BinOp_State) + if (t.m_state == Translator::BinOp_State) { // point error to unexpected token cmd_item->token = token; return ExpOpOrEnd_TokenStatus; } - status = Translator::errStatusExpected(t.cmd_stack.top().token + status = Translator::expectedErrStatus(t.m_cmdStack.top().token ->dataType()); // point error to unexpected token after setting error cmd_item->token = token; @@ -115,31 +115,31 @@ TokenStatus Print_CmdHandler(Translator &t, CmdItem *cmd_item, Token *token) { case Comma_Code: // make sure the expression before comma is complete - status = t.expression_end(); + status = t.expressionEnd(); if (status != Good_TokenStatus) { return status; } - status = t.add_print_code(); + status = t.addPrintCode(); if (status > Good_TokenStatus) { return status; } // append comma (advance to next column) token to output - t.output->append(new RpnItem(token)); + t.m_output->append(new RpnItem(token)); // set PRINT command item flag in case last item in statement // (resets PrintFunc_CmdFlag if set) - t.cmd_stack.top().flag = PrintStay_CmdFlag; + t.m_cmdStack.top().flag = PrintStay_CmdFlag; // switch back to operand state (expecting operand next) - t.state = Translator::OperandOrEnd_State; + t.m_state = Translator::OperandOrEnd_State; return Good_TokenStatus; case SemiColon_Code: - status = t.add_print_code(); + status = t.addPrintCode(); if (status == Good_TokenStatus) { // print code added, delete semicolon token @@ -148,16 +148,16 @@ TokenStatus Print_CmdHandler(Translator &t, CmdItem *cmd_item, Token *token) else if (status == Null_TokenStatus) { // check if last token added was a print function - if (t.cmd_stack.top().flag & PrintFunc_CmdFlag) + if (t.m_cmdStack.top().flag & PrintFunc_CmdFlag) { // set semicolon subcode flag on print function - t.output->last()->token->setSubCodeMask(SemiColon_SubCode); + t.m_output->last()->token()->setSubCodeMask(SemiColon_SubCode); // sub-code set, delete semicolon token delete token; } else // no expression, add dummy semicolon token { - t.output->append(new RpnItem(token)); + t.m_output->append(new RpnItem(token)); } } else // an error occurred @@ -167,21 +167,21 @@ TokenStatus Print_CmdHandler(Translator &t, CmdItem *cmd_item, Token *token) // set PRINT command item flag in case last item in statement // (resets PrintFunc_CmdFlag if set) - t.cmd_stack.top().flag = PrintStay_CmdFlag; + t.m_cmdStack.top().flag = PrintStay_CmdFlag; // switch back to operand state (expecting operand next) - t.state = Translator::OperandOrEnd_State; + t.m_state = Translator::OperandOrEnd_State; return Good_TokenStatus; case EOL_Code: - status = t.add_print_code(); + status = t.addPrintCode(); if (status == Good_TokenStatus // data type specific code added? || status == Null_TokenStatus // or not stay on line? && !(cmd_item->flag & PrintStay_CmdFlag)) { // append the print token to go to newline at runtime - t.output->append(new RpnItem(cmd_item->token)); + t.m_output->append(new RpnItem(cmd_item->token)); // set good status; could be set to null status = Good_TokenStatus; } @@ -210,7 +210,7 @@ TokenStatus Let_CmdHandler(Translator &t, CmdItem *cmd_item, Token *token) // if it is then it means that the LET command was not completed cmd_item->token = token; // point to end-of-statement token // make sure done stack is not empty - if (t.done_stack.empty()) + if (t.m_doneStack.empty()) { return ExpAssignItem_TokenStatus; } @@ -231,36 +231,36 @@ TokenStatus Input_CmdHandler(Translator &t, CmdItem *cmd_item, Token *token) // PROCESS BEGIN/PROMPT // used input begin command flag instead of element pointer - if (!(t.cmd_stack.top().flag & InputBegin_CmdFlag)) // no begin code yet? + if (!(t.m_cmdStack.top().flag & InputBegin_CmdFlag)) // no begin code yet? { - t.cmd_stack.top().flag |= InputBegin_CmdFlag; // begin processed + t.m_cmdStack.top().flag |= InputBegin_CmdFlag; // begin processed if (cmd_item->token->isCode(InputPrompt_Code)) { - if (t.done_stack.empty()) + if (t.m_doneStack.empty()) { // report error against token cmd_item->token = token; // set error token return ExpStrExpr_TokenStatus; } - if (Translator::equivalentDataType(t.done_stack.top().rpnItem - ->token->dataType()) != String_DataType) + if (Translator::equivalentDataType(t.m_doneStack.top().rpnItem + ->token()->dataType()) != String_DataType) { // don't delete token, caller will delete it // report error against first token of expression on done stack - token = t.done_stack.top().first - ->setThrough(t.done_stack.top().last); + token = t.m_doneStack.top().first + ->setThrough(t.m_doneStack.top().last); // delete last token if close paren, remove from done stack - t.delete_close_paren(t.done_stack.pop().rpnItem->token); + t.deleteCloseParen(t.m_doneStack.pop().rpnItem->token()); cmd_item->token = token; // set error token return ExpStrExpr_TokenStatus; } - if (t.table.flags(code) & EndStmt_Flag) + if (t.m_table.flags(code) & EndStmt_Flag) { cmd_item->token = token; // set error token return ExpOpSemiOrComma_TokenStatus; } // change token to InputBeginStr and set sub-code - t.table.setToken(token, InputBeginStr_Code); + t.m_table.setToken(token, InputBeginStr_Code); switch (code) { case Comma_Code: @@ -273,49 +273,49 @@ TokenStatus Input_CmdHandler(Translator &t, CmdItem *cmd_item, Token *token) cmd_item->token = token; // set error token return ExpSemiCommaOrEnd_TokenStatus; } - status = t.process_final_operand(token, NULL, 0); + status = t.processFinalOperand(token, NULL, 0); if (status == Good_TokenStatus) { // set pointer to new end of output - t.cmd_stack.top().index = t.output->size(); + t.m_cmdStack.top().index = t.m_output->size(); } else { ;//cmd_item->token = token; // set error token (2011-03-24) } - t.mode = Reference_TokenMode; // change mode + t.m_mode = Reference_TokenMode; // change mode // set state for first variable - t.state = Translator::Operand_State; + t.m_state = Translator::Operand_State; return status; } // Input_Code - if (!t.done_stack.empty()) + if (!t.m_doneStack.empty()) { // create new token for InputBegin // insert at begin of command before first variable - t.output->insert(t.cmd_stack.top().index++, - new RpnItem(t.table.newToken(InputBegin_Code))); + t.m_output->insert(t.m_cmdStack.top().index++, + new RpnItem(t.m_table.newToken(InputBegin_Code))); } // if no variable on done stack, error will be reported below // now continue with input variable } // PROCESS INPUT VARIABLE - if (t.state != Translator::EndStmt_State) + if (t.m_state != Translator::EndStmt_State) { - if (t.done_stack.empty()) + if (t.m_doneStack.empty()) { cmd_item->token = token; // set error token return ExpVar_TokenStatus; } // set token for data type specific input assign token - t.table.setToken(token, InputAssign_Code); + t.m_table.setToken(token, InputAssign_Code); // set reference flag to be handled correctly in find_code token->setReference(); // find appropriate input assign code and append to output - status = t.process_final_operand(token, NULL, 0); + status = t.processFinalOperand(token, NULL, 0); if (status != Good_TokenStatus) { cmd_item->token = token; // set error token @@ -327,23 +327,23 @@ TokenStatus Input_CmdHandler(Translator &t, CmdItem *cmd_item, Token *token) // (which is first associated 2 code of input assign code) // insert input parse token into list at current index (update index) - t.output->insert(t.cmd_stack.top().index++, - new RpnItem(t.table.newToken( - t.table.assoc2Code(token->code())))); + t.m_output->insert(t.m_cmdStack.top().index++, + new RpnItem(t.m_table.newToken( + t.m_table.assoc2Code(token->code())))); // now process code if (code == Comma_Code) { - t.state = Translator::Operand_State; // for next variable + t.m_state = Translator::Operand_State; // for next variable return Good_TokenStatus; // done now, but expecting more variables } if (code == SemiColon_Code) { - t.cmd_stack.top().flag |= InputStay_CmdFlag; // stay on line - t.state = Translator::EndStmt_State; // expecting end-of-statment + t.m_cmdStack.top().flag |= InputStay_CmdFlag; // stay on line + t.m_state = Translator::EndStmt_State; // expecting end-of-statment return Good_TokenStatus; // done now, wait for end-of-statment } - if (!(t.table.flags(code) & EndStmt_Flag)) + if (!(t.m_table.flags(code) & EndStmt_Flag)) { // unexpected token cmd_item->token = token; // set error token @@ -355,13 +355,14 @@ TokenStatus Input_CmdHandler(Translator &t, CmdItem *cmd_item, Token *token) // PROCESS END OF INPUT // mark last parse code with end subcode - (*t.output)[t.cmd_stack.top().index - 1]->token->setSubCode(End_SubCode); + (*t.m_output)[t.m_cmdStack.top().index - 1]->token() + ->setSubCode(End_SubCode); // append the input token to go to newline at runtime - if (t.cmd_stack.top().flag & InputStay_CmdFlag) + if (t.m_cmdStack.top().flag & InputStay_CmdFlag) { cmd_item->token->setSubCode(Keep_SubCode); } - t.output->append(new RpnItem(cmd_item->token)); + t.m_output->append(new RpnItem(cmd_item->token)); return Good_TokenStatus; } diff --git a/table.cpp b/table.cpp index cf3f88f..8ec79d1 100644 --- a/table.cpp +++ b/table.cpp @@ -1800,12 +1800,12 @@ Code Table::search(const QStringRef &word1, const QStringRef &word2) // - search begins at entry after index // - search ends at end of section -Code Table::search(Code index, int _noperands) +Code Table::search(Code index, int nArguments) { for (Code i = index + 1; m_entry[i].name != NULL; i++) { if (m_entry[index].name.compare(m_entry[i].name) == 0 - && _noperands == nOperands(i)) + && nArguments == nOperands(i)) { return i; } diff --git a/table.h b/table.h index 931c5ac..e4df76e 100644 --- a/table.h +++ b/table.h @@ -137,7 +137,7 @@ class Table { // TABLE SPECIFIC FUNCTIONS Code search(SearchType type, const QStringRef &string); Code search(const QStringRef &word1, const QStringRef &word2); - Code search(Code code, int nargs); + Code search(Code code, int nArguments); Code search(Code code, DataType *dataType); bool match(Code code, DataType *dataType); }; diff --git a/test_ibcp.cpp b/test_ibcp.cpp index 4753583..f107c2b 100644 --- a/test_ibcp.cpp +++ b/test_ibcp.cpp @@ -387,24 +387,24 @@ void translateInput(QTextStream &cout, Translator &translator, Parser &parser, parser.setInput(QString(testInput)); do { // set parser operand state from translator (2011-03-27) - parser.setOperandState(translator.get_operand_state()); + parser.setOperandState(translator.getOperandState()); orgToken = token = parser.getToken(); // 2010-03-18: need to check for a parser error if (token->isType(Error_TokenType)) { printError(cout, token, token->string()); delete token; - translator.clean_up(); + translator.cleanUp(); return; } //printToken(cout, token, tab); - status = translator.add_token(token); + status = translator.addToken(token); } while (status == Good_TokenStatus); if (status == Done_TokenStatus) { // 2010-05-15: change rpn_list from Token pointers - QList *rpnList = translator.get_result(); + QList *rpnList = translator.getResult(); // 2010-05-15: added separate print loop so operands can also be printed printOutput(cout, "Output", *rpnList); // 2010-03-21: corrected to handle an empty RPN list @@ -432,9 +432,9 @@ void translateInput(QTextStream &cout, Translator &translator, Parser &parser, } else // check if token is open paren (2011-01-30 leak) { - translator.delete_open_paren(token); + translator.deleteOpenParen(token); } - translator.clean_up(); + translator.cleanUp(); cout << endl; // FIXME not needed, here to match current results } } @@ -533,14 +533,14 @@ void printOutput(QTextStream &cout, const QString &header, cout << header << ": "; foreach (RpnItem *rpnItem, rpnList) { - printSmallToken(cout, rpnItem->token); - if (rpnItem->noperands > 0) + printSmallToken(cout, rpnItem->token()); + if (rpnItem->nOperands() > 0) { QChar separator('['); - for (int i = 0; i < rpnItem->noperands; i++) + for (int i = 0; i < rpnItem->nOperands(); i++) { cout << separator; - printSmallToken(cout, rpnItem->operand[i]->token); + printSmallToken(cout, rpnItem->operand(i)->token()); separator = ','; } cout << ']'; diff --git a/tokenhandlers.cpp b/tokenhandlers.cpp index 7f6518d..0026ca9 100644 --- a/tokenhandlers.cpp +++ b/tokenhandlers.cpp @@ -50,9 +50,9 @@ TokenStatus Operator_Handler(Translator &t, Token *&token) { // only check mode if not in parentheses (expression) - if (t.count_stack.empty()) + if (t.m_countStack.empty()) { - switch (t.mode) + switch (t.m_mode) { case Command_TokenMode: case Assignment_TokenMode: @@ -72,7 +72,7 @@ TokenStatus Operator_Handler(Translator &t, Token *&token) } } - return t.process_first_operand(token); + return t.processFirstOperand(token); } @@ -86,40 +86,40 @@ TokenStatus Equal_Handler(Translator &t, Token *&token) Token *org_token; // only check mode if not in parentheses (expression) - if (t.count_stack.empty()) + if (t.m_countStack.empty()) { - switch (t.mode) + switch (t.m_mode) { case Command_TokenMode: case Assignment_TokenMode: // start of assign statement - status = t.set_assign_command(token, Assign_Code); + status = t.setAssignCommand(token, Assign_Code); if (status != Good_TokenStatus) { return status; } // switch straight to expression mode - t.mode = Expression_TokenMode; + t.m_mode = Expression_TokenMode; // expecting operand next - t.state = Translator::Operand_State; + t.m_state = Translator::Operand_State; return Good_TokenStatus; case AssignmentList_TokenMode: // comma puts AssignList on hold stack delete token; // assign list operator already on hold stack - status = t.check_assignlist_token(token); + status = t.checkAssignListToken(token); if (status != Good_TokenStatus) { return status; } - t.mode = Expression_TokenMode; // end of list, expression follows + t.m_mode = Expression_TokenMode; // end of list, expression follows // expecting operand next - t.state = Translator::Operand_State; + t.m_state = Translator::Operand_State; return Good_TokenStatus; case Expression_TokenMode: @@ -131,7 +131,7 @@ TokenStatus Equal_Handler(Translator &t, Token *&token) } // inside an expression, keep Eq_Code - return t.process_first_operand(token); + return t.processFirstOperand(token); } @@ -141,42 +141,42 @@ TokenStatus Equal_Handler(Translator &t, Token *&token) TokenStatus Comma_Handler(Translator &t, Token *&token) { - int noperands; + int nOperands; TokenStatus status; // only check mode if not in parentheses (expression) - if (t.count_stack.empty()) + if (t.m_countStack.empty()) { - switch (t.mode) + switch (t.m_mode) { case Command_TokenMode: case Assignment_TokenMode: // this is an assignment list // (comma puts AssignList on hold stack) // assignment for a comma separated list, change token - if (t.done_stack.empty()) // make sure stack not empty + if (t.m_doneStack.empty()) // make sure stack not empty { // if nothing before comma, comma unexpected // return appropriate error for mode - return t.mode == Command_TokenMode + return t.m_mode == Command_TokenMode ? ExpCmd_TokenStatus : ExpAssignItem_TokenStatus; } - status = t.set_assign_command(token, AssignList_Code); + status = t.setAssignCommand(token, AssignList_Code); if (status != Good_TokenStatus) { return status; } // comma separated assignment list - t.mode = AssignmentList_TokenMode; + t.m_mode = AssignmentList_TokenMode; break; case AssignmentList_TokenMode: // continuation a comma separated list delete token; // don't need comma token on stack - status = t.check_assignlist_token(token); + status = t.checkAssignListToken(token); if (status != Good_TokenStatus) { return status; @@ -188,7 +188,7 @@ TokenStatus Comma_Handler(Translator &t, Token *&token) // inside an expression, but not in array or function // check if command allows comma - status = t.call_command_handler(token); + status = t.callCommandHandler(token); if (status == Null_TokenStatus) // command didn't expect comma { // this can only occur in expression only test mode @@ -196,8 +196,8 @@ TokenStatus Comma_Handler(Translator &t, Token *&token) } return status; - case Reference_TokenMode: // 2011-03-20: added - return t.call_command_handler(token); + case Reference_TokenMode: + return t.callCommandHandler(token); // it is up to command handler to set state appropriately // XXX assume command used comma token (otherwise need to check) // XXX assume command set state according to its needs @@ -209,27 +209,28 @@ TokenStatus Comma_Handler(Translator &t, Token *&token) else { // inside an expression, check if in array or function - if (t.count_stack.top().noperands == 0) + if (t.m_countStack.top().nOperands == 0) { // inside parentheses return ExpOpOrParen_TokenStatus; } - else if (t.count_stack.top().nexpected > 0) // internal function? + else if (t.m_countStack.top().nExpected > 0) // internal function? { - Token *top_token = t.hold_stack.top().token; - if (t.count_stack.top().noperands == t.count_stack.top().nexpected) + Token *topToken = t.m_holdStack.top().token; + if (t.m_countStack.top().nOperands + == t.m_countStack.top().nExpected) { // number of arguments doesn't match current function's entry // see if function has multiple entries - if ((t.table.flags(top_token->code()) & Multiple_Flag) != 0) + if ((t.m_table.flags(topToken->code()) & Multiple_Flag) != 0) { // change token to next code (index) // (table entries have been validated during initialization) // (need to increment index before assignment) - t.count_stack.top().code = top_token->nextCode(); + t.m_countStack.top().code = topToken->nextCode(); // update number of expected operands - t.count_stack.top().nexpected - = t.table.nOperands(top_token->code()); + t.m_countStack.top().nExpected + = t.m_table.nOperands(topToken->code()); } else { @@ -238,21 +239,21 @@ TokenStatus Comma_Handler(Translator &t, Token *&token) } // check argument, change code and insert conversion - status = t.find_code(top_token, t.count_stack.top().noperands - 1); + status = t.findCode(topToken, t.m_countStack.top().nOperands - 1); if (status != Good_TokenStatus) { delete token; // delete comma token - token = top_token; // return token with error + token = topToken; // return token with error return status; } } // increment the number of operands - t.count_stack.top().noperands++; + t.m_countStack.top().nOperands++; // delete comma token, it's not needed delete token; } - t.state = Translator::Operand_State; + t.m_state = Translator::Operand_State; return Good_TokenStatus; } @@ -264,20 +265,20 @@ TokenStatus Comma_Handler(Translator &t, Token *&token) TokenStatus SemiColon_Handler(Translator &t, Token *&token) { TokenStatus status; - int noperands; + int nOperands; // make sure the expression before semicolon is complete - status = t.expression_end(); + status = t.expressionEnd(); if (status != Good_TokenStatus) { return status; } - status = t.call_command_handler(token); + status = t.callCommandHandler(token); // it is up to command handler to set state appropriately if (status == Null_TokenStatus) // command stack was empty { - if (t.done_stack.empty()) + if (t.m_doneStack.empty()) { // no tokens received yet return ExpCmd_TokenStatus; @@ -295,53 +296,53 @@ TokenStatus SemiColon_Handler(Translator &t, Token *&token) TokenStatus CloseParen_Handler(Translator &t, Token *&token) { - Token *top_token; - int noperands; // for array/function support + Token *topToken; + int nOperands; // for array/function support int done_push = true; // for print-only functions // do closing parentheses processing - if (t.hold_stack.empty()) + if (t.m_holdStack.empty()) { // oops, stack is empty return BUG_DoneStackEmptyParen; } // don't pop top token yet in case error occurs - top_token = t.hold_stack.top().token; + topToken = t.m_holdStack.top().token; - if (t.count_stack.empty()) + if (t.m_countStack.empty()) { return NoOpenParen_TokenStatus; } - noperands = t.count_stack.pop().noperands; - if (noperands == 0) + nOperands = t.m_countStack.pop().nOperands; + if (nOperands == 0) { // just a parentheses expression - if (!top_token->isCode(OpenParen_Code)) + if (!topToken->isCode(OpenParen_Code)) { // oops, no open parentheses return BUG_UnexpectedCloseParen; // this should not happen } // clear reference for item on top of done stack - t.done_stack.top().rpnItem->token->setReference(false); + t.m_doneStack.top().rpnItem->token()->setReference(false); // replace first and last operands of item on done stack - t.delete_open_paren(t.done_stack.top().first); - t.done_stack.top().first = top_token; - t.delete_close_paren(t.done_stack.top().last); - t.done_stack.top().last = token; + t.deleteOpenParen(t.m_doneStack.top().first); + t.m_doneStack.top().first = topToken; + t.deleteCloseParen(t.m_doneStack.top().last); + t.m_doneStack.top().last = token; // mark close paren token as used for last operand and pending paren // (so that it doesn't get deleted until its not used anymore) token->setSubCodeMask(Last_SubCode + Used_SubCode); // set pending parentheses token pointer - t.pending_paren = token; + t.m_pendingParen = token; } else // array or function { int operand_index; // make sure token is an array or a function - if (!top_token->hasParen()) + if (!topToken->hasParen()) { // unexpected token on stack return BUG_UnexpectedToken; @@ -349,46 +350,46 @@ TokenStatus CloseParen_Handler(Translator &t, Token *&token) // set reference flag for array or function // (DefFuncP should not have reference set) - if (top_token->isType(Paren_TokenType)) + if (topToken->isType(Paren_TokenType)) { - top_token->setReference(); + topToken->setReference(); operand_index = 0; // not applicable } - else if (top_token->isType(DefFuncP_TokenType)) + else if (topToken->isType(DefFuncP_TokenType)) { operand_index = 0; // not applicable } else // INTERNAL FUNCTION { // check for number of arguments for internal functions - if (noperands != t.table.nOperands(top_token->code())) + if (nOperands != t.m_table.nOperands(topToken->code())) { return ExpOpOrComma_TokenStatus; } - operand_index = t.table.nOperands(top_token->code()) - 1; + operand_index = t.m_table.nOperands(topToken->code()) - 1; // tell process_final_operand() to use operand_index - noperands = 0; + nOperands = 0; } // change token operator code or insert conversion codes as needed - TokenStatus status = t.process_final_operand(top_token, token, - operand_index, noperands); + TokenStatus status = t.processFinalOperand(topToken, token, + operand_index, nOperands); if (status != Good_TokenStatus) { - // if top_token was not changed, pop it now - if (top_token == t.hold_stack.top().token) + // if topToken was not changed, pop it now + if (topToken == t.m_holdStack.top().token) { - t.hold_stack.resize(t.hold_stack.size() - 1); + t.m_holdStack.resize(t.m_holdStack.size() - 1); } delete token; // delete close paren token - token = top_token; // set token with error + token = topToken; // set token with error return status; } } // now pop the top token - t.hold_stack.resize(t.hold_stack.size() - 1); + t.m_holdStack.resize(t.m_holdStack.size() - 1); return Good_TokenStatus; } @@ -403,22 +404,22 @@ TokenStatus EndOfLine_Handler(Translator &t, Token *&token) // TODO this is end of statement processing // check for proper end of expression - TokenStatus status = t.expression_end(); + TokenStatus status = t.expressionEnd(); if (status != Good_TokenStatus) { return status; } // check for expression only mode - if (!t.exprmode) + if (!t.m_exprMode) { // process command on top of command stack - if (t.cmd_stack.empty()) + if (t.m_cmdStack.empty()) { - switch (t.mode) + switch (t.m_mode) { case Assignment_TokenMode: - if (t.state != Translator::BinOp_State) + if (t.m_state != Translator::BinOp_State) { return ExpAssignItem_TokenStatus; } @@ -434,12 +435,12 @@ TokenStatus EndOfLine_Handler(Translator &t, Token *&token) return BUG_InvalidMode; } } - status = t.call_command_handler(token); + status = t.callCommandHandler(token); if (status != Good_TokenStatus) { return status; } - t.cmd_stack.resize(t.cmd_stack.size() - 1); + t.m_cmdStack.resize(t.m_cmdStack.size() - 1); // upon return from the command handler, // the hold stack should have the null token on top // and done stack should be empty @@ -449,25 +450,25 @@ TokenStatus EndOfLine_Handler(Translator &t, Token *&token) else // handle expression only test mode { // check if find result is only thing on done stack - if (t.done_stack.empty()) + if (t.m_doneStack.empty()) { return BUG_DoneStackEmpty; } // pop result and delete any paren tokens in first/last operands - t.delete_open_paren(t.done_stack.top().first); - t.delete_close_paren(t.done_stack.pop().last); + t.deleteOpenParen(t.m_doneStack.top().first); + t.deleteCloseParen(t.m_doneStack.pop().last); } // pop and delete null token from top of stack - delete t.hold_stack.pop().token; + delete t.m_holdStack.pop().token; - if (!t.done_stack.empty()) + if (!t.m_doneStack.empty()) { return BUG_DoneStackNotEmpty; } // make sure command stack is empty (temporary TODO) - if (!t.cmd_stack.empty()) + if (!t.m_cmdStack.empty()) { return BUG_CmdStackNotEmpty; } diff --git a/translator.cpp b/translator.cpp index 27f2ff7..ffa0f86 100644 --- a/translator.cpp +++ b/translator.cpp @@ -374,11 +374,12 @@ // 2012-11-01 removed immediate command support #include "translator.h" +#include "tokenhandlers.h" // highest precedence value enum { - Highest_Precedence = 127 + HighestPrecedence = 127 // this value was selected as the highest value because it is the highest // one-byte signed value (in case the precedence member is changed to an // char); all precedences in the table must be below this value @@ -386,10 +387,7 @@ enum { // array of conversion codes [have data type] [need data type] -// 2010-05-15: add entries for TmpStr_DataType -// 2010-05-19: add entries for SubStr_DataType -// 2010-07-01: moved to begin of file -static Code cvtcode_have_need[numberof_DataType][numberof_DataType] = { +static Code cvtCodeHaveNeed[numberof_DataType][numberof_DataType] = { { // have Double, need: Null_Code, // Double CvtInt_Code, // Integer @@ -427,80 +425,70 @@ static Code cvtcode_have_need[numberof_DataType][numberof_DataType] = { } }; -// 2010-05-22: equivalent data type array (moved 2010-07-01) -static DataType equivalent_datatype[numberof_DataType] = { - Double_DataType, // Double - Integer_DataType, // Integer - String_DataType, // String - String_DataType, // TmpStr - String_DataType // SubStr -}; - +// function to return equivalent data type for data type +// (really to convert the various string data types to String_DataType) DataType Translator::equivalentDataType(DataType dataType) { - return equivalent_datatype[dataType]; + static DataType equivalent[numberof_DataType] = { + Double_DataType, // Double + Integer_DataType, // Integer + String_DataType, // String + String_DataType, // TmpStr + String_DataType // SubStr + }; + + return equivalent[dataType]; } -// 2010-07-03: error status data type array -static struct { - TokenStatus expected; - TokenStatus actual; - TokenStatus variable; -} errstatus_datatype[sizeof_DataType] = { - { // Double - ExpNumExpr_TokenStatus, - ExpStrExpr_TokenStatus, - ExpDblVar_TokenStatus - }, - { // Integer - ExpNumExpr_TokenStatus, - ExpStrExpr_TokenStatus, - ExpIntVar_TokenStatus - }, - { // String - ExpStrExpr_TokenStatus, - ExpNumExpr_TokenStatus, - ExpStrItem_TokenStatus - }, - { // TmpStr - ExpStrExpr_TokenStatus, - ExpNumExpr_TokenStatus, - BUG_InvalidDataType - }, - { // SubStr - ExpStrExpr_TokenStatus, - ExpNumExpr_TokenStatus, - BUG_InvalidDataType - }, - { // numberof - BUG_InvalidDataType, - BUG_InvalidDataType, - BUG_InvalidDataType - }, - { // None - ExpExpr_TokenStatus, // changed from Invalid (2011-01-01) - BUG_InvalidDataType, - ExpAssignItem_TokenStatus - } -}; - -TokenStatus Translator::errStatusExpected(DataType dataType) +// function to return the token error status for an expected data type +TokenStatus Translator::expectedErrStatus(DataType dataType) { - return errstatus_datatype[dataType].expected; + static TokenStatus tokenStatus[sizeof_DataType] = { + ExpNumExpr_TokenStatus, // Double + ExpNumExpr_TokenStatus, // Integer + ExpStrExpr_TokenStatus, // String + ExpStrExpr_TokenStatus, // TmpStr + ExpStrExpr_TokenStatus, // SubStr + BUG_InvalidDataType, // numberof + ExpExpr_TokenStatus // None + }; + + return tokenStatus[dataType]; } -TokenStatus Translator::errStatusActual(DataType dataType) +// function to return the token error status for an actual data type +TokenStatus Translator::actualErrStatus(DataType dataType) { - return errstatus_datatype[dataType].actual; + static TokenStatus tokenStatus[sizeof_DataType] = { + ExpStrExpr_TokenStatus, // Double + ExpStrExpr_TokenStatus, // Integer + ExpNumExpr_TokenStatus, // String + ExpNumExpr_TokenStatus, // TmpStr + ExpNumExpr_TokenStatus, // SubStr + BUG_InvalidDataType, // numberof + BUG_InvalidDataType // None + }; + + return tokenStatus[dataType]; } -TokenStatus Translator::errStatusVariable(DataType dataType) +// function to return the token error status for a variable data type +TokenStatus Translator::variableErrStatus(DataType dataType) { - return errstatus_datatype[dataType].variable; + static TokenStatus tokenStatus[sizeof_DataType] = { + ExpDblVar_TokenStatus, // Double + ExpIntVar_TokenStatus, // Integer + ExpStrItem_TokenStatus, // String + BUG_InvalidDataType, // TmpStr + BUG_InvalidDataType, // SubStr + BUG_InvalidDataType, // numberof + ExpAssignItem_TokenStatus // None + }; + + return tokenStatus[dataType]; } - // function to add a token to the output list, but token may be placed // on hold stack pending adding it to the output list so that higher // precedence tokens may be added to the list first @@ -510,15 +498,13 @@ TokenStatus Translator::errStatusVariable(DataType dataType) // - error status returned when an error is detected // - token argument may be changed when an error is detected -// 2010-04-04: made argument a reference so different token can be returned -TokenStatus Translator::add_token(Token *&token) +TokenStatus Translator::addToken(Token *&token) { TokenStatus status; - DataType datatype; - if (state == Initial_State) + if (m_state == Initial_State) { - // 2010-03-21: check for end of line at begin of input + // check for end of line at begin of input if (token->isType(Operator_TokenType) && token->isCode(EOL_Code)) { delete token; // 2010-04-04: delete EOL token @@ -527,29 +513,26 @@ TokenStatus Translator::add_token(Token *&token) // push null token to be last operator on stack // to prevent from popping past bottom of stack - // 2010-06-02: replaced new and set_token() with new_token() - hold_stack.resize(hold_stack.size() + 1); - hold_stack.top().token = table.newToken(Null_Code); - hold_stack.top().first = NULL; + m_holdStack.resize(m_holdStack.size() + 1); + m_holdStack.top().token = m_table.newToken(Null_Code); + m_holdStack.top().first = NULL; - // 2010-06-10: initialize to FirstOperand instead of Operand - state = OperandOrEnd_State; + m_state = OperandOrEnd_State; } - // 2010-05-29: added check for command token + // added check for command token if (token->isType(Command_TokenType)) { - if (mode == Command_TokenMode) + if (m_mode == Command_TokenMode) { - if (table.tokenMode(token->code()) != Null_TokenMode) + if (m_table.tokenMode(token->code()) != Null_TokenMode) { - mode = table.tokenMode(token->code()); - cmd_stack.resize(cmd_stack.size() + 1); - cmd_stack.top().token = token; - // 2011-03-01: removed code member initialization - cmd_stack.top().flag = None_CmdFlag; // 2010-06-01: reset flag - // initilize index to current last index of output (2012-10-26) - cmd_stack.top().index = output->size(); + m_mode = m_table.tokenMode(token->code()); + m_cmdStack.resize(m_cmdStack.size() + 1); + m_cmdStack.top().token = token; + m_cmdStack.top().flag = None_CmdFlag; + // initialize index to current last index of output + m_cmdStack.top().index = m_output->size(); return Good_TokenStatus; // nothing more to do } else @@ -557,38 +540,35 @@ TokenStatus Translator::add_token(Token *&token) return BUG_NotYetImplemented; } } - // 2011-03-10: removed error, fall through so proper error is reported + // fall through so proper error is reported } - // 2011-03-19: implemented end statement mode - if (state == EndStmt_State && !(table.flags(token) & EndStmt_Flag)) + // check for end statement + if (m_state == EndStmt_State && !(m_table.flags(token) & EndStmt_Flag)) { return ExpEndStmt_TokenStatus; } - // check for both operand states (2010-06-10) - if (state == Operand_State || state == OperandOrEnd_State) + // check for both operand states + if (m_state == Operand_State || m_state == OperandOrEnd_State) { if (!token->isOperator()) { - // 2011-02-13: moved code to new function, replaced with call - return process_operand(token); + return processOperand(token); } - // 2010-06-06: end-of-statement code acceptable instead of operand - else if (table.flags(token) & EndExpr_Flag) + // end-of-statement code acceptable instead of operand + else if (m_table.flags(token) & EndExpr_Flag) { - if (state != OperandOrEnd_State) + if (m_state != OperandOrEnd_State) { // an operand is expected, get the appropriate error - // 2011-02-13: moved code to new function, replaced with call - return end_expression_error(); + return endExpressionError(); } // fall thru to process end of expression operator token } else // operator when expecting operand, must be a unary operator { - // 2011-02-13: moved code to new function, replaced with call - if (process_unary_operator(token, status) == false) + if (processUnaryOperator(token, status) == false) { return status; } @@ -597,8 +577,7 @@ TokenStatus Translator::add_token(Token *&token) } else // a binary operator is expected { - // 2011-02-13: moved code to new function, replaced with call - status = process_binary_operator(token); + status = processBinaryOperator(token); if (status != Good_TokenStatus) { return status; @@ -606,8 +585,7 @@ TokenStatus Translator::add_token(Token *&token) } // process all operators - // 2011-02-13: moved code to new function, replaced with call - return process_operator(token); + return processOperator(token); } @@ -626,93 +604,82 @@ TokenStatus Translator::add_token(Token *&token) // - non-parentheses token is pushed onto done stack, appended to output // - state is set to binary operator -// 2011-02-13: implemented new function from parts of add_token() -TokenStatus Translator::process_operand(Token *&token) +TokenStatus Translator::processOperand(Token *&token) { - // 2010-03-25: added parentheses support - // 2010-03-26: check for and add dummy token if necessary - // 2010-05-29: changed argument to token pointer - do_pending_paren(hold_stack.top().token); + // check for and add dummy token if necessary + doPendingParen(m_holdStack.top().token); - // 2010-04-25: set default data type for token if it has none - set_default_datatype(token); + // set default data type for token if it has none + setDefaultDataType(token); - // 2010-04-02: moved to after pending parentheses check if (token->hasParen()) { // token is an array or a function - // 2010-04-02: implemented array/function support - // 2010-06-08: added number of operands for internal functions if (token->isType(IntFuncP_TokenType)) { - // 2010-06-11: detect invalid print-only function early - // 2011-03-05: added check for non-empty hold stack - // 2011-03-07: modified check to not catch empty command stack here - // 2012-10-25: corrected null token check in case code is not valid - if ((table.flags(token->code()) & Print_Flag) - && (!cmd_stack.empty() - && !cmd_stack.top().token->isCode(Print_Code) - || !hold_stack.top().token->isNull())) + // detect invalid print-only function + if ((m_table.flags(token->code()) & Print_Flag) + && (!m_cmdStack.empty() + && !m_cmdStack.top().token->isCode(Print_Code) + || !m_holdStack.top().token->isNull())) { - // 2011-03-05: replaced error with expression type error TokenStatus status; - DataType datatype; - if ((status = get_expr_datatype(datatype)) == Good_TokenStatus) + DataType dataType; + if ((status = getExprDataType(dataType)) == Good_TokenStatus) { - status = errstatus_datatype[datatype].expected; + status = expectedErrStatus(dataType); } return status; } - // 2010-06-24: check if not in expression mode - switch (mode) + // check if not in expression mode + switch (m_mode) { case Command_TokenMode: - case Assignment_TokenMode: // moved here (2011-03-11) - if (count_stack.empty()) + case Assignment_TokenMode: + if (m_countStack.empty()) { - if (table.dataType(token->code()) != SubStr_DataType) + if (m_table.dataType(token->code()) != SubStr_DataType) { - // return appropriate error for mode (2011-03-11) - return mode == Command_TokenMode + // return appropriate error for mode + return m_mode == Command_TokenMode ? ExpCmd_TokenStatus : ExpAssignItem_TokenStatus; } - // 2010-07-29: set reference of sub-string function + // set reference of sub-string function token->setReference(); } - // check if first operand of sub-string (2010-10-10) - else if (hold_stack.top().token->reference() - && count_stack.top().noperands == 1) + // check if first operand of sub-string + else if (m_holdStack.top().token->reference() + && m_countStack.top().nOperands == 1) { return ExpStrVar_TokenStatus; } break; case AssignmentList_TokenMode: - if (table.dataType(token->code()) != SubStr_DataType) + if (m_table.dataType(token->code()) != SubStr_DataType) { // in a comma separated list - return errstatus_datatype[cmd_stack.top().token->dataType()] - .variable; + return variableErrStatus(m_cmdStack.top().token + ->dataType()); } - // 2010-07-29: set reference flag of sub-string function + // set reference flag of sub-string function token->setReference(); break; - case Reference_TokenMode: // added mode (2011-03-07) - if (count_stack.empty()) + case Reference_TokenMode: + if (m_countStack.empty()) { return ExpVar_TokenStatus; } break; } } - // for reference mode, only no parentheses tokens allowed (2011-03-07) - // added check for command mod, (2011-03-13) - else if (count_stack.empty() && !token->isType(Paren_TokenType)) + // for reference mode, only no parentheses tokens allowed + else if (m_countStack.empty() && !token->isType(Paren_TokenType)) { - // return appropriate error for mode (2011-03-14) - if (mode == Command_TokenMode || mode == Assignment_TokenMode) + // return appropriate error for mode + if (m_mode == Command_TokenMode || m_mode == Assignment_TokenMode) { if (token->isType(DefFuncP_TokenType)) { @@ -723,44 +690,42 @@ TokenStatus Translator::process_operand(Token *&token) } return ExpEqualOrComma_TokenStatus; } - else if (mode == Reference_TokenMode) + else if (m_mode == Reference_TokenMode) { return ExpVar_TokenStatus; } } // 2010-06-08: changed count stack to hold count items - count_stack.resize(count_stack.size() + 1); - count_stack.top().noperands = 1; // assume at least one + m_countStack.resize(m_countStack.size() + 1); + m_countStack.top().nOperands = 1; // assume at least one if (token->isType(IntFuncP_TokenType)) { - count_stack.top().nexpected = table.nOperands(token->code()); - - // 2010-06-29: save index of internal function's table entry - count_stack.top().code = token->code(); + m_countStack.top().nExpected = m_table.nOperands(token->code()); + m_countStack.top().code = token->code(); } else // !token->isType(IntFuncP_TokenType) { - count_stack.top().nexpected = 0; + m_countStack.top().nExpected = 0; } - hold_stack.resize(hold_stack.size() + 1); - hold_stack.top().token = token; - hold_stack.top().first = NULL; + m_holdStack.resize(m_holdStack.size() + 1); + m_holdStack.top().token = token; + m_holdStack.top().first = NULL; // leave state == Operand - state = Operand_State; // make sure not FirstOperand (2010-06-10) + m_state = Operand_State; // make sure not OperandOrEnd } else // !token->hasParen() { - // for reference mode, only no parentheses tokens allowed (2011-03-07) - if (mode == Reference_TokenMode && count_stack.empty() + // for reference mode, only no parentheses tokens allowed + if (m_mode == Reference_TokenMode && m_countStack.empty() && !token->isType(NoParen_TokenType)) { return ExpVar_TokenStatus; } // token is a variable or a function with no arguments - // 2010-04-12: set reference flag for variable or function + // set reference flag for variable or function if (token->isType(NoParen_TokenType) || token->isType(DefFuncN_TokenType)) { @@ -769,22 +734,21 @@ TokenStatus Translator::process_operand(Token *&token) // add token directly output list // and push element pointer on done stack - // 2010-05-15: create RPN item to add to output list - RpnItem *rpn_item = new RpnItem(token); - output->append(rpn_item); - done_stack.resize(done_stack.size() + 1); - done_stack.top().rpnItem = rpn_item; - done_stack.top().first = done_stack.top().last = NULL; - // in reference mode, have variable, set end expr state (2011-03-07) + RpnItem *rpnItem = new RpnItem(token); + m_output->append(rpnItem); + m_doneStack.resize(m_doneStack.size() + 1); + m_doneStack.top().rpnItem = rpnItem; + m_doneStack.top().first = m_doneStack.top().last = NULL; + // in reference mode, if have variable, set end expression state // otherwise next token must be a binary operator - state = mode == Reference_TokenMode && count_stack.empty() + m_state = m_mode == Reference_TokenMode && m_countStack.empty() ? EndExpr_State : BinOp_State; } - // if command mode then change to assignment mode (2011-03-11) - if (mode == Command_TokenMode) + // if command mode then change to assignment mode + if (m_mode == Command_TokenMode) { - mode = Assignment_TokenMode; + m_mode = Assignment_TokenMode; } return Good_TokenStatus; @@ -797,51 +761,48 @@ TokenStatus Translator::process_operand(Token *&token) // - for command and assignments modes, count stack determines error // - for expression mode, current expression type determines error -// 2011-02-13: implemented new function from parts of add_token() -TokenStatus Translator::end_expression_error(void) +TokenStatus Translator::endExpressionError(void) { TokenStatus status = Good_TokenStatus; - DataType datatype; + DataType dataType; // unexpected of end expression - determine error to return - switch (mode) + switch (m_mode) { case Command_TokenMode: case Assignment_TokenMode: case AssignmentList_TokenMode: - // 2010-06-26: make sure done stack is not empty - if (count_stack.empty()) + // make sure done stack is not empty + if (m_countStack.empty()) { - status = errstatus_datatype[cmd_stack.top().token->dataType()] - .variable; + status = variableErrStatus(m_cmdStack.top().token->dataType()); } - else if (count_stack.top().nexpected == 0) + else if (m_countStack.top().nExpected == 0) { // in array status = ExpNumExpr_TokenStatus; } - else if (count_stack.top().noperands == 1) + else if (m_countStack.top().nOperands == 1) { // in function at first argument (sub-string function) status = ExpStrVar_TokenStatus; } else // in function not at first argument { - status = errstatus_datatype[table - .operandDataType(count_stack.top().code, - count_stack.top().noperands - 1)].expected; + status = expectedErrStatus(m_table + .operandDataType(m_countStack.top().code, + m_countStack.top().nOperands - 1)); } break; case Expression_TokenMode: - // 2011-01-03: replaced code with function call - if ((status = get_expr_datatype(datatype)) == Good_TokenStatus) + if ((status = getExprDataType(dataType)) == Good_TokenStatus) { - status = errstatus_datatype[datatype].expected; + status = expectedErrStatus(dataType); } break; - case Reference_TokenMode: // 2011-03-24: added + case Reference_TokenMode: status = ExpVar_TokenStatus; break; @@ -853,17 +814,15 @@ TokenStatus Translator::end_expression_error(void) } -// 2011-02-13: implemented new function from parts of add_token() -bool Translator::process_unary_operator(Token *&token, TokenStatus &status) +bool Translator::processUnaryOperator(Token *&token, TokenStatus &status) { - // 2010-06-13: if command mode, then this is not the way it starts - // 2010-07-01: check if count stack is empty before checking mode - // 2011-03-07: added check for assignment and reference modes - if (count_stack.empty()) + // check if count stack is empty before checking mode + if (m_countStack.empty()) { - switch (mode) + switch (m_mode) { case Command_TokenMode: + // if command mode, then this is not the way it starts status = ExpCmd_TokenStatus; return false; @@ -872,8 +831,7 @@ bool Translator::process_unary_operator(Token *&token, TokenStatus &status) return false; case AssignmentList_TokenMode: - status = errstatus_datatype[cmd_stack.top().token->dataType()] - .variable; + status = variableErrStatus(m_cmdStack.top().token->dataType()); return false; case Reference_TokenMode: @@ -881,58 +839,50 @@ bool Translator::process_unary_operator(Token *&token, TokenStatus &status) return false; } } - // 2011-03-13: added check for sub-string assignment - else if (hold_stack.top().token->isDataType(SubStr_DataType) - && hold_stack.top().token->reference() - && count_stack.top().noperands == 1) + else if (m_holdStack.top().token->isDataType(SubStr_DataType) + && m_holdStack.top().token->reference() + && m_countStack.top().nOperands == 1) { status = ExpStrVar_TokenStatus; return false; } - Code unary_code = table.unaryCode(token->code()); + Code unary_code = m_table.unaryCode(token->code()); if (unary_code == Null_Code) { - DataType datatype; + DataType dataType; // oops, not a valid unary operator - // get data type of expr for appropriate error (2011-01-08) - if ((status = get_expr_datatype(datatype)) == Good_TokenStatus) + if ((status = getExprDataType(dataType)) == Good_TokenStatus) { - status = errstatus_datatype[datatype].expected; + status = expectedErrStatus(dataType); } return false; } // change token to unary operator token->setCode(unary_code); - // 2010-03-25: added check for opening parentheses if (unary_code == OpenParen_Code) { - // 2010-03-26: don't initialize last_precedence here - // 2010-03-26: check for and add dummy token if necessary - // 2010-05-29: changed argument to token pointer - do_pending_paren(hold_stack.top().token); + // check for and add dummy token if necessary + doPendingParen(m_holdStack.top().token); - // 2011-03-12: removed, empty count stack mode check above - - // 2011-01-04: assign current expr data type to paren token + // assign current expression data type to paren token DataType dataType = token->dataType(); - if ((status = get_expr_datatype(dataType)) != Good_TokenStatus) + if ((status = getExprDataType(dataType)) != Good_TokenStatus) { return false; } token->setDataType(dataType); // push open parentheses right on stack and return - hold_stack.resize(hold_stack.size() + 1); - hold_stack.top().token = token; - hold_stack.top().first = NULL; - state = Operand_State; - - // 2010-04-02: add a null counter to prevent commas - // 2010-06-09: changed count stack to hold count items - count_stack.resize(count_stack.size() + 1); - count_stack.top().noperands = 0; - count_stack.top().nexpected = 0; + m_holdStack.resize(m_holdStack.size() + 1); + m_holdStack.top().token = token; + m_holdStack.top().first = NULL; + m_state = Operand_State; + + // add a null counter to prevent commas + m_countStack.resize(m_countStack.size() + 1); + m_countStack.top().nOperands = 0; + m_countStack.top().nExpected = 0; status = Good_TokenStatus; return false; } @@ -951,22 +901,21 @@ bool Translator::process_unary_operator(Token *&token, TokenStatus &status) // - error occurs if end statement operator in uncompleted multiple // assignment statement -// 2011-02-13: implemented new function from parts of add_token() -TokenStatus Translator::process_binary_operator(Token *&token) +TokenStatus Translator::processBinaryOperator(Token *&token) { TokenStatus status = Good_TokenStatus; - // 2010-10-10: check if after first operand of sub-string assignment - // 2011-03-09: moved command check to beginning - // 2012-10-25: make sure token has table entry before checking code - if (hold_stack.top().token->reference() && count_stack.top().noperands == 1 + // check if after first operand of sub-string assignment + // make sure token has table entry before checking code + if (m_holdStack.top().token->reference() + && m_countStack.top().nOperands == 1 && (!token->hasTableEntry() || !token->isCode(Comma_Code))) { // only a comma is allowed here return ExpComma_TokenStatus; } - // 2011-03-05: added end of expression token expected check - if (state == EndExpr_State && !(table.flags(token) & EndExpr_Flag)) + // end of expression token expected check + if (m_state == EndExpr_State && !(m_table.flags(token) & EndExpr_Flag)) { // TODO currently only occurs after print function // TODO add correct error based on current command @@ -977,29 +926,24 @@ TokenStatus Translator::process_binary_operator(Token *&token) if (!token->isOperator()) { // state == BinOp_State, but token is not an operator - // 2011-03-12: replaced code with call to new function - return operator_error(); + return operatorError(); } - // 2010-03-21: changed unary operator check - else if (table.isUnaryOperator(token->code())) + else if (m_table.isUnaryOperator(token->code())) { status = ExpBinOpOrEnd_TokenStatus; } - // 2011-03-09: moved check for first operand to beginning above - // 2010-03-26: initialize last precedence before emptying stack for ')' + // initialize last precedence before emptying stack for ')' else if (token->isCode(CloseParen_Code)) { - // 2010-03-26: check for and add dummy token if necessary - // before emptying stack - // 2010-05-29: changed argument to token pointer - do_pending_paren(hold_stack.top().token); + // check for and add dummy token if necessary before emptying stack + doPendingParen(m_holdStack.top().token); // now set last precedence to highest in case no operators in ( ) - last_precedence = Highest_Precedence; + m_lastPrecedence = HighestPrecedence; } - // 2010-06-26: added checking at end of statement - else if (table.flags(token) & EndStmt_Flag - && mode == AssignmentList_TokenMode) + // checking at end of statement + else if (m_table.flags(token) & EndStmt_Flag + && m_mode == AssignmentList_TokenMode) { // no equal token received yet status = ExpEqualOrComma_TokenStatus; @@ -1020,75 +964,54 @@ TokenStatus Translator::process_binary_operator(Token *&token) // - after higher precedence operators are processed from the hold stack, // the token handler for the operator is called -// 2010-04-13: made argument a reference so different value can be returned -// 2010-04-25: implemented data type handling for non-assignment operators -// removed popping of operands, find_code() does this -// removed unary operator check -// 2010-05-08: removed temporary assignment code, find_code() now handles -// assignment operators but only last assignment list operand -// 2010-07-01: removed assignment and assignment list code, now handled in -// Equal_Handler(), Comma_Handler() and Assign_CmdHandler() -// 2010-08-07: check second operator or binary operator or only operand of -// unary operator -// 2010-03-25: added parentheses support -// 2010-03-26: replaced code with process_final_operand() function call -// 2010-05-29: changed process_final_operand() argument to token pointer -// 2010-06-05: do before assign check, which will append to output -// 2010-08-22: moved to before final operand processing -// 2011-01-13: added first operand token pointer (from hold stack) -// 2011-02-13: renamed from add_operator(), added code from add_token() -TokenStatus Translator::process_operator(Token *&token) +TokenStatus Translator::processOperator(Token *&token) { - // 2010-04-02: changed stack top precedence to work with paren tokens - // 2011-03-27: unary operators don't force other tokens from hold stack - while (table.precedence(hold_stack.top().token) - >= table.precedence(token->code()) - && !table.isUnaryOperator(token->code())) + // unary operators don't force other tokens from hold stack + while (m_table.precedence(m_holdStack.top().token) + >= m_table.precedence(token->code()) + && !m_table.isUnaryOperator(token->code())) { // pop operator on top of stack and add it to the output - // 2010-04-13: set top_token so reference can be passed - Token *top_token = hold_stack.top().token; - // don't pop token in case error occurs (2011-01-30 leak) + Token *topToken = m_holdStack.top().token; + // (don't pop token here in case error occurs) - do_pending_paren(top_token); + doPendingParen(topToken); // change token operator code or insert conversion codes as needed - TokenStatus status = process_final_operand(top_token, - hold_stack.top().first, - table.isUnaryOperator(top_token->code()) ? 0 : 1); + TokenStatus status = processFinalOperand(topToken, + m_holdStack.top().first, + m_table.isUnaryOperator(topToken->code()) ? 0 : 1); if (status != Good_TokenStatus) { - delete token; // delete token (2011-01-30 leak) - token = top_token; // 2010-04-13: return token with error + delete token; + token = topToken; // return token with error return status; } // save precedence of operator being added // (doesn't matter if not currently within parentheses, // it will be reset upon next open parentheses) - last_precedence = table.precedence(top_token->code()); + m_lastPrecedence = m_table.precedence(topToken->code()); - hold_stack.resize(hold_stack.size() - 1); + m_holdStack.resize(m_holdStack.size() - 1); } // check for special token processing - // 2010-03-25: change code to switch and added closing parentheses support - // 2010-05-28: change code from switch to token handler functions - TokenHandler token_handler = table.tokenHandler(token->code()); - if (token_handler == NULL) // no special handler? + TokenHandler tokenHandler = m_table.tokenHandler(token->code()); + if (tokenHandler == NULL) // no special handler? { - // check for command token with no token handler (2011-03-12) + // check for command token with no token handler if (token->isType(Command_TokenType)) { // valid commands in BinOp state must have a token handler - return operator_error(); + return operatorError(); } // use default operator token handler - token_handler = Operator_Handler; + tokenHandler = Operator_Handler; } - return (*token_handler)(*this, token); + return (*tokenHandler)(*this, token); } @@ -1097,15 +1020,14 @@ TokenStatus Translator::process_operator(Token *&token) // of array/user function, and if not inside parentheses, then error is // dependent on current token mode -// 2011-03-12: implemented new function from parts of process_binary_operator() -TokenStatus Translator::operator_error(void) +TokenStatus Translator::operatorError(void) { TokenStatus status; - if ((status = paren_status()) == Good_TokenStatus) + if ((status = parenStatus()) == Good_TokenStatus) { // error is dependent on mode - switch (mode) + switch (m_mode) { case Command_TokenMode: case Assignment_TokenMode: @@ -1133,55 +1055,50 @@ TokenStatus Translator::operator_error(void) // // - index argument is table index of operator to check against -// 2010-05-29: changed argument to token pointer -void Translator::do_pending_paren(Token *token) +void Translator::doPendingParen(Token *token) { - if (pending_paren != NULL) // is a closing parentheses token pending? - { - // may need to add a dummy token - // if the precedence of the last operator added within the - // last parentheses sub-expression is higher than or - // same as (operand state only) the operator - // 2010-05-29: changed index argument to token - int precedence = table.precedence(token); - if (last_precedence > precedence - || state == Operand_State && last_precedence == precedence) + if (m_pendingParen != NULL) // is a closing parentheses token pending? + { + // may need to add a dummy token if the precedence of the last + // operator added within the last parentheses sub-expression + // is higher than or same as (operand state only) the operator + int precedence = m_table.precedence(token); + if (m_lastPrecedence > precedence + || m_state == Operand_State && m_lastPrecedence == precedence) { - // 2010-05-29: replaced dummy token with parentheses sub-code flag - if (output->last()->token->isSubCode(Paren_SubCode)) + if (m_output->last()->token()->isSubCode(Paren_SubCode)) { - // already has parentheses sub-code set, so - // add dummy token - // 2010-05-15: create RPN item to add to output list - output->append(new RpnItem(pending_paren)); - // reset pending token and return (2011-01-22) - pending_paren = NULL; + // already has parentheses sub-code set, + // so add dummy token + m_output->append(new RpnItem(m_pendingParen)); + // reset pending token and return + m_pendingParen = NULL; return; } else { - QList::iterator last = output->end() - 1; - if (table.flags((*last)->token) & Hidden_Flag) + QList::iterator last = m_output->end() - 1; + if (m_table.flags((*last)->token()) & Hidden_Flag) { // last token added is a hidden code - last--; // get token before this + last--; // so get token before hidden code } - (*last)->token->setSubCodeMask(Paren_SubCode); + (*last)->token()->setSubCodeMask(Paren_SubCode); } // TODO something needed on done stack? // TODO (reference flag already cleared by close parentheses) } - // check if being used as last operand before deleting (2011-01-22) - if (pending_paren->isSubCode(Last_SubCode)) + // check if being used as last operand before deleting + if (m_pendingParen->isSubCode(Last_SubCode)) { // still used as last operand token, just clear used flag - pending_paren->clearSubCodeMask(Used_SubCode); + m_pendingParen->clearSubCodeMask(Used_SubCode); } else // don't need pending token { - delete pending_paren; // release it's memory + delete m_pendingParen; // release it's memory } - pending_paren = NULL; // reset pending token + m_pendingParen = NULL; // reset pending token } } @@ -1194,8 +1111,7 @@ void Translator::do_pending_paren(Token *token) // - no action if first operand token does not have a table entry // - no action if first operand token is not a closing parentheses token -// 2011-01-22: new function to delete a open paren token -void Translator::delete_open_paren(Token *first) +void Translator::deleteOpenParen(Token *first) { if (first != NULL && first->hasTableEntry() && first->isCode(OpenParen_Code)) { @@ -1215,13 +1131,11 @@ void Translator::delete_open_paren(Token *first) // as a dummy parentheses token, then last operand flag is cleared // - if closing parentheses token is not being used, then it is deleted -// 2011-01-15: new function to delete a close paren token -void Translator::delete_close_paren(Token *last) +void Translator::deleteCloseParen(Token *last) { - // 2011-01-16: added check if token has table entry if (last != NULL && last->hasTableEntry() && last->isCode(CloseParen_Code)) { - // 2011-01-22: check if parentheses token is still being used + // check if parentheses token is still being used if (last->isSubCode(Used_SubCode)) { // no longer used as last token @@ -1241,35 +1155,34 @@ void Translator::delete_close_paren(Token *last) // - attaches first operand token from operand on top of done stack // - no first operand token for unary operators -// 2011-01-14: new function created (code from Operator/Equal handlers) -TokenStatus Translator::process_first_operand(Token *&token) +TokenStatus Translator::processFirstOperand(Token *&token) { - Token *first = NULL; // first operand token (2011-01-14) + Token *first = NULL; // first operand token - // check first operand of binary operators (2010-08-07) - if (!table.isUnaryOperator(token->code())) + // check first operand of binary operators + if (!m_table.isUnaryOperator(token->code())) { // changed token operator code or insert conversion codes as needed - Token *org_token = token; - TokenStatus status = find_code(token, 0, &first); + Token *orgToken = token; + TokenStatus status = findCode(token, 0, &first); if (status != Good_TokenStatus) { - // check if different token has error (2011-01-30 leak) - if (token != org_token) + // check if different token has error + if (token != orgToken) { - delete org_token; // delete operator token + delete orgToken; // delete operator token } return status; } } // push it onto the holding stack - hold_stack.resize(hold_stack.size() + 1); - hold_stack.top().token = token; - hold_stack.top().first = first; // attach first operand (2011-01-14) + m_holdStack.resize(m_holdStack.size() + 1); + m_holdStack.top().token = token; + m_holdStack.top().first = first; // attach first operand - // expecting another operand next (2010-06-10) - state = Translator::Operand_State; + // expecting another operand next + m_state = Translator::Operand_State; return Good_TokenStatus; } @@ -1297,143 +1210,139 @@ TokenStatus Translator::process_first_operand(Token *&token) // - from CloseParen_Handler, token2 is CloseParen token // - from Assign_CmdHandler, token2 will be NULL (not used) -// 2010-08-30: new function created -// 2011-01-13: added pointer to second token -TokenStatus Translator::process_final_operand(Token *&token, Token *token2, - int operand_index, int noperands) +TokenStatus Translator::processFinalOperand(Token *&token, Token *token2, + int operandIndex, int nOperands) { - bool done_push = true; // 2010-06-01: for print-only functions - Token *first; // 2011-01-15: first operand token - Token *last; // 2011-01-15: last operand token + bool donePush = true; // for print-only functions + Token *first; // first operand token + Token *last; // last operand token - if (noperands == 0) // internal function or operator + if (nOperands == 0) // internal function or operator { - TokenStatus status = find_code(token, operand_index, &first, &last); + TokenStatus status = findCode(token, operandIndex, &first, &last); if (status != Good_TokenStatus) { return status; } - // 2011-02-05: added check non-assignment operator - if ((table.flags(token->code()) & Reference_Flag)) + // check for non-assignment operator + if ((m_table.flags(token->code()) & Reference_Flag)) { // for assignment operators, nothing gets pushed to the done stack - done_push = false; + donePush = false; // get number of strings for this assignment operator - noperands = table.nStrings(token->code()); + nOperands = m_table.nStrings(token->code()); // no longer need the first and last operands - delete_open_paren(first); - delete_close_paren(last); + deleteOpenParen(first); + deleteCloseParen(last); } - // save string operands only (2010-08-07) - // get number of strings for non-sub-string codes (2010-12-24) - // include sub-string reference which are put on done stack (2011-02-01) + // save string operands only + // get number of strings for non-sub-string codes + // include sub-string reference, which are put on done stack else if ((!token->isDataType(SubStr_DataType) || token->reference())) { - // no operands for sub-string references (2011-02-01) - noperands = token->reference() ? 0 : table.nStrings(token->code()); + // no operands for sub-string references + nOperands = token->reference() + ? 0 : m_table.nStrings(token->code()); - // set first and last operands (2011-01-15) - delete_open_paren(first); + // set first and last operands + deleteOpenParen(first); if (token->isOperator()) { // if unary operator, then operator, else first from hold stack - // 2011-01-20: set first token to unary op - first = operand_index == 0 ? token : token2; + // (set first token to unary op) + first = operandIndex == 0 ? token : token2; // last operand from token that was on done stack } else // non-sub-string internal function { first = NULL; // token itself is first operand - delete_close_paren(last); + deleteCloseParen(last); last = token2; // last operand is CloseParen token } } - // don't push non-reference sub-string function (2010-12-25) - else // 2011-02-01: removed reference change, include sub-strings + // don't push non-reference sub-string function + else { - done_push = false; // don't push sub-string function on done stack - // set first/last operands of operand on done stack (2011-01-15) - delete_open_paren(done_stack.top().first); - done_stack.top().first = token; // set to sub-string function token - delete_close_paren(done_stack.top().last); - done_stack.top().last = token2; // set to CloseParen token + donePush = false; // don't push sub-string function on done stack + // set first/last operands of operand on done stack + deleteOpenParen(m_doneStack.top().first); + m_doneStack.top().first = token; // set to sub-str function token + deleteCloseParen(m_doneStack.top().last); + m_doneStack.top().last = token2; // set to CloseParen token } - // 2010-06-01: process print-only internal functions - // 2011-03-03: check for and function with no return value + // process print-only internal functions + // (check for function with no return value) if (token->isDataType(None_DataType)) { - if (table.flags(token->code()) & Print_Flag) + if (m_table.flags(token->code()) & Print_Flag) { - // 2011-03-03: removed PRINT command check, already performed // tell PRINT to stay on same line - // also set print function flag (2010-06-08) - cmd_stack.top().flag = PrintStay_CmdFlag | PrintFunc_CmdFlag; + m_cmdStack.top().flag = PrintStay_CmdFlag | PrintFunc_CmdFlag; } - done_push = false; // don't push on done stack - // delete closing parentheses if print function (2011-02-01 leak) - // 2011-03-05: added check, token2 could be null (e.g. print code) + donePush = false; // don't push on done stack + // delete closing parentheses if print function + // (token2 could be null, e.g. print code) if (token2 != NULL) { - // if print function, make sure expression ends (2011-03-05) - if (table.flags(token->code()) & Print_Flag) + // if print function, make sure expression ends + if (m_table.flags(token->code()) & Print_Flag) { - state = EndExpr_State; + m_state = EndExpr_State; } delete token2; } } } - else // array or user function (2011-01-15) + else // array or user function { first = NULL; // token itself is first operand last = token2; // token's CloseParen is last - // check for end of array in reference mode (2011-03-07) - if (mode == Reference_TokenMode && count_stack.empty()) + // check for end of array in reference mode + if (m_mode == Reference_TokenMode && m_countStack.empty()) { // have array element, set end expression state - state = EndExpr_State; + m_state = EndExpr_State; } } RpnItem **operand; - if (noperands == 0) // no string operands to save? + if (nOperands == 0) // no string operands to save? { operand = NULL; } else // pop string operands off of stack into new array { - operand = new RpnItem *[noperands]; - // 2010-05-15: save operands for storage in output list - for (int i = noperands; --i >= 0;) + operand = new RpnItem *[nOperands]; + // save operands for storage in output list + for (int i = nOperands; --i >= 0;) { - if (done_stack.empty()) + if (m_doneStack.empty()) { return BUG_DoneStackEmptyOperands; } // TODO need to keep first/last operands for array/function args - delete_open_paren(done_stack.top().first); - // check if operand's last token was CloseParen (2011-01-15) - delete_close_paren(done_stack.top().last); - operand[i] = done_stack.pop().rpnItem; + deleteOpenParen(m_doneStack.top().first); + // check if operand's last token was CloseParen + deleteCloseParen(m_doneStack.top().last); + operand[i] = m_doneStack.pop().rpnItem; } } // add token to output list and push element pointer on done stack - // 2010-05-15: create RPN item to add to output list - RpnItem *rpn_item = new RpnItem(token, noperands, operand); - // 2010-06-01: check if output item is to be pushed on done stack - output->append(rpn_item); - if (done_push) + RpnItem *rpnItem = new RpnItem(token, nOperands, operand); + m_output->append(rpnItem); + // check if output item is to be pushed on done stack + if (donePush) { // push index of rpm item about to be added to output list - done_stack.resize(done_stack.size() + 1); - done_stack.top().rpnItem = rpn_item; - done_stack.top().first = first; - done_stack.top().last = last; + m_doneStack.resize(m_doneStack.size() + 1); + m_doneStack.top().rpnItem = rpnItem; + m_doneStack.top().first = first; + m_doneStack.top().last = last; } return Good_TokenStatus; @@ -1453,126 +1362,115 @@ TokenStatus Translator::process_final_operand(Token *&token, Token *token2, // // - operand index must be valid to token code -// 2010-04-25: implemented new function -// 2010-05-08: added last_operand argument for assignment list processing -// 2010-07-01: removed last_operand argument, no longer needed -// 2010-08-30: only process one operand at a time, added operand_index arg -// 2011-01-15: added first/last token pointers arguments -TokenStatus Translator::find_code(Token *&token, int operand_index, - Token **first, Token **last) +TokenStatus Translator::findCode(Token *&token, int operandIndex, Token **first, + Token **last) { - if (done_stack.empty()) + if (m_doneStack.empty()) { // oops, there should have been operands on done stack return BUG_DoneStackEmptyFindCode; } - Token *top_token = done_stack.top().rpnItem->token; - // 2011-01-15: get first and last operands for top token - // 2011-01-22: used work pointers instead, set arguments if requested - Token *work_first = done_stack.top().first; - if (work_first == NULL) + Token *topToken = m_doneStack.top().rpnItem->token(); + // get first and last operands for top token + Token *workFirst = m_doneStack.top().first; + if (workFirst == NULL) { - work_first = top_token; // first operand not set, set to operand token + workFirst = topToken; // first operand not set, set to operand token } if (first != NULL) // requested by caller? { - *first = work_first; - done_stack.top().first = NULL; // prevent deletion below + *first = workFirst; + m_doneStack.top().first = NULL; // prevent deletion below } - Token *work_last = done_stack.top().last; - if (work_last == NULL) + Token *workLast = m_doneStack.top().last; + if (workLast == NULL) { - work_last = top_token; // last operand not set, set to operand token + workLast = topToken; // last operand not set, set to operand token } if (last != NULL) // requested by caller? { - *last = work_last; - done_stack.top().last = NULL; // prevent deletion below + *last = workLast; + m_doneStack.top().last = NULL; // prevent deletion below } - // 2010-05-08: check if reference is required for first operand - if (operand_index == 0 && token->reference()) + // check if reference is required for first operand + if (operandIndex == 0 && token->reference()) { - if (!top_token->reference()) + if (!topToken->reference()) { // need a reference, so return error - // only delete token if it's not an internal function (2010-10-09) + // only delete token if it's not an internal function if (!token->isType(IntFuncP_TokenType)) { // (internal function is on hold stack, will be deleted later) delete token; // delete the token } // return non-reference operand - // report entire expression (2011-01-16) - token = work_first->setThrough(work_last); + // (report entire expression) + token = workFirst->setThrough(workLast); - // delete last token if close paren (2011-01-30 leak) - delete_close_paren(work_last); + // delete last token if close paren + deleteCloseParen(workLast); // XXX check command on top of command stack XXX - // 2011-03-13: changed return value return ExpAssignItem_TokenStatus; } } else { // reset reference flag of operand - top_token->setReference(false); + topToken->setReference(false); } // see if main code's data type matches - DataType datatype = top_token->dataType(); - DataType operand_datatype = table.operandDataType(token->code(), - operand_index); - // 2010-10-04: actually check for exact match, not cvt_code is Null_Code - if (datatype == operand_datatype) // exact match? - { - // 2010-10-03: pop all references (for assignments) from stack - if (operand_datatype != String_DataType || token->reference()) + DataType dataType = topToken->dataType(); + DataType operandDataType = m_table.operandDataType(token->code(), + operandIndex); + if (dataType == operandDataType) // exact match? + { + // pop all references (for assignments) from stack + if (operandDataType != String_DataType || token->reference()) { // pop non-string from done stack - delete_open_paren(done_stack.top().first); - // check if operand's last token was CloseParen (2011-01-15) - delete_close_paren(done_stack.pop().last); + deleteOpenParen(m_doneStack.top().first); + // check if operand's last token was CloseParen + deleteCloseParen(m_doneStack.pop().last); } return Good_TokenStatus; } - Code cvt_code = cvtcode_have_need[datatype][operand_datatype]; + Code cvt_code = cvtCodeHaveNeed[dataType][operandDataType]; Code new_code = cvt_code == Invalid_Code ? Null_Code : token->code(); // see if any associated code's data types match - // 2010-05-08: get actual number of associated codes - // 2010-08-07: get start/end indexes to support second assoc codes group - int start = operand_index != 1 ? 0 : table.assoc2Index(token->code()); - int end = table.nAssocCodes(token->code()); - if (operand_index == 0 && table.assoc2Index(token->code()) != 0) + int start = operandIndex != 1 ? 0 : m_table.assoc2Index(token->code()); + int end = m_table.nAssocCodes(token->code()); + if (operandIndex == 0 && m_table.assoc2Index(token->code()) != 0) { // for first operand, end at begin of second group of associated codes - end = table.assoc2Index(token->code()); + end = m_table.assoc2Index(token->code()); } for (int i = start; i < end; i++) { - Code assoc_code = table.assocCode(token->code(), i); - DataType operand_datatype2 = table.operandDataType(assoc_code, - operand_index); - // 2010-10-04: actually check for exact match, not cvt_code is Null_Code - if (datatype == operand_datatype2) // exact match? + Code assoc_code = m_table.assocCode(token->code(), i); + DataType operandDatatype2 = m_table.operandDataType(assoc_code, + operandIndex); + if (dataType == operandDatatype2) // exact match? { // change token's code and data type to associated code - table.setToken(token, assoc_code); + m_table.setToken(token, assoc_code); - // 2010-10-03: pop all references (for assignments) from stack - if (operand_datatype2 != String_DataType || token->reference()) + // pop all references (for assignments) from stack + if (operandDatatype2 != String_DataType || token->reference()) { // pop non-string from done stack - delete_open_paren(done_stack.top().first); - // check if operand's last token was CloseParen (2011-01-15) - delete_close_paren(done_stack.pop().last); + deleteOpenParen(m_doneStack.top().first); + // check if operand's last token was CloseParen + deleteCloseParen(m_doneStack.pop().last); } return Good_TokenStatus; } - Code cvt_code2 = cvtcode_have_need[datatype][operand_datatype2]; + Code cvt_code2 = cvtCodeHaveNeed[dataType][operandDatatype2]; if (cvt_code2 != Invalid_Code && new_code == Null_Code) { new_code = assoc_code; @@ -1585,25 +1483,23 @@ TokenStatus Translator::find_code(Token *&token, int operand_index, if (!token->isCode(new_code)) // not the main code? { // change token's code and data type to associated code - table.setToken(token, new_code); - token->setDataType(table.dataType(token->code())); + m_table.setToken(token, new_code); + token->setDataType(m_table.dataType(token->code())); } - // is there an actual conversion code to insert? (2010-10-04) + // is there an actual conversion code to insert? if (cvt_code != Null_Code) { - // a conversion code implies a non-string on done stack (2010-09-11) + // a conversion code implies a non-string on done stack // pop non-string from done stack - delete_open_paren(done_stack.top().first); - // check if operand's last token was CloseParen (2011-01-15) - delete_close_paren(done_stack.pop().last); + deleteOpenParen(m_doneStack.top().first); + // check if operand's last token was CloseParen + deleteCloseParen(m_doneStack.pop().last); // INSERT CONVERSION CODE // create convert token with convert code // append token to end of output list (after operand) - // 2010-05-15: create RPN item to add to output list - // 2010-06-02: replaced code with call to new_token() - output->append(new RpnItem(table.newToken(cvt_code))); + m_output->append(new RpnItem(m_table.newToken(cvt_code))); } return Good_TokenStatus; @@ -1612,13 +1508,12 @@ TokenStatus Translator::find_code(Token *&token, int operand_index, // no match found, report error // change token to token with invalid data type and return error // use main code's expected data type for operand - // 2010-10-10: return expected variable error for references and sub-strings - // 2010-12-25: breakup single statement into if-else structure + // (return expected variable error for references and sub-strings) TokenStatus status; if (!token->reference()) { - status = errstatus_datatype[operand_datatype].expected; - // 2011-02-02: sub-string no longer needed with first/last operands + status = expectedErrStatus(operandDataType); + // sub-string no longer needed with first/last operands } else if (token->isDataType(SubStr_DataType)) { @@ -1626,13 +1521,13 @@ TokenStatus Translator::find_code(Token *&token, int operand_index, } else { - status = errstatus_datatype[operand_datatype].variable; + status = variableErrStatus(operandDataType); } - // report entire expression (2011-01-16) - token = work_first->setThrough(work_last); + // report entire expression + token = workFirst->setThrough(workLast); - // delete last token if close paren (2011-01-30 leak) - delete_close_paren(work_last); + // delete last token if close paren + deleteCloseParen(workLast); return status; } @@ -1649,26 +1544,25 @@ TokenStatus Translator::find_code(Token *&token, int operand_index, // - performs pending parentheses check before returning // - returns good status or error status -// 2010-06-03: created new function from code in EOL token handler -TokenStatus Translator::expression_end(void) +TokenStatus Translator::expressionEnd(void) { TokenStatus status; Token *token; // do end of statement processing - if (hold_stack.empty()) + if (m_holdStack.empty()) { // oops, stack is empty - return BUG_HoldStackEmpty; // 2010-04-26: changed bug named + return BUG_HoldStackEmpty; } - if ((status = paren_status()) != Good_TokenStatus) + if ((status = parenStatus()) != Good_TokenStatus) { return status; } else { - token = hold_stack.top().token; + token = m_holdStack.top().token; if (!token->hasTableEntry()) { return BUG_Debug2; @@ -1677,10 +1571,9 @@ TokenStatus Translator::expression_end(void) { // check if there is some unexpected token on hold stack // could be assignment on hold stack - switch (mode) + switch (m_mode) { - // 2011-03-12: removed command mode (can't happen) - + // note: Command_TokenMode can't happen here case Assignment_TokenMode: // expression hasn't started yet return ExpEqualOrComma_TokenStatus; @@ -1700,11 +1593,9 @@ TokenStatus Translator::expression_end(void) } } - // 2010-03-25: check if there is a pending closing parentheses - // 2010-03-26: replaced code with function call - // 2010-05-29: changed argument to token pointer + // check if there is a pending closing parentheses // pass Null_Code token (will always add dummy) - do_pending_paren(token); + doPendingParen(token); return Good_TokenStatus; } @@ -1723,23 +1614,22 @@ TokenStatus Translator::expression_end(void) // to determine if an operator or parentheses is expected, or an operator, // comma or parentheses is expected -// 2010-06-14: implement new function from other code -TokenStatus Translator::paren_status(void) +TokenStatus Translator::parenStatus(void) { - if (count_stack.empty()) + if (m_countStack.empty()) { // no parentheses return Good_TokenStatus; } // parentheses, array or function without closing parentheses - if (count_stack.top().noperands == 0) + if (m_countStack.top().nOperands == 0) { // open parentheses return ExpOpOrParen_TokenStatus; } - if (count_stack.top().nexpected == 0) + if (m_countStack.top().nExpected == 0) { // array, defined function or user function // (more subscripts/arguments possible) @@ -1748,11 +1638,11 @@ TokenStatus Translator::paren_status(void) // internal function int index; - Token *top_token = hold_stack.top().token; - if (count_stack.top().noperands == count_stack.top().nexpected) + Token *topToken = m_holdStack.top().token; + if (m_countStack.top().nOperands == m_countStack.top().nExpected) { - // check if there could be more arguments (2011-01-08) - if ((table.flags(top_token->code()) & Multiple_Flag) == 0) + // check if there could be more arguments + if ((m_table.flags(topToken->code()) & Multiple_Flag) == 0) { // internal function - at last argument (no more expected) return ExpOpOrParen_TokenStatus; @@ -1765,16 +1655,16 @@ TokenStatus Translator::paren_status(void) // internal function - more arguments expected // (number of arguments doesn't match function's entry) - if ((table.flags(top_token->code()) & Multiple_Flag) != 0 - && (index = table.search(top_token->code(), - count_stack.top().noperands)) > 0) + if ((m_table.flags(topToken->code()) & Multiple_Flag) != 0 + && (index = m_table.search(topToken->code(), + m_countStack.top().nOperands)) > 0) { // found alternate code matching current number of operands // (could be at last argument, could be more arguments) return ExpOpCommaOrParen_TokenStatus; } - // 2011-03-12: removed command mode (can't happen) - else if (mode == AssignmentList_TokenMode) + // note: Command_TokenMode can't happen here + else if (m_mode == AssignmentList_TokenMode) { // sub-string function return ExpComma_TokenStatus; @@ -1796,57 +1686,56 @@ TokenStatus Translator::paren_status(void) // - if internal function, then get it's current operand's data type // - if array or non-internal function, then data type is None -// 2011-01-02: implemented new function from parts of add_token() -TokenStatus Translator::get_expr_datatype(DataType &datatype) +TokenStatus Translator::getExprDataType(DataType &dataType) { TokenStatus status = Good_TokenStatus; - if (hold_stack.empty()) // at least NULL token should be on hold stack + if (m_holdStack.empty()) // at least NULL token should be on hold stack { status = BUG_HoldStackEmpty; } - else if (hold_stack.top().token->isOperator()) + else if (m_holdStack.top().token->isOperator()) { - Code code = hold_stack.top().token->code(); + Code code = m_holdStack.top().token->code(); if (code == Null_Code) { // nothing on hold stack, get expected type for command - if (cmd_stack.empty()) + if (m_cmdStack.empty()) { - if (!exprmode) + if (!m_exprMode) { status = BUG_CmdStackEmptyExpr; // this shouldn't happen } } else { - datatype = cmd_stack.top().token->dataType(); + dataType = m_cmdStack.top().token->dataType(); } } else if (code == OpenParen_Code) { // no operator, get data type of open parentheses (could be none) - datatype = hold_stack.top().token->dataType(); + dataType = m_holdStack.top().token->dataType(); } else // an regular operator on top of hold stack { - // datatype from operand of operator on top of hold stack + // data type from operand of operator on top of hold stack // (first operand for unary and second operand for binary operator) - datatype = table.operandDataType(code, - table.isUnaryOperator(code) ? 0 : 1); + dataType = m_table.operandDataType(code, + m_table.isUnaryOperator(code) ? 0 : 1); } } - else if (count_stack.empty()) // no parentheses, array or function? + else if (m_countStack.empty()) // no parentheses, array or function? { // this situation should have been handled above status = BUG_CountStackEmpty; // this shouldn't happen } - else if (count_stack.top().nexpected > 0) // internal function? + else if (m_countStack.top().nExpected > 0) // internal function? { - // datatype from current operator of internal function - datatype = table.operandDataType(count_stack.top().code, - count_stack.top().noperands - 1); + // data type from current operator of internal function + dataType = m_table.operandDataType(m_countStack.top().code, + m_countStack.top().nOperands - 1); } - else if (count_stack.top().noperands == 0) // in parentheses? + else if (m_countStack.top().nOperands == 0) // in parentheses? { // this situation should have been handled above status = BUG_UnexpParenExpr; @@ -1854,7 +1743,7 @@ TokenStatus Translator::get_expr_datatype(DataType &datatype) else // in array or non-internal function { // (cannot determine type of expression) - datatype = None_DataType; + dataType = None_DataType; } return status; } @@ -1871,31 +1760,29 @@ TokenStatus Translator::get_expr_datatype(DataType &datatype) // deletedunless it is the token reported as the error // - for errors, the token returned by the command handler is returned -// 2011-02-10: implement new function from parts of the EOL token handler -TokenStatus Translator::call_command_handler(Token *&token) +TokenStatus Translator::callCommandHandler(Token *&token) { - if (cmd_stack.empty()) + if (m_cmdStack.empty()) { // token was not expected // let caller report the appropriate error return Null_TokenStatus; } - // changed from pop, leave command on top of stack (2010-12-29) - CmdItem cmd_item = cmd_stack.top(); - CommandHandler cmd_handler = table.commandHandler(cmd_item.token->code()); - if (cmd_handler == NULL) // missing command handler? + CmdItem cmdItem = m_cmdStack.top(); + CommandHandler cmdHandler = m_table.commandHandler(cmdItem.token->code()); + if (cmdHandler == NULL) // missing command handler? { return BUG_NotYetImplemented; } - TokenStatus status = (*cmd_handler)(*this, &cmd_item, token); + TokenStatus status = (*cmdHandler)(*this, &cmdItem, token); if (status != Good_TokenStatus) { - // delete token if error at another token (2011-01-30 leak) - if (cmd_item.token != token) + // delete token if error at another token + if (cmdItem.token != token) { delete token; } - token = cmd_item.token; // command decided where error is + token = cmdItem.token; // command decided where error is } return status; } @@ -1905,46 +1792,44 @@ TokenStatus Translator::call_command_handler(Token *&token) // // - must be called after add_token() returns an error -void Translator::clean_up(void) +void Translator::cleanUp(void) { // clean up from error - while (!hold_stack.empty()) + while (!m_holdStack.empty()) { - // delete first token in command stack item (2011-01-30 leak) - delete_open_paren(hold_stack.top().first); - // 2010-04-04: added delete to free the token that was on the stack - delete hold_stack.pop().token; + // delete first token in command stack item + deleteOpenParen(m_holdStack.top().first); + // delete to free the token that was on the stack + delete m_holdStack.pop().token; } - while (!done_stack.empty()) + while (!m_doneStack.empty()) { - delete_open_paren(done_stack.top().first); - // check if operand's last token was CloseParen (2011-01-15) - delete_close_paren(done_stack.pop().last); + deleteOpenParen(m_doneStack.top().first); + // check if operand's last token was CloseParen + deleteCloseParen(m_doneStack.pop().last); } - // 2010-04-02: comma support - need to empty count_stack - while (!count_stack.empty()) + // comma support - need to empty count_stack + while (!m_countStack.empty()) { - count_stack.resize(count_stack.size() - 1); + m_countStack.resize(m_countStack.size() - 1); } - // 2011-01-16: moved to after stack cleanups (so last tokens still exist) - while (!output->isEmpty()) + while (!m_output->isEmpty()) { - // 2010-04-04: added delete to free the token that was in the list - delete output->takeLast(); + // delete to free the token that was in the list + delete m_output->takeLast(); } - delete output; - output = NULL; - // 2010-03-25: parentheses support - need to delete pending parentheses - if (pending_paren != NULL) + delete m_output; + m_output = NULL; + // need to delete pending parentheses + if (m_pendingParen != NULL) { - delete pending_paren; - pending_paren = NULL; + delete m_pendingParen; + m_pendingParen = NULL; } - // 2010-06-02: command support - need to empty command_stack - while (!cmd_stack.empty()) + while (!m_cmdStack.empty()) { - // delete token in command stack item (2011-01-30 leak) - delete cmd_stack.pop().token; + // delete token in command stack item + delete m_cmdStack.pop().token; } } @@ -1963,15 +1848,13 @@ void Translator::clean_up(void) // - returns Good if print code added successfully // - returns Null if stack was empty -// 2010-06-04: implemented new function -TokenStatus Translator::add_print_code(void) +TokenStatus Translator::addPrintCode(void) { - if (!done_stack.empty()) + if (!m_doneStack.empty()) { // create token for data type specific print token - Token *token = table.newToken(PrintDbl_Code); - // 2010-12-28: corrected status return value and arguments in call - return process_final_operand(token, NULL, 0); + Token *token = m_table.newToken(PrintDbl_Code); + return processFinalOperand(token, NULL, 0); } return Null_TokenStatus; // nothing done } @@ -1985,32 +1868,31 @@ TokenStatus Translator::add_print_code(void) // - returns Good if successful // - returns error if one is detected -TokenStatus Translator::set_assign_command(Token *&token, Code assign_code) +TokenStatus Translator::setAssignCommand(Token *&token, Code assign_code) { // start of assign list statement - table.setToken(token, assign_code); - // 2010-08-01: removed setting of Comma_SubCode to AssignList - // 2010-07-29: set reference flag of assignment + m_table.setToken(token, assign_code); + // set reference flag of assignment token->setReference(); - // 2010-07-01: find appropriate assign or assign list code - TokenStatus status = find_code(token, 0); + // find appropriate assign or assign list code + TokenStatus status = findCode(token, 0); if (status != Good_TokenStatus) { return status; } - if (cmd_stack.empty()) // still command mode? + if (m_cmdStack.empty()) // still command mode? { - cmd_stack.resize(cmd_stack.size() + 1); // push new command on stack + m_cmdStack.resize(m_cmdStack.size() + 1); // push new command on stack } else // was preceded by let keyword { token->setSubCodeMask(Let_SubCode); // set sub-code to indicate let - delete cmd_stack.top().token; // delete the let token + delete m_cmdStack.top().token; // delete the let token } - cmd_stack.top().token = token; - cmd_stack.top().flag = None_CmdFlag; + m_cmdStack.top().token = token; + m_cmdStack.top().flag = None_CmdFlag; return Good_TokenStatus; } @@ -2025,34 +1907,31 @@ TokenStatus Translator::set_assign_command(Token *&token, Code assign_code) // - returns Good if successful // - returns error if one is detected -TokenStatus Translator::check_assignlist_token(Token *&token) +TokenStatus Translator::checkAssignListToken(Token *&token) { - if (!done_stack.empty()) + if (!m_doneStack.empty()) { - // delete close paren (array or sub-string) on operand (2011-01-30 leak) - delete_close_paren(done_stack.top().last); - token = done_stack.pop().rpnItem->token; + // delete close paren (array or sub-string) on operand + deleteCloseParen(m_doneStack.top().last); + token = m_doneStack.pop().rpnItem->token(); if (!token->reference() - || equivalent_datatype[cmd_stack.top().token->dataType()] - != equivalent_datatype[token->dataType()]) + || equivalentDataType(m_cmdStack.top().token->dataType()) + != equivalentDataType(token->dataType())) { - // point to just open parentheses of DefFuncP tokens (2011-03-14) + // point to just open parentheses of DefFuncP tokens if (token->isType(DefFuncP_TokenType)) { // just point to open parentheses on token - // 2011-03-26: removed "- 1" as paren not in string token->addLengthToColumn(); token->setLength(1); return ExpEqualOrComma_TokenStatus; } - // 2010-06-30: replaced with expected variable errors - return errstatus_datatype[cmd_stack.top().token->dataType()] - .variable; + return variableErrStatus(m_cmdStack.top().token->dataType()); } - if (equivalent_datatype[token->dataType()] == String_DataType - && !token->isDataType(cmd_stack.top().token->dataType())) + if (equivalentDataType(token->dataType()) == String_DataType + && !token->isDataType(m_cmdStack.top().token->dataType())) { - cmd_stack.top().token->setCode(AssignListMix_Code); + m_cmdStack.top().token->setCode(AssignListMix_Code); } } return Good_TokenStatus; diff --git a/translator.h b/translator.h index 187dd6d..1fca7d9 100644 --- a/translator.h +++ b/translator.h @@ -43,7 +43,7 @@ enum { // FLAGS FOR PRINT COMMAND PrintStay_CmdFlag = 0x00010000, // PRINT stay on line flag - PrintFunc_CmdFlag = 0x00020000, // print func flag (2010-06-08) + PrintFunc_CmdFlag = 0x00020000, // print function flag // FLAGS FOR ASSIGNMENT COMMANDS AssignList_CmdFlag = 0x00010000, // currently an assign list @@ -57,54 +57,91 @@ enum { // command item struct CmdItem { Token *token; // pointer to command token - int flag; // 2010-06-01: generic flag for command use + int flag; // generic flag for command use int index; // index into output list for command use }; // structure for holding RPN output list information -struct RpnItem { - Token *token; // pointer to token - int noperands; // number of operands - RpnItem **operand; // array of operand pointers +class RpnItem { + Token *m_token; // pointer to token + int m_nOperands; // number of operands + RpnItem **m_operand; // array of operand pointers - RpnItem(Token *_token, int _noperands = 0, RpnItem **_operand = NULL) +public: + RpnItem(Token *token, int nOperands = 0, RpnItem **operand = NULL) { - token = _token; - noperands = _noperands; - operand = _operand; + m_token = token; + m_nOperands = nOperands; + m_operand = operand; } ~RpnItem() { - delete token; - if (noperands > 0) + delete m_token; + if (m_nOperands > 0) { - delete[] operand; + delete[] m_operand; } } + // access functions + Token *token(void) + { + return m_token; + } + void setToken(Token *token) + { + m_token = token; + } + + int nOperands(void) + { + return m_nOperands; + } + void setNOperands(int nOperands) + { + m_nOperands = nOperands; + } + + RpnItem **operand(void) + { + return m_operand; + } + void setOperand(RpnItem **operand) + { + m_operand = operand; + } + RpnItem *operand(int index) + { + return m_operand[index]; + } + void setOperand(int index, RpnItem *operand) + { + m_operand[index] = operand; + } + // function to set operands without allocating a new array - void set(int _noperands, RpnItem **_operand) + void set(int nOperands, RpnItem **operand) { - noperands = _noperands; - operand = _operand; + m_nOperands = nOperands; + m_operand = operand; } }; class Translator { - struct HoldStackItem { + struct HoldItem { Token *token; // token pointer on hold stack Token *first; // operator token's first operand pointer }; - struct DoneStackItem { + struct DoneItem { RpnItem *rpnItem; // pointer to RPN item Token *first; // operator token's first operand pointer Token *last; // operator token's last operand pointer }; struct CountItem { - char noperands; // number of operands seen - char nexpected; // number of arguments expected + char nOperands; // number of operands seen + char nExpected; // number of arguments expected Code code; // table index of internal function }; enum State { @@ -115,42 +152,42 @@ class Translator { EndExpr_State, // expecting end of expression (2011-03-05) EndStmt_State, // expecting end of statement (2011-03-19) sizeof_State - } state; // current state of translator - - Table &table; // pointer to the table object - QList *output; // pointer to RPN list output - QStack hold_stack; // operator/function holding stack - QStack done_stack; // items processed stack - Token *pending_paren; // closing parentheses token is pending - int last_precedence; // precedence of last op added during paren - QStack count_stack; // number of operands counter stack - TokenMode mode; // current assignment mode - QStack cmd_stack; // stack of commands waiting processing - bool exprmode; // expression only mode active flag + } m_state; // current state of translator + + Table &m_table; // pointer to the table object + QList *m_output; // pointer to RPN list output + QStack m_holdStack; // operator/function holding stack + QStack m_doneStack; // items processed stack + Token *m_pendingParen; // closing parentheses token is pending + int m_lastPrecedence; // precedence of last op added during paren + QStack m_countStack; // number of operands counter stack + TokenMode m_mode; // current assignment mode + QStack m_cmdStack; // stack of commands waiting processing + bool m_exprMode; // expression only mode active flag public: - Translator(Table &t): table(t), output(NULL), pending_paren(NULL) {} - void start(bool _exprmode = false) + Translator(Table &t): m_table(t), m_output(NULL), m_pendingParen(NULL) {} + void start(bool exprMode = false) { - exprmode = _exprmode; // save flag - output = new QList; - state = Initial_State; + m_exprMode = exprMode; // save flag + m_output = new QList; + m_state = Initial_State; // (expression mode for testing) - mode = exprmode ? Expression_TokenMode : Command_TokenMode; + m_mode = m_exprMode ? Expression_TokenMode : Command_TokenMode; } // function to access if operand state - bool get_operand_state(void) + bool getOperandState(void) { - return state == Operand_State || state == OperandOrEnd_State; + return m_state == Operand_State || m_state == OperandOrEnd_State; } - TokenStatus add_token(Token *&token); - QList *get_result(void) // only call when add_token returns Done + TokenStatus addToken(Token *&token); + QList *getResult(void) // only call when add_token returns Done { - QList *list = output; - output = NULL; + QList *list = m_output; + m_output = NULL; return list; } - void clean_up(void); // only call when add_token returns an error + void cleanUp(void); // only call when add_token returns an error private: enum Match { @@ -160,14 +197,14 @@ class Translator { sizeof_Match }; - TokenStatus process_operand(Token *&token); - TokenStatus end_expression_error(void); - bool process_unary_operator(Token *&token, TokenStatus &status); - TokenStatus process_binary_operator(Token *&token); - TokenStatus process_operator(Token *&token); - TokenStatus operator_error(void); + TokenStatus processOperand(Token *&token); + TokenStatus endExpressionError(void); + bool processUnaryOperator(Token *&token, TokenStatus &status); + TokenStatus processBinaryOperator(Token *&token); + TokenStatus processOperator(Token *&token); + TokenStatus operatorError(void); // TODO move this function to translator.cpp - void set_default_datatype(Token *token) + void setDefaultDataType(Token *token) { // only set to double if not an internal function if (token->isDataType(None_DataType) @@ -184,33 +221,33 @@ class Translator { token->setDataType(TmpStr_DataType); } } - TokenStatus process_first_operand(Token *&token); - TokenStatus process_final_operand(Token *&token, Token *token2, - int operand_index, int noperands = 0); - TokenStatus find_code(Token *&token, int operand_index, + TokenStatus processFirstOperand(Token *&token); + TokenStatus processFinalOperand(Token *&token, Token *token2, + int operandIndex, int nOperands = 0); + TokenStatus findCode(Token *&token, int operandIndex, Token **first = NULL, Token **last = NULL); - void do_pending_paren(Token *token); - TokenStatus expression_end(void); - TokenStatus paren_status(void); - TokenStatus get_expr_datatype(DataType &datatype); - void delete_close_paren(Token *last); - TokenStatus call_command_handler(Token *&token); + void doPendingParen(Token *token); + TokenStatus expressionEnd(void); + TokenStatus parenStatus(void); + TokenStatus getExprDataType(DataType &dataType); + void deleteCloseParen(Token *last); + TokenStatus callCommandHandler(Token *&token); // COMMAND SPECIFIC FUNCTIONS - TokenStatus add_print_code(void); - TokenStatus check_assignlist_token(Token *&token); - TokenStatus set_assign_command(Token *&token, Code assign_code); + TokenStatus addPrintCode(void); + TokenStatus checkAssignListToken(Token *&token); + TokenStatus setAssignCommand(Token *&token, Code assign_code); // By DataType Access Functions - static TokenStatus errStatusExpected(DataType dataType); - static TokenStatus errStatusActual(DataType dataType); - static TokenStatus errStatusVariable(DataType dataType); + static TokenStatus expectedErrStatus(DataType dataType); + static TokenStatus actualErrStatus(DataType dataType); + static TokenStatus variableErrStatus(DataType dataType); static DataType equivalentDataType(DataType dataType); public: // function to delete an open paren token // (public to be used to delete token to prevent memory leak) - void delete_open_paren(Token *first); + void deleteOpenParen(Token *first); // token handler friend function definitions section friend TokenStatus Operator_Handler(Translator &t, Token *&token); @@ -232,13 +269,4 @@ class Translator { }; -// token handler function definitions section -extern TokenStatus Operator_Handler(Translator &t, Token *&token); -extern TokenStatus Equal_Handler(Translator &t, Token *&token); -extern TokenStatus Comma_Handler(Translator &t, Token *&token); -extern TokenStatus CloseParen_Handler(Translator &t, Token *&token); -extern TokenStatus EndOfLine_Handler(Translator &t, Token *&token); -extern TokenStatus SemiColon_Handler(Translator &t, Token *&token); - - #endif // TRANSLATOR_H