Return to the usual whitespace-skipping istreams. No need to go beyond
word-based parsing.

This exercise reinforces the amount of duplication between
load_program() and transform_immediate().
This commit is contained in:
Kartik Agaram 2018-07-10 20:23:14 -07:00
parent ced962dbf8
commit 5e2e2eb5da
2 changed files with 44 additions and 59 deletions

View File

@ -198,63 +198,36 @@ void load_program(const string& text_bytes, uint32_t addr) {
load_program(in, addr);
}
void load_program(istream& in, uint32_t addr) {
in >> std::noskipws;
while (has_data(in)) {
char c1 = next_hex_byte(in);
if (c1 == '\0') break;
if (!has_data(in)) {
raise << "input program truncated mid-byte\n" << end();
return;
string line_data;
getline(in, line_data);
//? cerr << "line: " << SIZE(line_data) << ": " << line_data << '\n';
istringstream line(line_data);
while (has_data(line)) {
string word;
line >> word;
if (word.empty()) continue;
if (word[0] == '#') {
// comment
break;
}
// otherwise it's a hex byte
uint32_t next_byte = 0;
istringstream ss(word);
ss >> std::hex >> next_byte;
if (next_byte > 0xff) {
raise << "invalid hex byte " << word << '\n' << end();
return;
}
write_mem_u8(addr, static_cast<uint8_t>(next_byte));
trace(99, "load") << addr << " -> " << HEXBYTE << NUM(read_mem_u8(addr)) << end();
//? cerr << addr << " -> " << HEXBYTE << NUM(read_mem_u8(addr)) << '\n';
addr++;
}
char c2 = next_hex_byte(in);
if (c2 == '\0') {
raise << "input program truncated mid-byte\n" << end();
return;
}
write_mem_u8(addr, to_byte(c1, c2));
trace(99, "load") << addr << " -> " << HEXBYTE << NUM(read_mem_u8(addr)) << end();
addr++;
}
End_of_program = addr;
}
char next_hex_byte(istream& in) {
while (has_data(in)) {
char c = '\0';
in >> c;
if (c == ' ' || c == '\n') continue;
while (c == '#') {
while (has_data(in)) {
in >> c;
if (c == '\n') {
in >> c;
break;
}
}
}
if (c == '\0') return c;
if (c >= '0' && c <= '9') return c;
if (c >= 'a' && c <= 'f') return c;
if (c >= 'A' && c <= 'F') return tolower(c);
// disallow any non-hex characters, including a '0x' prefix
if (!isspace(c)) {
raise << "invalid non-hex character " << NUM(c) << "\n" << end();
break;
}
}
return '\0';
}
uint8_t to_byte(char hex_byte1, char hex_byte2) {
return to_hex_num(hex_byte1)*16 + to_hex_num(hex_byte2);
}
uint8_t to_hex_num(char c) {
if (c >= '0' && c <= '9') return c - '0';
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
assert(false);
return 0;
}
inline uint8_t next() {
return read_mem_u8(EIP++);
}

View File

@ -23,17 +23,29 @@ Transform.push_back(transform_immediate);
:(code)
void transform_immediate(const string& input, string& output) {
istringstream in(input);
in >> std::noskipws;
ostringstream out;
while (has_data(in)) {
string word = next_word(in);
if (word.find("/imm") == string::npos)
out << word << ' ';
else {
string output = transform_immediate(word);
trace("translate") << "converting '" << word << "' to '" << output << "'" << end();
out << output << ' ';
string line_data;
getline(in, line_data);
istringstream line(line_data);
while (has_data(line)) {
string word;
line >> word;
if (word.empty()) continue;
if (word[0] == '#') {
// skip comment
break;
}
if (word.find("/imm") == string::npos) {
out << word << ' ';
}
else {
string output = transform_immediate(word);
trace("translate") << "converting '" << word << "' to '" << output << "'" << end();
out << output << ' ';
}
}
out << '\n';
}
out.str().swap(output);
}