diff --git a/src/Parser.cpp b/src/Parser.cpp index 6a719f5..b8530e0 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -25,6 +25,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ +#include #include "Parser.h" void Parser::parse() { @@ -61,162 +62,167 @@ void Parser::parse() { Declaration currentDeclaration; while (true) { - c = getByte(); - if (c == '\n' || c == '\0' || (!isComment && (c == ' ' || c == '\t' || c == ',' || c == ';'))) { - //End token + try{ + c = getByte(); + if (c == '\n' || c == '\0' || (!isComment && (c == ' ' || c == '\t' || c == ',' || c == ';'))) { + //End token - //TODO: identify Token - if (!currentValue.empty()) { - bool foundToken = false; - for (auto &t : states[currentStateIndex]) { - switch (t.first) { - case Token::Type::Label: - if (isLabel(currentValue)) { - if (!currentFunction.label.empty()) { - functions.emplace_back(std::move(currentFunction)); - currentFunction = Function(); - } - currentFunction.label = currentValue.substr(0, currentValue.size() - 1); + //TODO: identify Token + if (!currentValue.empty()) { + bool foundToken = false; + for (auto &t : states[currentStateIndex]) { + switch (t.first) { + case Token::Type::Label: + if (isLabel(currentValue)) { + if (!currentFunction.label.empty()) { + functions.emplace_back(std::move(currentFunction)); + currentFunction = Function(); + } + currentFunction.label = currentValue.substr(0, currentValue.size() - 1); - foundToken = true; - } - break; - case Token::Type::LocalLabel: - if (isLocalLabel(currentValue)) { - currentDeclaration.label = currentValue.substr(0, currentValue.size() - 1); - foundToken = true; - } - break; - case Token::Type::Operator: - if (isOperator(currentValue)) { - currentDeclaration.tokens.emplace_back(Token(t.first, currentValue)); - foundToken = true; - } - break; - case Token::Type::RegisterLocation: - if (isRegisterLocation(currentValue)) { - currentDeclaration.tokens.emplace_back( - Token(t.first, currentValue.substr(1, std::string::npos), - std::stoi(currentValue.substr(1, std::string::npos), nullptr, 0))); - foundToken = true; - } - break; - case Token::Type::CodeLabel: - if (isCodeLabel(currentValue)) { - currentDeclaration.tokens.emplace_back( - Token(t.first, currentValue.substr(1, std::string::npos))); - foundToken = true; - } - break; - case Token::Type::CodeLocation: - if (isCodeLocation(currentValue)) { - currentDeclaration.tokens.emplace_back( - Token(t.first, currentValue.substr(1, std::string::npos), - std::stoi(currentValue.substr(1, std::string::npos), nullptr, 0))); - foundToken = true; - } - break; - case Token::Type::Immediate: - if (isImmediate(currentValue)) { - currentDeclaration.tokens.emplace_back( - Token(t.first, currentValue, std::stoi(currentValue, nullptr, 0))); - foundToken = true; - } - break; - case Token::Type::Offset: - if (isOffset(currentValue) && !currentDeclaration.tokens.empty()) { - auto& prevValue = currentDeclaration.tokens.at(currentDeclaration.tokens.size() - 1); - if(prevValue.getType() == Token::Type::Immediate || prevValue.getType() == Token::Type::CodeLabel || prevValue.getType() == Token::Type::CodeLocation || prevValue.getType() == Token::Type::RegisterLocation){ - prevValue.valueImmediate += std::stoi(currentValue, nullptr, 0); - }else{ - throw std::runtime_error("Cannot apply Offset to value not numeric"); + foundToken = true; } - foundToken = true; - } - break; - case Token::Type::Directive: - if (isDirective(currentValue) && currentValue == ".constant") { - if (!currentFunction.label.empty()) { - functions.emplace_back(std::move(currentFunction)); - currentFunction = Function(); + break; + case Token::Type::LocalLabel: + if (isLocalLabel(currentValue)) { + currentDeclaration.label = currentValue.substr(0, currentValue.size() - 1); + foundToken = true; } + break; + case Token::Type::Operator: + if (isOperator(currentValue)) { + currentDeclaration.tokens.emplace_back(Token(t.first, currentValue)); + foundToken = true; + } + break; + case Token::Type::RegisterLocation: + if (isRegisterLocation(currentValue)) { + currentDeclaration.tokens.emplace_back( + Token(t.first, currentValue.substr(1, std::string::npos), + std::stoul(currentValue.substr(1, std::string::npos), nullptr, 0))); + foundToken = true; + } + break; + case Token::Type::CodeLabel: + if (isCodeLabel(currentValue)) { + currentDeclaration.tokens.emplace_back( + Token(t.first, currentValue.substr(1, std::string::npos))); + foundToken = true; + } + break; + case Token::Type::CodeLocation: + if (isCodeLocation(currentValue)) { + currentDeclaration.tokens.emplace_back( + Token(t.first, currentValue.substr(1, std::string::npos), + std::stoul(currentValue.substr(1, std::string::npos), nullptr, 0))); + foundToken = true; + } + break; + case Token::Type::Immediate: + if (isImmediate(currentValue)) { + currentDeclaration.tokens.emplace_back( + Token(t.first, currentValue, std::stoul(currentValue, nullptr, 0))); + foundToken = true; + } + break; + case Token::Type::Offset: + if (isOffset(currentValue) && !currentDeclaration.tokens.empty()) { + auto& prevValue = currentDeclaration.tokens.at(currentDeclaration.tokens.size() - 1); + if(prevValue.getType() == Token::Type::Immediate || prevValue.getType() == Token::Type::CodeLabel || prevValue.getType() == Token::Type::CodeLocation || prevValue.getType() == Token::Type::RegisterLocation){ + prevValue.valueImmediate += std::stoi(currentValue, nullptr, 0); + }else{ + throw std::runtime_error("Cannot apply Offset to value not numeric"); + } + foundToken = true; + } + break; + case Token::Type::Directive: + if (isDirective(currentValue) && currentValue == ".constant") { + if (!currentFunction.label.empty()) { + functions.emplace_back(std::move(currentFunction)); + currentFunction = Function(); + } - currentDeclaration.tokens.emplace_back( - Token(t.first, currentValue)); - foundToken = true; - } - break; - case Token::Type::BareValue: - if (isAlphaNumeric(currentValue)) { - if (currentDeclaration.tokens.size() == 1 && - currentDeclaration.tokens.at(0).getType() == Token::Type::Directive) { currentDeclaration.tokens.emplace_back( Token(t.first, currentValue)); - } else { - if (variables.find(currentValue) != variables.end()) { - for (auto &token : variables[currentValue]) { - currentDeclaration.tokens.emplace_back(token); - } - } else { - throw std::runtime_error("Unknown variable " + currentValue); - } + foundToken = true; } - foundToken = true; - } - break; - default: + break; + case Token::Type::BareValue: + if (isAlphaNumeric(currentValue)) { + if (currentDeclaration.tokens.size() == 1 && + currentDeclaration.tokens.at(0).getType() == Token::Type::Directive) { + currentDeclaration.tokens.emplace_back( + Token(t.first, currentValue)); + } else { + if (variables.find(currentValue) != variables.end()) { + for (auto &token : variables[currentValue]) { + currentDeclaration.tokens.emplace_back(token); + } + } else { + throw std::runtime_error("Unknown variable " + currentValue); + } + } + foundToken = true; + } + break; + default: + break; + } + + if (foundToken) { + currentValue.clear(); + currentStateIndex = t.second; break; + } + } - if (foundToken) { - currentValue.clear(); - currentStateIndex = t.second; + if (!foundToken) { + //TODO: ERROR + throw std::runtime_error("Could not find new Token state"); + } + } + + if (c == '\n' || c == '\0') { + isComment = false; + if (resetStateIndex < currentStateIndex) { + currentStateIndex = resetStateIndex; + } + + if (!currentDeclaration.tokens.empty()) { + if (currentDeclaration.tokens.size() >= 3 && + currentDeclaration.tokens.at(0).getType() == Token::Type::Directive) { + if (currentDeclaration.tokens.at(0).getTextValue() == ".constant") { + std::vector tokens; + for (auto it = currentDeclaration.tokens.begin() + 2; + it < currentDeclaration.tokens.end(); ++it) { + tokens.push_back(*it); + } + variables[currentDeclaration.tokens.at(1).getTextValue()] = tokens; + } + currentDeclaration = Declaration(); + currentStateIndex = 0; + } else { + currentFunction.declarations.emplace_back(std::move(currentDeclaration)); + currentDeclaration = Declaration(); + } + } + + if (c == '\0') { + functions.emplace_back(std::move(currentFunction)); break; } - } - - if (!foundToken) { - //TODO: ERROR - throw std::runtime_error("Could not find new Token state"); + if (c == ';') { + isComment = true; } + } else if (!isComment) { + currentValue += c; } - - if (c == '\n' || c == '\0') { - isComment = false; - if (resetStateIndex < currentStateIndex) { - currentStateIndex = resetStateIndex; - } - - if (!currentDeclaration.tokens.empty()) { - if (currentDeclaration.tokens.size() >= 3 && - currentDeclaration.tokens.at(0).getType() == Token::Type::Directive) { - if (currentDeclaration.tokens.at(0).getTextValue() == ".constant") { - std::vector tokens; - for (auto it = currentDeclaration.tokens.begin() + 2; - it < currentDeclaration.tokens.end(); ++it) { - tokens.push_back(*it); - } - variables[currentDeclaration.tokens.at(1).getTextValue()] = tokens; - } - currentDeclaration = Declaration(); - currentStateIndex = 0; - } else { - currentFunction.declarations.emplace_back(std::move(currentDeclaration)); - currentDeclaration = Declaration(); - } - } - - if (c == '\0') { - functions.emplace_back(std::move(currentFunction)); - break; - } - } - if (c == ';') { - isComment = true; - } - } else if (!isComment) { - currentValue += c; + }catch (const std::exception& e){ + std::cerr << "Exception: " << e.what() << " on " << currentFunction.label << "\n"; + throw e; } } } diff --git a/src/instructions/Instruction.cpp b/src/instructions/Instruction.cpp index eb001c6..782e895 100644 --- a/src/instructions/Instruction.cpp +++ b/src/instructions/Instruction.cpp @@ -173,8 +173,8 @@ namespace Instruction { segments.push_back(segment); } - uint8_t offset1 = segments.size() > 1 ? std::stoi(segments.at(1).substr(0, 1), nullptr, 10) : 0; - uint8_t offset2 = (segments.size() > 1 && segments.at(1).size() > 1) ? std::stoi( + uint8_t offset1 = segments.size() > 1 ? std::stoul(segments.at(1).substr(0, 1), nullptr, 10) : 0; + uint8_t offset2 = (segments.size() > 1 && segments.at(1).size() > 1) ? std::stoul( segments.at(1).substr(1, 1), nullptr, 10) : 0; return Instruction::parseOperatorResult{