// PRINT command translate function TokenStatus printTranslate(Translator &translator, Token *commandToken, Token *&token) { TokenStatus status; Token *lastSemiColon = NULL; bool separator = false; bool printFunction = false; forever { if ((status = translator.getExpression(token, None_DataType)) != Done_TokenStatus) { if (status == Parser_TokenStatus && token->isDataType(None_DataType)) { if (translator.doneStackEmpty()) { status = ExpExprCommaPfnOrEnd_TokenStatus; } // change parser error if not inside paren else if (translator.doneStackTopToken() ->isDataType(None_DataType)) { status = ExpSemiCommaOrEnd_TokenStatus; } else // not a print function { status = ExpOpSemiCommaOrEnd_TokenStatus; } } break; } if (!translator.doneStackEmpty()) { if (translator.doneStackTopToken()->isDataType(None_DataType)) { translator.doneStackDrop(); // print function printFunction = true; } else // append appropriate print code for done stack top item { Token *printToken = translator.table().newToken(PrintDbl_Code); translator.processFinalOperand(printToken); printFunction = false; } separator = true; delete lastSemiColon; lastSemiColon = NULL; } if (token->isCode(Comma_Code)) { if (lastSemiColon != NULL) { status = ExpExprPfnOrEnd_TokenStatus; break; } translator.outputAppend(token); delete lastSemiColon; lastSemiColon = NULL; } else if (token->isCode(SemiColon_Code)) { if (!separator) { status = lastSemiColon == NULL ? ExpExprCommaPfnOrEnd_TokenStatus : ExpExprPfnOrEnd_TokenStatus; break; } delete lastSemiColon; lastSemiColon = token; } else // some other token, maybe end-of-statement { break; // exit loop } separator = false; token = NULL; } if (status != Done_TokenStatus) { delete lastSemiColon; delete commandToken; return status; } if (lastSemiColon != NULL) { // append last semicolon token as command token delete commandToken; commandToken = lastSemiColon; } translator.outputAppend(commandToken); if (!translator.table().hasFlag(token, EndStmt_Flag)) { return printFunction ? ExpSemiCommaOrEnd_TokenStatus : ExpOpSemiCommaOrEnd_TokenStatus; } return Done_TokenStatus; }
// INPUT command translate function TokenStatus inputTranslate(Translator &translator, Token *commandToken, Token *&token) { TokenStatus status; int indexBegin; bool done; Token *inputToken; if (commandToken->isCode(Input_Code)) { token = translator.table().newToken(InputBegin_Code); } else // InputPrompt_Code { token = NULL; status = translator.getExpression(token, String_DataType); if (status != Done_TokenStatus) { if (status == Parser_TokenStatus && token->isDataType(None_DataType)) { status = ExpSemiOrComma_TokenStatus; } delete commandToken; return status; } translator.doneStackDrop(); if (token->isCode(Comma_Code)) { token->addSubCode(Option_SubCode); } else if (!token->isCode(SemiColon_Code)) { delete commandToken; return ExpOpSemiOrComma_TokenStatus; } token->setCode(InputBeginStr_Code); } // save index where to insert input parse codes and append input begin indexBegin = translator.outputCount(); translator.outputAppend(token); // loop to read input variables do { // get variable reference token = NULL; if ((status = translator.getOperand(token, Any_DataType, Translator::Variable_Reference)) != Good_TokenStatus) { break; } // get and check next token if ((status = translator.getToken(token)) != Good_TokenStatus) { status = ExpCommaSemiOrEnd_TokenStatus; break; } if (token->isCode(Comma_Code)) { done = false; inputToken = token; } else if (token->isCode(SemiColon_Code)) { commandToken->addSubCode(Option_SubCode); done = true; inputToken = token; // get and check next token if ((status = translator.getToken(token)) != Good_TokenStatus) { status = ExpEndStmt_TokenStatus; break; } } else // possible end-of-statement (checked below) { done = true; inputToken = new Token; } // change token to appropriate assign code and append to output translator.table().setToken(inputToken, InputAssign_Code); status = translator.processFinalOperand(inputToken); if (status != Good_TokenStatus) { break; } // create and insert input parse code at beginning // (inserted in reverse order for each input variable) translator.outputInsert(indexBegin, translator.table() .newToken(translator.table() .secondAssociatedCode(inputToken->code()))); } while (!done); if (status != Good_TokenStatus) { delete commandToken; return status; } translator.outputAppend(commandToken); // check terminating token for end-of-statement if (!translator.table().hasFlag(token, EndStmt_Flag)) { return ExpCommaSemiOrEnd_TokenStatus; } return Done_TokenStatus; }
// LET command translate function TokenStatus letTranslate(Translator &translator, Token *commandToken, Token *&token) { TokenStatus status; int column; bool hidden; DataType dataType; bool done; TokenStack letStack; bool haveSubStr = false; if (commandToken == NULL) { column = token->column(); hidden = true; } else // delete unneeded command token and get another token { column = commandToken->column(); delete commandToken; hidden = false; } dataType = Any_DataType; do { if ((status = translator.getOperand(token, dataType, Translator::All_Reference)) != Good_TokenStatus) { if (token->column() > column) { return status; } // next token determines error Token *nextToken; if ((status = translator.getToken(nextToken)) != Good_TokenStatus) { status = ExpCmd_TokenStatus; } if (nextToken->isCode(Comma_Code) || nextToken->isCode(Eq_Code)) { status = ExpAssignItem_TokenStatus; } else { status = ExpCmd_TokenStatus; } delete nextToken; return status; } // get and check next token for comma or equal status = translator.getToken(token); if (token->isCode(Comma_Code)) { done = false; } else if (token->isCode(Eq_Code)) { done = true; } else // invalid token or parser error { if (translator.table().hasFlag(translator.doneStackTopToken(), SubStr_Flag)) { delete translator.doneStackPop(); } return ExpEqualOrComma_TokenStatus; } // check if this is a sub-string assignment if (translator.table().hasFlag(translator.doneStackTopToken(), SubStr_Flag)) { // delete comma/equal token, use sub-string function token delete token; // get sub-string function token from rpn item on top of stack // (delete rpn item since it was not appended to output) RpnItem *rpnItem = translator.doneStackPop(); token = rpnItem->token(); rpnItem->setToken(NULL); // prevent delete of token delete rpnItem; // change to assign sub-string code (first associated code) translator.table().setToken(token, translator.table().associatedCode(token->code())); haveSubStr = true; } else // use comma/equal token { // change token to appropriate assign code translator.table().setToken(token, Assign_Code); status = translator.processDoneStackTop(token); if (status != Good_TokenStatus) { return status; } } letStack.push(token); // save token // get data type for assignment if (dataType == Any_DataType) { dataType = token->dataType(); } token = NULL; } while (!done); // get expression for value to assign if ((status = translator.getExpression(token, translator.equivalentDataType(dataType))) != Done_TokenStatus) { if (status == Parser_TokenStatus && token->isDataType(None_DataType)) { status = ExpOpOrEnd_TokenStatus; } return status; } Token *letToken = letStack.pop(); if (!letStack.isEmpty()) { if (haveSubStr) { // add each token saved in let stack except the last do { // change to keep code (second associated code) translator.table().setToken(letToken, translator.table().associatedCode(letToken->code())); // append to output and pop next token from let stack translator.outputAppend(letToken); letToken = letStack.pop(); } while (!letStack.isEmpty()); // continue until last token } else // have a multiple assignment, change to list code { translator.table().setToken(letToken, translator.table().secondAssociatedCode(letToken->code())); } } // drop expresion result from done stack, append last assignment token translator.doneStackDrop(); translator.outputAppend(letToken); // set hidden LET flag if needed if (!hidden) { letToken->addSubCode(Option_SubCode); } // check terminating token for end-of-statement if (!translator.table().hasFlag(token, EndStmt_Flag)) { return ExpOpOrEnd_TokenStatus; } return Done_TokenStatus; }