diff --git a/ibcp.h b/ibcp.h index e8b19dc..4d8d667 100644 --- a/ibcp.h +++ b/ibcp.h @@ -303,12 +303,17 @@ enum class DataType // sub-code flags for use in Token and internal program enum SubCode : uint16_t { - None_SubCode = 0x0000, // no sub-code present ProgramMask_SubCode = 0xFC00, // mask for actual program sub-codes - Paren_SubCode = 0x0400, // reproduce unnecessary parenthesis - Colon_SubCode = 0x0800, // reproduce ":" after token + Paren_SubCode = 0x0400, // recreate unnecessary parenthesis + Colon_SubCode = 0x0400, // recreate ":" after token + Unused3_SubCode = 0x0800, // unused option + // note: Paren for operators, Colon for commands Option_SubCode = 0x1000, // reproduce command specific option - // sub-codes used by translator only + // note: command option for INPUT/INPUT PROMPT ('Keep') + // command option for InputBeginStr ('Question') + // recreate 'LET' on assignments + Unused2_SubCode = 0x2000, // unused option + Unused1_SubCode = 0x4000, // unused option Double_SubCode = 0x8000, // integer constant has decimal/exponent // note: for constants in translator only (not encoded in program) // recreate '#' on double identifiers diff --git a/programcode.h b/programcode.h index 77d1abd..be79766 100644 --- a/programcode.h +++ b/programcode.h @@ -49,7 +49,7 @@ class ProgramWord { return SubCode(m_word & ProgramMask_SubCode); } - bool instructionHasSubCode(int subCode) const + bool instructionHasSubCode(SubCode subCode) const { return (m_word & subCode) != 0; } diff --git a/programmodel.cpp b/programmodel.cpp index d050cbc..159d6d0 100644 --- a/programmodel.cpp +++ b/programmodel.cpp @@ -46,7 +46,9 @@ std::ostream &operator<<(std::ostream &os, ProgramWord word) if (word.instructionHasSubCode(ProgramMask_SubCode)) { os << '\''; - if (word.instructionHasSubCode(Paren_SubCode)) + bool command = table.type(code) == Token::Type::Command + || table.hasFlag(code, Command_Flag); + if (!command && word.instructionHasSubCode(Paren_SubCode)) { os << ')'; } @@ -55,7 +57,7 @@ std::ostream &operator<<(std::ostream &os, ProgramWord word) std::string option {table.optionName(code)}; os << (option.empty() ? "BUG" : option); } - if (word.instructionHasSubCode(Colon_SubCode)) + if (command && word.instructionHasSubCode(Colon_SubCode)) { os << ":"; } diff --git a/recreator.cpp b/recreator.cpp index 0f730e9..69fdb11 100644 --- a/recreator.cpp +++ b/recreator.cpp @@ -52,11 +52,13 @@ std::string Recreator::operator()(const RpnList &rpnList, bool exprMode) { recreate(*this, rpnItem); } - if (rpnItem->token()->hasSubCode(Paren_SubCode)) + bool command = rpnItem->token()->isType(Token::Type::Command) + || m_table.hasFlag(rpnItem->token(), Command_Flag); + if (!command && rpnItem->token()->hasSubCode(Paren_SubCode)) { parenRecreate(*this, rpnItem); } - if (rpnItem->token()->hasSubCode(Colon_SubCode)) + if (command && rpnItem->token()->hasSubCode(Colon_SubCode)) { // FLAG option: spaces before colons (default=no) m_output += ':'; diff --git a/table.cpp b/table.cpp index 0cc515f..46cce69 100644 --- a/table.cpp +++ b/table.cpp @@ -663,13 +663,13 @@ static TableEntry tableEntries[] = { // Comma_Code Token::Type::Operator, ",", "", "", - TableFlag{}, 6, &Null_ExprInfo, + Command_Flag, 6, &Null_ExprInfo, NULL, NULL, NULL, NULL, printCommaRecreate }, { // SemiColon_Code Token::Type::Operator, ";", "", "", - TableFlag{}, 6, &Null_ExprInfo, + Command_Flag, 6, &Null_ExprInfo, NULL, NULL, NULL, NULL, printSemicolonRecreate }, { // Colon_Code @@ -691,37 +691,37 @@ static TableEntry tableEntries[] = { // Assign_Code Token::Type{}, "=", "Assign", "LET", - Reference_Flag, 4, &Dbl_Dbl_ExprInfo, + Reference_Flag | Command_Flag, 4, &Dbl_Dbl_ExprInfo, NULL, NULL, NULL, NULL, assignRecreate }, { // AssignInt_Code Token::Type{}, "=", "Assign%", "LET", - Reference_Flag, 4, &Int_Int_ExprInfo, + Reference_Flag | Command_Flag, 4, &Int_Int_ExprInfo, NULL, NULL, NULL, NULL, assignRecreate }, { // AssignStr_Code Token::Type{}, "=", "Assign$", "LET", - Reference_Flag, 4, &Str_Str_ExprInfo, + Reference_Flag | Command_Flag, 4, &Str_Str_ExprInfo, NULL, NULL, NULL, NULL, assignStrRecreate }, { // AssignLeft_Code Token::Type{}, "LEFT$(", "Assign", "LET", - Reference_Flag | SubStr_Flag, 4, &Str_StrInt_ExprInfo, + Reference_Flag | SubStr_Flag | Command_Flag, 4, &Str_StrInt_ExprInfo, NULL, NULL, NULL, NULL, assignStrRecreate }, { // AssignMid2_Code Token::Type{}, "MID$(", "Assign2", "LET", - Reference_Flag | SubStr_Flag, 4, &Str_StrInt_ExprInfo, + Reference_Flag | SubStr_Flag | Command_Flag, 4, &Str_StrInt_ExprInfo, NULL, NULL, NULL, NULL, assignStrRecreate }, { // AssignMid3_Code Token::Type{}, "MID$(", "Assign3", "LET", - Reference_Flag | SubStr_Flag | Multiple_Flag, 4, &Str_StrIntInt_ExprInfo, + Reference_Flag | SubStr_Flag | Command_Flag, 4, &Str_StrIntInt_ExprInfo, NULL, NULL, NULL, NULL, assignStrRecreate }, { // AssignRight_Code @@ -733,19 +733,19 @@ static TableEntry tableEntries[] = { // AssignList_Code Token::Type{}, "=", "AssignList", "LET", - Reference_Flag, 4, &Dbl_Dbl_ExprInfo, + Reference_Flag | Command_Flag, 4, &Dbl_Dbl_ExprInfo, NULL, NULL, NULL, NULL, assignRecreate }, { // AssignListInt_Code Token::Type{}, "=", "AssignList%", "LET", - Reference_Flag, 4, &Int_Int_ExprInfo, + Reference_Flag | Command_Flag, 4, &Int_Int_ExprInfo, NULL, NULL, NULL, NULL, assignRecreate }, { // AssignListStr_Code Token::Type{}, "=", "AssignList$", "LET", - Reference_Flag, 4, &Str_Str_ExprInfo, + Reference_Flag | Command_Flag, 4, &Str_Str_ExprInfo, NULL, NULL, NULL, NULL, assignRecreate }, { // AssignKeepStr_Code @@ -769,8 +769,7 @@ static TableEntry tableEntries[] = { // AssignKeepMid3_Code Token::Type{}, "MID$(", "AssignKeep3", "LET", - Reference_Flag | SubStr_Flag | Multiple_Flag | Keep_Flag, 4, - &Str_StrStrInt_ExprInfo, + Reference_Flag | SubStr_Flag | Keep_Flag, 4, &Str_StrStrInt_ExprInfo, NULL, NULL, NULL, NULL, assignStrRecreate }, { // AssignKeepRight_Code diff --git a/table.h b/table.h index 7ed7a51..d69c8a0 100644 --- a/table.h +++ b/table.h @@ -46,6 +46,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 EndStmt_Flag = 1u << 31 // end statement }; diff --git a/test_ibcp.cpp b/test_ibcp.cpp index 473092a..b7f8bc1 100644 --- a/test_ibcp.cpp +++ b/test_ibcp.cpp @@ -126,7 +126,9 @@ std::ostream &operator<<(std::ostream &os, const TokenPtr &token) if (token->hasSubCode()) { os << '\''; - if (token->hasSubCode(Paren_SubCode)) + bool command = token->isType(Token::Type::Command) + || table.hasFlag(token, Command_Flag); + if (!command && token->hasSubCode(Paren_SubCode)) { os << ')'; } @@ -142,7 +144,7 @@ std::ostream &operator<<(std::ostream &os, const TokenPtr &token) os << option; } } - if (token->hasSubCode(Colon_SubCode)) + if (command && token->hasSubCode(Colon_SubCode)) { os << ':'; } diff --git a/token.cpp b/token.cpp index d42450b..9f97649 100644 --- a/token.cpp +++ b/token.cpp @@ -60,13 +60,13 @@ Token::Token(int column, int length, const std::string string, double value, { m_dataType = DataType::Integer; // 'double' if decimal pointer present - m_subCode = decimal ? Double_SubCode : None_SubCode; + m_subCode = decimal ? Double_SubCode : SubCode{}; m_valueInt = value; // convert to integer in case needed } else // number can't be converted to integer { m_dataType = DataType::Double; - m_subCode = None_SubCode; // ignore sub-code argument + m_subCode = {}; // ignore sub-code argument } } diff --git a/token.h b/token.h index f093085..8237ad3 100644 --- a/token.h +++ b/token.h @@ -66,10 +66,8 @@ class Token Token(int column, int length, const std::string string, int value) : m_column{column}, m_length{length}, m_type{Token::Type::Constant}, m_dataType{DataType::Integer}, m_string{string}, m_code{Invalid_Code}, - m_reference{}, m_subCode{None_SubCode}, m_valueInt{value} - { - m_value = value; // convert to double in case needed - } + m_reference{}, m_subCode{}, m_value(value), /*convert*/ + m_valueInt{value} {} // constructor for double constants Token(int column, int length, const std::string string, double value, @@ -79,7 +77,7 @@ class Token Token(int column, int length, const std::string string) : m_column{column}, m_length{length}, m_type{Token::Type::Constant}, m_dataType{DataType::String}, m_string{string}, m_code{Invalid_Code}, - m_reference{}, m_subCode{None_SubCode} {} + m_reference{}, m_subCode{} {} Token(const Token &token) // copy constructor { @@ -185,19 +183,19 @@ class Token { return m_subCode; } - bool hasSubCode(int subCode) const + bool hasSubCode(SubCode subCode) const { return m_subCode & subCode; } - void addSubCode(int subCode) + void addSubCode(SubCode subCode) { m_subCode |= subCode; } - void removeSubCode(int subCode) + void removeSubCode(SubCode subCode) { m_subCode &= ~subCode; } - int subCodes(void) const + uint16_t subCodes(void) const { return m_subCode; } @@ -260,7 +258,7 @@ class Token std::string m_string; // pointer to string of token Code m_code; // internal code of token (index of TableEntry) bool m_reference; // token is a reference flag - int m_subCode; // sub-code flags of token + uint16_t m_subCode; // sub-code flags of token double m_value; // double value for constant token int m_valueInt; // integer value for constant token (if possible) int m_index; // index within encoded program code line