From 5e2e2eb5da2bcbb0d4e485ecc73bb9697afa1bac Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Tue, 10 Jul 2018 20:23:14 -0700 Subject: 4337 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(). --- subx/010core.cc | 75 ++++++++++++++---------------------------- subx/022transform_immediate.cc | 28 +++++++++++----- 2 files changed, 44 insertions(+), 59 deletions(-) (limited to 'subx') diff --git a/subx/010core.cc b/subx/010core.cc index 44419696..f6c79a78 100644 --- a/subx/010core.cc +++ b/subx/010core.cc @@ -198,61 +198,34 @@ 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; - } - 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; - } + 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; } - } - 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; + // 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(next_byte)); + trace(99, "load") << addr << " -> " << HEXBYTE << NUM(read_mem_u8(addr)) << end(); +//? cerr << addr << " -> " << HEXBYTE << NUM(read_mem_u8(addr)) << '\n'; + addr++; } } - 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; + End_of_program = addr; } inline uint8_t next() { diff --git a/subx/022transform_immediate.cc b/subx/022transform_immediate.cc index eefe9a40..48f5dfa9 100644 --- a/subx/022transform_immediate.cc +++ b/subx/022transform_immediate.cc @@ -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); } -- cgit 1.4.1-2-gfad0