about summary refs log tree commit diff stats
path: root/subx/030---operands.cc
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2018-08-13 16:50:31 -0700
committerKartik Agaram <vc@akkartik.com>2018-08-13 16:50:31 -0700
commit5e8ef005d8387b3b7977cf55e6032bd7b9052470 (patch)
treee1ffc4b889e920821d3bb2f30eb65909db39aaac /subx/030---operands.cc
parent31338623d1d44e422c04cf886429cfa0f479d947 (diff)
downloadmu-5e8ef005d8387b3b7977cf55e6032bd7b9052470.tar.gz
4518
Support both signed and unsigned numbers when parsing strings.
Diffstat (limited to 'subx/030---operands.cc')
-rw-r--r--subx/030---operands.cc27
1 files changed, 24 insertions, 3 deletions
diff --git a/subx/030---operands.cc b/subx/030---operands.cc
index 68a37324..3b3b286c 100644
--- a/subx/030---operands.cc
+++ b/subx/030---operands.cc
@@ -430,16 +430,37 @@ bool is_hex_int(const string& s) {
 }
 
 int32_t parse_int(const string& s) {
+  if (s.empty()) return 0;
   istringstream in(s);
-  int32_t result = 0;
-  in >> std::hex >> result;
+  in >> std::hex;
+  if (s.at(0) == '-') {
+    int32_t result = 0;
+    in >> result;
+    if (!in || !in.eof()) {
+      raise << "not a number: " << s << '\n' << end();
+      return 0;
+    }
+    return result;
+  }
+  uint32_t uresult = 0;
+  in >> uresult;
   if (!in || !in.eof()) {
     raise << "not a number: " << s << '\n' << end();
     return 0;
   }
-  return result;
+  return static_cast<int32_t>(uresult);
+}
+:(before "End Unit Tests")
+void test_parse_int() {
+  CHECK_EQ(0, parse_int("0"));
+  CHECK_EQ(0, parse_int("0x0"));
+  CHECK_EQ(0, parse_int("0x0"));
+  CHECK_EQ(16, parse_int("10"));  // hex always
+  CHECK_EQ(-1, parse_int("-1"));
+  CHECK_EQ(-1, parse_int("0xffffffff"));
 }
 
+:(code)
 string to_string(const line& inst) {
   ostringstream out;
   for (int i = 0;  i < SIZE(inst.words);  ++i) {