From 098009de2443c8406a20ad37768692beea033699 Mon Sep 17 00:00:00 2001 From: Thunder422 Date: Sat, 17 Jan 2015 21:44:18 -0500 Subject: [PATCH] table: replaced command type use with command flag changed to use command flag instead added command flag to all command entries (formally command type) - the type initializer was changed to the default type added is command table entry and token pass-thru access functions - also checks if not reference flag (assignment) - and checks if not operator (comma, semicolon) updated command type checks in tester and translator classes --- programmodel.cpp | 8 +- recreator.cpp | 8 +- table.cpp | 96 ++++++++--------- table.h | 10 +- test_ibcp.cpp | 274 +++++++++++++++++++++++++---------------------- token.h | 4 + translator.cpp | 13 ++- 7 files changed, 221 insertions(+), 192 deletions(-) diff --git a/programmodel.cpp b/programmodel.cpp index d98f0b4..b194617 100644 --- a/programmodel.cpp +++ b/programmodel.cpp @@ -45,9 +45,8 @@ std::ostream &operator<<(std::ostream &os, ProgramWord word) if (word.instructionHasSubCode(ProgramMask_SubCode)) { os << '\''; - bool command = entry->type() == Type::Command - || entry->hasFlag(Command_Flag); - if (!command && word.instructionHasSubCode(Paren_SubCode)) + if (!entry->hasFlag(Command_Flag) + && word.instructionHasSubCode(Paren_SubCode)) { os << ')'; } @@ -56,7 +55,8 @@ std::ostream &operator<<(std::ostream &os, ProgramWord word) std::string option {entry->optionName()}; os << (option.empty() ? "BUG" : option); } - if (command && word.instructionHasSubCode(Colon_SubCode)) + if (entry->hasFlag(Command_Flag) + && word.instructionHasSubCode(Colon_SubCode)) { os << ":"; } diff --git a/recreator.cpp b/recreator.cpp index 8528774..8a27975 100644 --- a/recreator.cpp +++ b/recreator.cpp @@ -51,13 +51,13 @@ std::string Recreator::operator()(const RpnList &rpnList, bool exprMode) { recreate(*this, rpnItem); } - bool command = rpnItem->token()->isType(Type::Command) - || rpnItem->token()->hasFlag(Command_Flag); - if (!command && rpnItem->token()->hasSubCode(Paren_SubCode)) + if (!rpnItem->token()->hasFlag(Command_Flag) + && rpnItem->token()->hasSubCode(Paren_SubCode)) { parenRecreate(*this, rpnItem); } - if (command && rpnItem->token()->hasSubCode(Colon_SubCode)) + if (rpnItem->token()->hasFlag(Command_Flag) + && rpnItem->token()->hasSubCode(Colon_SubCode)) { // FLAG option: spaces before colons (default=no) m_output += ':'; diff --git a/table.cpp b/table.cpp index d85830c..361a9bc 100644 --- a/table.cpp +++ b/table.cpp @@ -162,167 +162,167 @@ static TableEntry tableEntries[] = // Commands //-------------- { // Let_Code - Type::Command, + Type{}, "LET", "", "", - TableFlag{}, 4, &Null_ExprInfo, + Command_Flag, 4, &Null_ExprInfo, letTranslate, NULL, NULL, NULL, NULL }, { // Print_Code - Type::Command, + Type{}, "PRINT", "", "", - TableFlag{}, 4, &Null_ExprInfo, + Command_Flag, 4, &Null_ExprInfo, printTranslate, NULL, NULL, NULL, printRecreate }, { // Input_Code - Type::Command, + Type{}, "INPUT", "", "Keep", - Two_Flag, 4, &Null_ExprInfo, + Command_Flag | Two_Flag, 4, &Null_ExprInfo, inputTranslate, NULL, NULL, NULL, inputRecreate }, { // InputPrompt_Code - Type::Command, + Type{}, "INPUT", "PROMPT", "Keep", - Two_Flag, 4, &Null_ExprInfo, + Command_Flag | Two_Flag, 4, &Null_ExprInfo, inputTranslate, NULL, NULL, NULL, inputRecreate }, { // Dim_Code - Type::Command, + Type{}, "DIM", "", "", - TableFlag{}, 4, &Null_ExprInfo, + Command_Flag, 4, &Null_ExprInfo, NULL, NULL, NULL, NULL, NULL }, { // Def_Code - Type::Command, + Type{}, "DEF", "", "", - TableFlag{}, 4, &Null_ExprInfo, + Command_Flag, 4, &Null_ExprInfo, NULL, NULL, NULL, NULL, NULL }, { // Rem_Code - Type::Command, + Type{}, "REM", "", "", - TableFlag{}, 4, &Null_ExprInfo, + Command_Flag, 4, &Null_ExprInfo, NULL, remEncode, remOperandText, remRemove, remRecreate }, { // If_Code - Type::Command, + Type{}, "IF", "", "", - TableFlag{}, 4, &Null_ExprInfo, + Command_Flag, 4, &Null_ExprInfo, NULL, NULL, NULL, NULL, NULL }, { // Then_Code - Type::Command, + Type{}, "THEN", "", "", - TableFlag{}, 4, &Null_ExprInfo, + Command_Flag, 4, &Null_ExprInfo, NULL, NULL, NULL, NULL, NULL }, { // Else_Code - Type::Command, + Type{}, "ELSE", "", "", - TableFlag{}, 4, &Null_ExprInfo, + Command_Flag, 4, &Null_ExprInfo, NULL, NULL, NULL, NULL, NULL }, { // End_Code - Type::Command, + Type{}, "END", "", "", - Two_Flag, 4, &Null_ExprInfo, + Command_Flag | Two_Flag, 4, &Null_ExprInfo, NULL, NULL, NULL, NULL, NULL }, { // EndIf_Code - Type::Command, + Type{}, "END", "IF", "", - Two_Flag, 4, &Null_ExprInfo, + Command_Flag | Two_Flag, 4, &Null_ExprInfo, NULL, NULL, NULL, NULL, NULL }, { // For_Code - Type::Command, + Type{}, "FOR", "", "", - TableFlag{}, 4, &Null_ExprInfo, + Command_Flag, 4, &Null_ExprInfo, NULL, NULL, NULL, NULL, NULL }, { // To_Code - Type::Command, + Type{}, "TO", "", "", - TableFlag{}, 4, &Null_ExprInfo, + Command_Flag, 4, &Null_ExprInfo, NULL, NULL, NULL, NULL, NULL }, { // Step_Code - Type::Command, + Type{}, "STEP", "", "", - TableFlag{}, 4, &Null_ExprInfo, + Command_Flag, 4, &Null_ExprInfo, NULL, NULL, NULL, NULL, NULL }, { // Next_Code - Type::Command, + Type{}, "NEXT", "", "", - TableFlag{}, 4, &Null_ExprInfo, + Command_Flag, 4, &Null_ExprInfo, NULL, NULL, NULL, NULL, NULL }, { // Do_Code - Type::Command, + Type{}, "DO", "", "", - Two_Flag, 4, &Null_ExprInfo, + Command_Flag | Two_Flag, 4, &Null_ExprInfo, NULL, NULL, NULL, NULL, NULL }, { // DoWhile_Code - Type::Command, + Type{}, "DO", "WHILE", "", - Two_Flag, 4, &Null_ExprInfo, + Command_Flag | Two_Flag, 4, &Null_ExprInfo, NULL, NULL, NULL, NULL, NULL }, { // DoUntil_Code - Type::Command, + Type{}, "DO", "UNTIL", "", - Two_Flag, 4, &Null_ExprInfo, + Command_Flag | Two_Flag, 4, &Null_ExprInfo, NULL, NULL, NULL, NULL, NULL }, { // While_Code - Type::Command, + Type{}, "WHILE", "", "", - Two_Flag, 4, &Null_ExprInfo, + Command_Flag | Two_Flag, 4, &Null_ExprInfo, NULL, NULL, NULL, NULL, NULL }, { // Until_Code - Type::Command, + Type{}, "UNTIL", "", "", - Two_Flag, 4, &Null_ExprInfo, + Command_Flag | Two_Flag, 4, &Null_ExprInfo, NULL, NULL, NULL, NULL, NULL }, { // Loop_Code - Type::Command, + Type{}, "LOOP", "", "", - Two_Flag, 4, &Null_ExprInfo, + Command_Flag | Two_Flag, 4, &Null_ExprInfo, NULL, NULL, NULL, NULL, NULL }, { // LoopWhile_Code - Type::Command, + Type{}, "LOOP", "WHILE", "", - Two_Flag, 4, &Null_ExprInfo, + Command_Flag | Two_Flag, 4, &Null_ExprInfo, NULL, NULL, NULL, NULL, NULL }, { // LoopUntil_Code - Type::Command, + Type{}, "LOOP", "UNTIL", "", - Two_Flag, 4, &Null_ExprInfo, + Command_Flag | Two_Flag, 4, &Null_ExprInfo, NULL, NULL, NULL, NULL, NULL }, diff --git a/table.h b/table.h index 4523147..11ea01a 100644 --- a/table.h +++ b/table.h @@ -38,8 +38,7 @@ using TokenPtr = std::shared_ptr; // TODO temporary until code type enumeration implemented enum class Type { - Command = 1, - Operator, + Operator = 1, IntFunc, Constant, DefFunc, @@ -61,7 +60,7 @@ enum TableFlag : unsigned UseConstAsIs_Flag = 1u << 5, // use constant data type as is Keep_Flag = 1u << 6, // sub-string keep assignment Two_Flag = 1u << 7, // code can have two words or characters - Command_Flag = 1u << 8, // operator code is really a command + Command_Flag = 1u << 8, // code is a command EndStmt_Flag = 1u << 31 // end statement }; @@ -150,6 +149,11 @@ class TableEntry { return m_flags & flag ? true : false; } + bool isCommand() const + { + return hasFlag(Command_Flag) && !hasFlag(Reference_Flag) + && m_type != Type::Operator; + } int precedence() const { return m_precedence; diff --git a/test_ibcp.cpp b/test_ibcp.cpp index 01f5b64..6a0b732 100644 --- a/test_ibcp.cpp +++ b/test_ibcp.cpp @@ -39,58 +39,8 @@ std::ostream &operator<<(std::ostream &os, const TokenPtr &token) { bool second {}; - switch (token->type()) + if (token->isCommand()) { - case Type::NoParen: - os << token->stringWithDataType(); - if (token->hasFlag(Reference_Flag)) - { - os << ""; - } - break; - - case Type::DefFuncNoArgs: - os << token->stringWithDataType(); - break; - - case Type::DefFunc: - case Type::Paren: - os << token->stringWithDataType() << '('; - break; - - case Type::Constant: - switch (token->dataType()) - { - case DataType::Integer: - case DataType::Double: - os << token->string(); - if (token->dataType() == DataType::Integer) - { - os << "%"; - } - break; - - case DataType::String: - os << '"' << token->string() << '"'; - break; - default: - break; - } - break; - - case Type::Operator: - if (token->isCode(RemOp_Code)) - { - os << token->name(); - second = true; - } - else - { - os << token->debugName(); - } - break; - - case Type::Command: if (token->isCode(Rem_Code)) { os << token->name(); @@ -104,12 +54,65 @@ std::ostream &operator<<(std::ostream &os, const TokenPtr &token) os << '-' << token->name2(); } } - break; + } + else + { + switch (token->type()) + { + case Type::NoParen: + os << token->stringWithDataType(); + if (token->hasFlag(Reference_Flag)) + { + os << ""; + } + break; + + case Type::DefFuncNoArgs: + os << token->stringWithDataType(); + break; + + case Type::DefFunc: + case Type::Paren: + os << token->stringWithDataType() << '('; + break; + + case Type::Constant: + switch (token->dataType()) + { + case DataType::Integer: + case DataType::Double: + os << token->string(); + if (token->dataType() == DataType::Integer) + { + os << "%"; + } + break; + + case DataType::String: + os << '"' << token->string() << '"'; + break; + default: + break; + } + break; - default: - // output debug name by default - os << token->debugName(); - break; + case Type::Operator: + if (token->isCode(RemOp_Code)) + { + os << token->name(); + second = true; + } + else + { + os << token->debugName(); + } + break; + + default: + // output debug name by default + os << token->debugName(); + break; + } } if (token->reference()) { @@ -118,9 +121,7 @@ std::ostream &operator<<(std::ostream &os, const TokenPtr &token) if (token->hasSubCode()) { os << '\''; - bool command = token->isType(Type::Command) - || token->hasFlag(Command_Flag); - if (!command && token->hasSubCode(Paren_SubCode)) + if (!token->hasFlag(Command_Flag) && token->hasSubCode(Paren_SubCode)) { os << ')'; } @@ -136,7 +137,7 @@ std::ostream &operator<<(std::ostream &os, const TokenPtr &token) os << option; } } - if (command && token->hasSubCode(Colon_SubCode)) + if (token->hasFlag(Command_Flag) && token->hasSubCode(Colon_SubCode)) { os << ':'; } @@ -646,26 +647,31 @@ static const char *dataTypeName(DataType dataType) // function to convert token type enumerator to string -static const char *tokenTypeName(Type type) +static const char *tokenTypeName(const TokenPtr &token) { - switch (type) + if (token->isCommand()) { - case Type::Command: return "Command"; - case Type::Operator: - return "Operator"; - case Type::IntFunc: - return "IntFunc"; - case Type::Constant: - return "Constant"; - case Type::DefFunc: - return "DefFunc"; - case Type::DefFuncNoArgs: - return "DefFuncN"; - case Type::NoParen: - return "NoParen"; - case Type::Paren: - return "Paren"; + } + else + { + switch (token->type()) + { + case Type::Operator: + return "Operator"; + case Type::IntFunc: + return "IntFunc"; + case Type::Constant: + return "Constant"; + case Type::DefFunc: + return "DefFunc"; + case Type::DefFuncNoArgs: + return "DefFuncN"; + case Type::NoParen: + return "NoParen"; + case Type::Paren: + return "Paren"; + } } return ""; // silence compiler warning (doesn't reach here at run-time) } @@ -675,68 +681,74 @@ static const char *tokenTypeName(Type type) void Tester::printToken(const TokenPtr &token) { m_cout << '\t' << std::setw(2) << std::right << token->column() << std::left - << ": " << std::setw(10) << tokenTypeName(token->type()); - switch (token->type()) - { - case Type::IntFunc: - m_cout << (token->operandCount() == 0 ? " " : "()"); - break; - case Type::Constant: - case Type::NoParen: - case Type::DefFuncNoArgs: - m_cout << " "; - break; - case Type::Paren: - case Type::DefFunc: - m_cout << "()"; - break; - case Type::Operator: - case Type::Command: - m_cout << "Op"; - break; - } - if (!token->isType(Type::Command)) + << ": " << std::setw(10) << tokenTypeName(token); + if (token->isCommand()) { - m_cout << ' ' << std::setw(7) << dataTypeName(token->dataType()); + m_cout << "Op " << token->debugName(); + if (token->isCode(Rem_Code)) + { + m_cout << " |" << token->string() << '|'; + } } - switch (token->type()) - { - case Type::DefFuncNoArgs: - case Type::NoParen: - m_cout << " |" << token->stringWithDataType() << '|'; - break; - case Type::DefFunc: - case Type::Paren: - m_cout << " |" << token->stringWithDataType() << "(|"; - break; - case Type::Constant: - switch (token->dataType()) - { - case DataType::Integer: - m_cout << ' ' << token->valueInt(); + else + { + switch (token->type()) + { + case Type::IntFunc: + m_cout << (token->operandCount() == 0 ? " " : "()"); break; - case DataType::Double: - m_cout << ' '; - if (token->hasSubCode(IntConst_SubCode)) - { - m_cout << token->valueInt() << ","; - } - m_cout << token->value(); + case Type::Constant: + case Type::NoParen: + case Type::DefFuncNoArgs: + m_cout << " "; + break; + case Type::Paren: + case Type::DefFunc: + m_cout << "()"; + break; + case Type::Operator: + m_cout << "Op"; break; - default: - break; } - m_cout << " |" << token->string() << '|'; - break; - case Type::Operator: - case Type::IntFunc: - case Type::Command: - m_cout << " " << token->debugName(); - if (token->isCode(Rem_Code) || token->isCode(RemOp_Code)) + m_cout << ' ' << std::setw(7) << dataTypeName(token->dataType()); + switch (token->type()) { + case Type::DefFuncNoArgs: + case Type::NoParen: + m_cout << " |" << token->stringWithDataType() << '|'; + break; + case Type::DefFunc: + case Type::Paren: + m_cout << " |" << token->stringWithDataType() << "(|"; + break; + case Type::Constant: + switch (token->dataType()) + { + case DataType::Integer: + m_cout << ' ' << token->valueInt(); + break; + case DataType::Double: + m_cout << ' '; + if (token->hasSubCode(IntConst_SubCode)) + { + m_cout << token->valueInt() << ","; + } + m_cout << token->value(); + break; + default: + break; + } m_cout << " |" << token->string() << '|'; + break; + case Type::Operator: + case Type::IntFunc: + m_cout << " " << token->debugName(); + if (token->isCode(RemOp_Code)) + { + m_cout << " |" << token->string() << '|'; + } + break; } - break; } m_cout << std::endl; } diff --git a/token.h b/token.h index 5061c82..13b092a 100644 --- a/token.h +++ b/token.h @@ -208,6 +208,10 @@ class Token { return m_entry->hasFlag(flag); } + bool isCommand() const + { + return m_entry->isCommand(); + } int precedence() const { return m_entry->precedence(); diff --git a/translator.cpp b/translator.cpp index 9d3fc2e..0a0a1d2 100644 --- a/translator.cpp +++ b/translator.cpp @@ -150,7 +150,7 @@ void Translator::getCommands() } // process command (assume assignment statement if not command token) - if (TranslateFunction translate = m_token->isType(Type::Command) + if (TranslateFunction translate = m_token->isCommand() ? m_token->tableEntry()->translateFunction() : Table::entry(Let_Code)->translateFunction()) { @@ -332,9 +332,18 @@ bool Translator::getOperand(DataType dataType, Reference reference) getToken(Status{}, dataType, reference); bool doneAppend {true}; + if (m_token->isCommand()) + { + if (dataType == DataType::None) + { + // nothing is acceptable, this is terminating token + return false; + } + throw TokenError {expectedErrorStatus(dataType, reference), + std::move(m_token)}; + } switch (m_token->type()) { - case Type::Command: case Type::Operator: if (dataType == DataType::None) {