I've been making an assembler for the CHIP-8 these days, and today I tried implementing arguments for the opcodes to work properly. However, when I have to write 2 arguments to complete the opcode, I have this code:
// Chip8Instruction is a struct I've made that holds the final machine code to be written, the mnemonic,
// the argument count and the position for each argument in hex
void writeTwoArguments(Chip8Instruction instruction, const std::string& line, int lineNum, const std::string& romName) {
unsigned int arg1;
unsigned int arg2;
std::string remainingLine = line;
std::string testStr;
std::stringstream stringStream;
// Arguments are comma and then space separated, assume I give 3, FF
std::string::size_type commaPos = line.find(',');
if (commaPos != std::string::npos) {
stringStream << std::hex << remainingLine.substr(0, commaPos); // This writes 3, like it should
testStr = stringStream.str(); // Holds "3", like it should
stringStream >> arg1; // This holds 0x3, like it should
stringStream.str("");
remainingLine.erase(0, commaPos+2); // FF remains, like it should
stringStream << std::hex << remainingLine;
testStr = stringStream.str(); // This holds nothing but it should have "FF", if I don't empty the stream it holds "3" from before
stringStream >> arg2; // This also holds nothing but it should have 0xFF, holds 0x3 if not empty stream
instruction.machineCode = instruction.start + (arg1 * instruction.arg1Pos) + (arg2 * instruction.arg2Pos);
}
writeMultipleDigitsToROM(romName, instruction.machineCode, lineNum);
}
Minimum reproducible example:
#include <iostream>
#include <sstream>
int main() {
std::string line = "3, FF";
std::stringstream stringStream;
unsigned int int1;
unsigned int int2;
// Get position of comma
std::string::size_type commaPos = line.find(',');
// Get everything up to the comma
stringStream << std::hex << line.substr(0, commaPos);
stringStream >> int1; // This holds 0x3, like it should
stringStream.str("");
line.erase(0, commaPos+2); // "FF" remains, like it should
stringStream << std::hex << line;
stringStream >> int2; // This is empty but should be 0xFF
}
As the code comments describe, the held values are either wrong or outdated. What might be the problem, why, and how can I fix it?
All help is appreciated, thank you!
I tried isolating the problem with this code:
However, it appears to work correctly on my end. Not sure what the difference is, sorry, unless I made a mistake in the input format. BTW, I’d recommend, that instead of extracting to string stream, extract from it by wrapping your input in a string stream, like so:
Better yet, you could overload the stream extraction operator
operator>>
for your type, so it could be something like this:You can do that by declaring something like:
Sorry I can’t help with the actual parsing problem, but it isn’t clear to me what I did differently from you.