8#include <unordered_map>
11#include "absl/strings/str_cat.h"
12#include "absl/strings/str_split.h"
63 return std::hash<std::string>()(k.
mnemonic) ^
64 (std::hash<int>()(
static_cast<int>(k.
mode)) << 1);
70 std::vector<uint8_t>
Parse(
const std::string& instruction) {
73 if (tokens.size() < 1) {
74 throw std::runtime_error(
"Invalid instruction format: " + instruction);
78 std::vector<uint8_t> bytes;
79 while (index < tokens.size()) {
89 const std::string& mnemonic = tokens[index];
95 std::string qualifier =
"";
96 std::string potential_mode = tokens[index];
97 if (absl::StrContains(potential_mode,
".")) {
98 qualifier = potential_mode;
105 std::string operand = tokens[index];
106 if (operand ==
"#") {
110 if (tokens[index] ==
"#") {
112 operand = tokens[index];
115 }
else if (operand ==
"$") {
117 operand = tokens[index];
126 throw std::runtime_error(
"Opcode not found for mnemonic and mode: " +
130 bytes.push_back(opcode_entry->second);
139 std::vector<std::string>
Tokenize(
const std::string& instruction) {
140 std::vector<std::string> tokens;
141 std::regex tokenRegex{R
"((\w+|\.\w+|[\#$]|[0-9a-fA-F]+|[a-zA-Z]+))"};
142 auto words_begin = std::sregex_iterator(instruction.begin(),
143 instruction.end(), tokenRegex);
144 auto words_end = std::sregex_iterator();
146 for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
147 std::smatch match = *i;
148 tokens.push_back(match.str());
155 const std::string& operand,
158 switch (addressing_mode) {
160 bytes.push_back(
static_cast<uint8_t
>(std::stoi(operand,
nullptr, 16)));
164 uint16_t word_operand =
165 static_cast<uint16_t
>(std::stoi(operand,
nullptr, 16));
166 bytes.push_back(
static_cast<uint8_t
>(word_operand & 0xFF));
167 bytes.push_back(
static_cast<uint8_t
>((word_operand >> 8) & 0xFF));
171 uint32_t long_operand =
172 static_cast<uint32_t
>(std::stoul(operand,
nullptr, 16));
173 bytes.push_back(
static_cast<uint8_t
>(long_operand & 0xFF));
174 bytes.push_back(
static_cast<uint8_t
>((long_operand >> 8) & 0xFF));
175 bytes.push_back(
static_cast<uint8_t
>((long_operand >> 16) & 0xFF));
183 bytes.push_back(
static_cast<uint8_t
>(std::stoi(operand,
nullptr, 16)));
188 const std::string& addressingMode = tokens[1];
189 if (addressingMode ==
".b") {
191 }
else if (addressingMode ==
".w") {
193 }
else if (addressingMode ==
".l") {
202 value = std::stoi(str,
nullptr, 16);
204 }
catch (
const std::invalid_argument& e) {
211 value = std::stoul(str,
nullptr, 16);
213 }
catch (
const std::invalid_argument& e) {
442 std::unordered_map<MnemonicMode, uint8_t, MnemonicModeHash>
void AppendOperandBytes(std::vector< uint8_t > &bytes, const std::string &operand, const AddressingMode &addressing_mode)
void CreateInternalOpcodeMap()
std::unordered_map< MnemonicMode, uint8_t, MnemonicModeHash > mnemonic_to_opcode_
bool TryParseHex(const std::string &str, uint32_t &value)
AddressingMode DetermineMode(const std::vector< std::string > &tokens)
bool TryParseByte(const std::string &str, uint8_t &value)
std::vector< std::string > Tokenize(const std::string &instruction)
std::vector< uint8_t > Parse(const std::string &instruction)
@ kDirectPageIndirectIndexedY
@ kStackRelativeIndirectIndexedY
@ kStackRelativeIndirectIndexedYLong
@ kDirectPageIndirectLongIndexedX
@ kProgramCounterRelative
@ kDirectPageIndirectLong
@ kDirectPageIndirectLongIndexedY
@ kDirectPageIndirectIndexedX
@ kProgramCounterRelativeLong
@ kAbsoluteIndexedIndirect
std::size_t operator()(const MnemonicMode &k) const
bool operator==(const MnemonicMode &other) const