about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2018-07-10 20:23:14 -0700
committerKartik Agaram <vc@akkartik.com>2018-07-10 20:26:35 -0700
commit5e2e2eb5da2bcbb0d4e485ecc73bb9697afa1bac (patch)
tree4ec0401ec4aba95afc3ca780ff882720a92e2381
parentced962dbf8ac4ad6616c1b3573f268a83a925c8b (diff)
downloadmu-5e2e2eb5da2bcbb0d4e485ecc73bb9697afa1bac.tar.gz
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().
-rw-r--r--subx/010core.cc75
-rw-r--r--subx/022transform_immediate.cc28
2 files changed, 44 insertions, 59 deletions
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<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++;
     }
   }
-  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);
 }