about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-05-12 17:00:56 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-05-12 17:10:33 -0700
commit827898fc1b41e1974bf4ec2eebbd97fe23ff3d08 (patch)
tree437518c84d6df812c6af440c79f578e0949a5c8e
parent3663ca6c2d4c42c4a7bf6af4b2edf71dd8d10dd7 (diff)
downloadmu-827898fc1b41e1974bf4ec2eebbd97fe23ff3d08.tar.gz
1357 - temporarily revert floating-point support
-rw-r--r--002test.cc1
-rw-r--r--003trace.cc2
-rw-r--r--010vm.cc2
-rw-r--r--012transform.cc2
-rw-r--r--020run.cc23
-rw-r--r--021arithmetic.cc234
-rw-r--r--022boolean.cc6
-rw-r--r--023jump.cc6
-rw-r--r--024compare.cc30
-rw-r--r--027debug.cc2
-rw-r--r--030container.cc10
-rw-r--r--031address.cc2
-rw-r--r--032array.cc21
-rw-r--r--033length.cc4
-rw-r--r--034exclusive_container.cc7
-rw-r--r--036call_ingredient.cc4
-rw-r--r--038scheduler.cc4
-rw-r--r--039wait.cc12
-rw-r--r--040brace.cc31
-rw-r--r--041name.cc8
-rw-r--r--042new.cc11
-rw-r--r--043space.cc8
-rw-r--r--044space_surround.cc4
-rw-r--r--047jump_label.cc2
-rw-r--r--050scenario.cc20
-rw-r--r--060string.mu16
-rw-r--r--070display.cc6
-rw-r--r--071print.mu2
-rw-r--r--072scenario_screen.cc29
-rw-r--r--075scenario_keyboard.cc6
30 files changed, 127 insertions, 388 deletions
diff --git a/002test.cc b/002test.cc
index 9a6765d1..0b445526 100644
--- a/002test.cc
+++ b/002test.cc
@@ -54,7 +54,6 @@ if (Run_tests) {
   time_t t; time(&t);
   cerr << "C tests: " << ctime(&t);
   for (index_t i=0; i < sizeof(Tests)/sizeof(Tests[0]); ++i) {
-//?     cerr << "===\n"; //? 1
     run_test(i);
   }
   // End Tests
diff --git a/003trace.cc b/003trace.cc
index 85779092..6fb6dfa7 100644
--- a/003trace.cc
+++ b/003trace.cc
@@ -205,7 +205,7 @@ struct lease_tracer {
 #define START_TRACING_UNTIL_END_OF_SCOPE  lease_tracer leased_tracer;
 :(before "End Test Setup")
 START_TRACING_UNTIL_END_OF_SCOPE
-//? Trace_stream->dump_layer = "all"; //? 2
+//? Trace_stream->dump_layer = "all"; //? 1
 
 :(before "End Tracing")
 void trace_all(const string& label, const list<string>& in) {
diff --git a/010vm.cc b/010vm.cc
index f330b29e..af60896a 100644
--- a/010vm.cc
+++ b/010vm.cc
@@ -250,7 +250,7 @@ string slurp_until(istream& in, char delim) {
 
 void dump_memory() {
   for (map<index_t, long long int>::iterator p = Memory.begin(); p != Memory.end(); ++p) {
-    cout << p->first << ": " << value(p->second) << '\n';
+    cout << p->first << ": " << p->second << '\n';
   }
 }
 :(before "End Includes")
diff --git a/012transform.cc b/012transform.cc
index 1ec8d6e4..7b2b58e8 100644
--- a/012transform.cc
+++ b/012transform.cc
@@ -48,5 +48,5 @@ void parse_int_reagents() {
 void populate_value(reagent& r) {
   if (r.initialized) return;
   if (!is_number(r.name)) return;
-  r.set_value(mu_integer(to_number(r.name)));
+  r.set_value(to_number(r.name));
 }
diff --git a/020run.cc b/020run.cc
index ff23200e..3e220f28 100644
--- a/020run.cc
+++ b/020run.cc
@@ -78,11 +78,7 @@ void run_current_routine()
     switch (current_instruction().operation) {
       // Primitive Recipe Implementations
       case COPY: {
-        products.resize(ingredients.size());
-        for (index_t i = 0; i < ingredients.size(); ++i) {
-          copy(ingredients.at(i).begin(), ingredients.at(i).end(), inserter(products.at(i), products.at(i).begin()));
-        }
-//?         copy(ingredients.begin(), ingredients.end(), inserter(products, products.begin()));
+        copy(ingredients.begin(), ingredients.end(), inserter(products, products.begin()));
         break;
       }
       // End Primitive Recipe Implementations
@@ -188,14 +184,10 @@ vector<long long int> read_memory(reagent x) {
     return result;
   }
   index_t base = x.value;
-//?   cerr << "AAA " << base << '\n'; //? 1
-  assert(!is_negative(base));
-  base = value(base);
   size_t size = size_of(x);
   for (index_t offset = 0; offset < size; ++offset) {
     long long int val = Memory[base+offset];
-//?     cerr << "AAA2 " << val << '\n'; //? 1
-    trace("mem") << "location " << base+offset << " is " << value(val);
+    trace("mem") << "location " << base+offset << " is " << val;
     result.push_back(val);
   }
   return result;
@@ -203,20 +195,11 @@ vector<long long int> read_memory(reagent x) {
 
 void write_memory(reagent x, vector<long long int> data) {
   if (is_dummy(x)) return;
-  // Preprocess x.
-  // End Preprocess x.
   index_t base = x.value;
-  assert(!is_negative(base));
-  base = value(base);
   if (size_of(x) != data.size())
     raise << "size mismatch in storing to " << x.to_string() << '\n';
-//?   cerr << "BBB " << base << '\n'; //? 1
   for (index_t offset = 0; offset < data.size(); ++offset) {
-    trace("mem") << "storing " << value(data.at(offset)) << " in location " << base+offset;
-//?     if (base+offset > 99999) { //? 1
-//?       raise << "AAAAAAAAAAAAAAAAAAAAA\n"; //? 1
-//?       Trace_stream->newline(), exit(0); //? 1
-//?     } //? 1
+    trace("mem") << "storing " << data.at(offset) << " in location " << base+offset;
     Memory[base+offset] = data.at(offset);
   }
 }
diff --git a/021arithmetic.cc b/021arithmetic.cc
index ed852b9e..307bcb18 100644
--- a/021arithmetic.cc
+++ b/021arithmetic.cc
@@ -6,13 +6,13 @@ ADD,
 Recipe_number["add"] = ADD;
 :(before "End Primitive Recipe Implementations")
 case ADD: {
-  double result = 0;
+  long long int result = 0;
   for (index_t i = 0; i < ingredients.size(); ++i) {
     assert(ingredients.at(i).size() == 1);  // scalar
-    result += value(ingredients.at(i).at(0));
+    result += ingredients.at(i).at(0);
   }
   products.resize(1);
-  products.at(0).push_back(mu_noninteger(result));
+  products.at(0).push_back(result);
   break;
 }
 
@@ -53,13 +53,13 @@ Recipe_number["subtract"] = SUBTRACT;
 :(before "End Primitive Recipe Implementations")
 case SUBTRACT: {
   assert(ingredients.at(0).size() == 1);  // scalar
-  double result = value(ingredients.at(0).at(0));
+  long long int result = ingredients.at(0).at(0);
   for (index_t i = 1; i < ingredients.size(); ++i) {
     assert(ingredients.at(i).size() == 1);  // scalar
-    result -= value(ingredients.at(i).at(0));
+    result -= ingredients.at(i).at(0);
   }
   products.resize(1);
-  products.at(0).push_back(mu_noninteger(result));
+  products.at(0).push_back(result);
   break;
 }
 
@@ -99,13 +99,13 @@ MULTIPLY,
 Recipe_number["multiply"] = MULTIPLY;
 :(before "End Primitive Recipe Implementations")
 case MULTIPLY: {
-  double result = 1;
+  long long int result = 1;
   for (index_t i = 0; i < ingredients.size(); ++i) {
     assert(ingredients.at(i).size() == 1);  // scalar
-    result *= value(ingredients.at(i).at(0));
+    result *= ingredients.at(i).at(0);
   }
   products.resize(1);
-  products.at(0).push_back(mu_noninteger(result));
+  products.at(0).push_back(result);
   break;
 }
 
@@ -146,13 +146,13 @@ Recipe_number["divide"] = DIVIDE;
 :(before "End Primitive Recipe Implementations")
 case DIVIDE: {
   assert(ingredients.at(0).size() == 1);  // scalar
-  double result = value(ingredients.at(0).at(0));
+  long long int result = ingredients.at(0).at(0);
   for (index_t i = 1; i < ingredients.size(); ++i) {
     assert(ingredients.at(i).size() == 1);  // scalar
-    result /= value(ingredients.at(i).at(0));
+    result /= ingredients.at(i).at(0);
   }
   products.resize(1);
-  products.at(0).push_back(mu_noninteger(result));
+  products.at(0).push_back(result);
   break;
 }
 
@@ -192,15 +192,11 @@ DIVIDE_WITH_REMAINDER,
 Recipe_number["divide-with-remainder"] = DIVIDE_WITH_REMAINDER;
 :(before "End Primitive Recipe Implementations")
 case DIVIDE_WITH_REMAINDER: {
-  assert(ingredients.at(0).size() == 1);  // scalar
-  long long int a = value(ingredients.at(0).at(0));
-  assert(ingredients.at(1).size() == 1);  // scalar
-  long long int b = value(ingredients.at(1).at(0));
-  long long int quotient = a / b;
-  long long int remainder = a % b;
+  long long int quotient = ingredients.at(0).at(0) / ingredients.at(1).at(0);
+  long long int remainder = ingredients.at(0).at(0) % ingredients.at(1).at(0);
   products.resize(2);
-  products.at(0).push_back(mu_integer(quotient));
-  products.at(1).push_back(mu_integer(remainder));
+  products.at(0).push_back(quotient);
+  products.at(1).push_back(remainder);
   break;
 }
 
@@ -231,201 +227,3 @@ recipe main [
 +mem: storing 2 in location 3
 +run: product 1 is 4
 +mem: storing 5 in location 4
-
-//:: Support for non-integer numbers.
-
-:(scenario divide_with_decimal_point)
-recipe main [
-  # todo: literal floats?
-  1:integer <- divide 5:literal, 2:literal
-]
-+mem: storing 2.5 in location 1
-
-//: Supporting non-integers is hopefully the only place where we need to think
-//: about the size of each location of memory.
-:(after "int main")
-assert(sizeof(long long int) == 8);
-assert(sizeof(double) == 8);
-
-:(before "End Globals")
-//: Conventional hardware uses the most significant bit to represent the sign
-//: in both (2's complement) integers, and so-called floating-point numbers
-//: (with sign, exponent and fraction regions: https://en.wikipedia.org/wiki/Double-precision_floating-point_format)
-
-//: Watch out: perform bitwise operations only on unsigned values to avoid
-//: undefined behavior.
-//: For similar reasons, don't coerce between signed and unsigned, instead
-//: manually interpret the bit-pattern
-
-const unsigned long long int HOST_SET_NEGATIVE = (0x1ULL << 63ULL);
-
-//: As an experiment, we'd like to not have to distinguish between the two in
-//: mu. So we'll use the most-significant bit to represent whether a number is
-//: an integer (MSB 0) or a float (MSB 1). This will halve the set of numbers
-//: we can represent, whether integers or non-integers, but that price seems
-//: reasonable right now.
-const unsigned long long int MU_NUMBER_NONINTEGER_MASK = (0x1ULL << 63ULL);
-//: As a result, the sign bit is now pushed to the second-most significant
-//: bit..
-const unsigned long long int MU_NUMBER_SIGN_MASK = (0x1ULL << 62ULL);
-
-:(after "int main")
-assert(MU_NUMBER_NONINTEGER_MASK == HOST_SET_NEGATIVE);
-
-:(code)
-inline bool is_float(long long int number) {
-  unsigned long long int tmp = *reinterpret_cast<unsigned long long int*>(&number);
-  return tmp & MU_NUMBER_NONINTEGER_MASK;
-}
-
-inline bool is_integer(long long int number) {
-  return !is_float(number);
-}
-
-inline bool is_negative(long long int number) {
-  unsigned long long int tmp = *reinterpret_cast<unsigned long long int*>(&number);
-  return tmp & MU_NUMBER_SIGN_MASK;
-}
-
-inline double value(long long int number) {
-  return is_integer(number) ? to_int(number) : to_float(number);
-}
-
-// convert a mu integer to host representation
-long long int to_int(long long int number) {
-  assert(is_integer(number));
-  if (!is_negative(number)) return number;
-  // negative number
-  unsigned long long int tmp = *reinterpret_cast<unsigned long long int*>(&number);
-  // slide the sign over by one bit
-  tmp = tmp | HOST_SET_NEGATIVE;
-//?   // clear the old sign bit
-//?   // so the range of numbers we can represent shrinks by half
-//?   tmp = tmp & (~MU_NUMBER_SIGN_MASK);
-  // reinterpret back as signed
-  long long int result = *reinterpret_cast<long long int*>(&tmp);
-  return result;
-}
-
-// convert an integer from host representation to mu representation
-long long int mu_integer(long long int n) {
-  unsigned long long int tmp = *reinterpret_cast<unsigned long long int*>(&n);
-  // slide the sign to the right
-  if (tmp & HOST_SET_NEGATIVE) tmp = tmp | MU_NUMBER_SIGN_MASK;
-  // clear the old sign bit
-  tmp = tmp & (~HOST_SET_NEGATIVE);
-  // reinterpret back as signed
-  long long int result = *reinterpret_cast<long long int*>(&tmp);
-  assert(is_integer(result));
-//?   printf("%llx\n", result); //? 1
-  return result;
-}
-
-// convert a mu non-integer to host representation
-double to_float(long long int number) {
-  assert(is_float(number));
-  unsigned long long int tmp = *reinterpret_cast<unsigned long long int*>(&number);
-  // slide the entire number over the most significant bit
-  // so the precision of numbers we can represent shrinks by 1 bit
-  tmp = (tmp << 1);
-  double result = *reinterpret_cast<double*>(&tmp);
-  return result;
-}
-
-// convert a float from host representation to mu representation
-long long int mu_noninteger(double n) {
-  unsigned long long int tmp = *reinterpret_cast<unsigned long long int*>(&n);
-  tmp = (tmp >> 1);
-  tmp = (tmp | MU_NUMBER_NONINTEGER_MASK);
-  long long int result = *reinterpret_cast<long long int*>(&tmp);
-  assert(is_float(result));
-  return result;
-}
-
-// Spot-check some bit-patterns and make sure they convert back to themselves.
-void test_integer_representation() {
-  // Assuming long long int is 8 bytes:
-  static const int nbits = 64;
-//?   cerr << '\n'; //? 1
-//?   cerr << nbits << " iterations\n"; //? 1
-//?   cerr << std::hex; //? 1
-//?   cerr << "type mask: " << MU_NUMBER_NONINTEGER_MASK << '\n'; //? 1
-//?   cerr << "sign mask: " << MU_NUMBER_SIGN_MASK << '\n'; //? 1
-//?   cerr << std::dec; //? 1
-  // until the last 2 bits all integers retain their value
-  for (int i = 0; i < nbits-2; ++i) {
-    unsigned long long int x = (0x1ULL << i);
-    long long int n = *reinterpret_cast<long long int*>(&x);
-//?     cerr << i << ": " << "0x" << std::hex << n << std::dec << ' ' << n << " => " << to_int(n) << '\n'; //? 2
-    CHECK(is_integer(n));
-    CHECK_EQ(n, to_int(n));
-//?     printf("0x%llx\n", mu_integer(to_int(n))); //? 1
-    CHECK_EQ(n, mu_integer(to_int(n)));
-  }
-  // second-last bit
-  unsigned long long int x = (0x1ULL << (nbits-2));
-  long long int n = *reinterpret_cast<long long int*>(&x);
-  CHECK(is_integer(n));
-//?   cerr << nbits-2 << ": " << "0x" << std::hex << n << std::dec << ' ' << n << " => " << to_int(n) << '\n'; //? 1
-  CHECK(is_negative(n));
-  CHECK_EQ(n, mu_integer(to_int(n)));
-  // most significant bit is for non-integers below
-}
-
-// Now go the other way; spot-check a few mu integers and make sure they
-// convert back to themselves.
-void test_small_integers() {
-  for (long long int n = -1000; n < 1000; ++n) {
-//?     printf("0x%llx vs 0x%llx\n", n, to_int(mu_integer(n))); //? 1
-    CHECK_EQ(n, to_int(mu_integer(n)));
-  }
-}
-
-// Spot-check some bit-patterns and make sure they convert back to themselves.
-void test_noninteger_representation() {
-  // Assuming long long int is 8 bytes:
-  static const int nbits = 64;
-  static const long long int FLOAT_MASK = (0x1ULL << (nbits-1));
-//?   double f = -2.0; //? 1
-//?   printf("0x%llx\n", *(long long int*)&f); //? 1
-//?   printf("\n"); //? 1
-  for (int fraction = 0; fraction < 52; ++fraction) {
-    for (int exponent = 52; exponent < 63; ++exponent) {
-      long long int n = (0x1ULL << fraction) | (0x1ULL << exponent) | FLOAT_MASK;
-      CHECK(is_float(n));
-      double result = to_float(n);
-//?       double result_on_host = *reinterpret_cast<double*>(&n); //? 1
-//?       printf("%02d %d: 0x%llx %.30e\n", fraction, exponent, n, result_on_host); //? 1
-//?       printf("=>                        %.30e\n", result); //? 1
-//?       printf("=>     0x%llx\n", mu_noninteger(result)); //? 1
-      CHECK_EQ(n, mu_noninteger(result));
-    }
-    int exponent = 63;
-    long long int n = ((0x1ULL << 62) | (0x1ULL << exponent) | FLOAT_MASK);
-    CHECK(is_float(n));
-    double result = to_float(n);
-//?     double result_on_host = *reinterpret_cast<double*>(&n); //? 1
-//?     printf("%02d %d: 0x%llx %.30e\n", fraction, nbits-1, n, result_on_host); //? 1
-//?     printf("=>                        %.30e\n", result); //? 1
-//?     printf("=>     0x%llx\n", mu_noninteger(result)); //? 1
-    CHECK_EQ(n, mu_noninteger(result));
-  }
-}
-
-:(code)
-// Now go the other way; spot-check a few mu non-integers and make sure they
-// convert back to themselves.
-void test_small_nonintegers() {
-  for (double n = -1000.0; n < 1000.0; n += 0.001) {
-//?     printf("%.30e vs %.30e\n", n, to_float(mu_noninteger(n))); //? 1
-    CHECK(fabs(n - to_float(mu_noninteger(n))) < epsilon);
-  }
-}
-
-:(before "End Globals")
-const double epsilon = 1e-13;
-
-:(before "End Includes")
-#include<iomanip>
-#include<limits>
-#include<math.h>
diff --git a/022boolean.cc b/022boolean.cc
index bca425b0..e91dc209 100644
--- a/022boolean.cc
+++ b/022boolean.cc
@@ -12,7 +12,7 @@ case AND: {
     result = result && ingredients.at(i).at(0);
   }
   products.resize(1);
-  products.at(0).push_back(result);  // boolean must be a positive integer
+  products.at(0).push_back(result);
   break;
 }
 
@@ -60,7 +60,7 @@ case OR: {
     result = result || ingredients.at(i).at(0);
   }
   products.resize(1);
-  products.at(0).push_back(result);  // boolean must be a positive integer
+  products.at(0).push_back(result);
   break;
 }
 
@@ -105,7 +105,7 @@ case NOT: {
   products.resize(ingredients.size());
   for (index_t i = 0; i < ingredients.size(); ++i) {
     assert(ingredients.at(i).size() == 1);  // must be a scalar
-    products.at(i).push_back(!ingredients.at(i).at(0));  // boolean must be a positive integer
+    products.at(i).push_back(!ingredients.at(i).at(0));
   }
   break;
 }
diff --git a/023jump.cc b/023jump.cc
index 4252b36e..807113f3 100644
--- a/023jump.cc
+++ b/023jump.cc
@@ -9,7 +9,7 @@ case JUMP: {
   assert(current_instruction().ingredients.at(0).initialized);
   assert(ingredients.size() == 1);
   assert(ingredients.at(0).size() == 1);  // scalar
-  instruction_counter += value(ingredients.at(0).at(0));
+  instruction_counter += ingredients.at(0).at(0);
   trace("run") << "jumping to instruction " << instruction_counter+1;
   break;
 }
@@ -49,7 +49,7 @@ case JUMP_IF: {
     break;
   }
   assert(ingredients.at(1).size() == 1);  // scalar
-  instruction_counter += value(ingredients.at(1).at(0));
+  instruction_counter += ingredients.at(1).at(0);
   trace("run") << "jumping to instruction " << instruction_counter+1;
   break;
 }
@@ -89,7 +89,7 @@ case JUMP_UNLESS: {
     break;
   }
   assert(ingredients.at(1).size() == 1);  // scalar
-  instruction_counter += value(ingredients.at(1).at(0));
+  instruction_counter += ingredients.at(1).at(0);
   trace("run") << "jumping to instruction " << instruction_counter+1;
   break;
 }
diff --git a/024compare.cc b/024compare.cc
index c9d73170..92d87e5c 100644
--- a/024compare.cc
+++ b/024compare.cc
@@ -9,23 +9,13 @@ case EQUAL: {
   vector<long long int>& exemplar = ingredients.at(0);
   bool result = true;
   for (index_t i = 1; i < ingredients.size(); ++i) {
-//?     cerr << ingredients.at(i).at(0) << " <=> " << exemplar.at(0) << '\n'; //? 1
-//?     cerr << value(ingredients.at(i).at(0)) << " <=> " << value(exemplar.at(0)) << '\n'; //? 1
-    if (ingredients.at(i).size() != exemplar.size()) {
+    if (!equal(ingredients.at(i).begin(), ingredients.at(i).end(), exemplar.begin())) {
       result = false;
       break;
     }
-//?     if (!equal(ingredients.at(i).begin(), ingredients.at(i).end(), exemplar.begin()))
-    for (index_t j = 0; j < exemplar.size(); ++j) {
-      if (value(ingredients.at(i).at(j)) != value(exemplar.at(j))) {
-        result = false;
-        goto finish;
-      }
-    }
   }
-  finish:
   products.resize(1);
-  products.at(0).push_back(result);  // boolean must be a positive integer
+  products.at(0).push_back(result);
   break;
 }
 
@@ -80,12 +70,12 @@ case GREATER_THAN: {
     assert(ingredients.at(i).size() == 1);  // scalar
   }
   for (index_t i = /**/1; i < ingredients.size(); ++i) {
-    if (value(ingredients.at(i-1).at(0)) <= value(ingredients.at(i).at(0))) {
+    if (ingredients.at(i-1).at(0) <= ingredients.at(i).at(0)) {
       result = false;
     }
   }
   products.resize(1);
-  products.at(0).push_back(result);  // boolean must be a positive integer
+  products.at(0).push_back(result);
   break;
 }
 
@@ -140,12 +130,12 @@ case LESSER_THAN: {
     assert(ingredients.at(i).size() == 1);  // scalar
   }
   for (index_t i = /**/1; i < ingredients.size(); ++i) {
-    if (value(ingredients.at(i-1).at(0)) >= value(ingredients.at(i).at(0))) {
+    if (ingredients.at(i-1).at(0) >= ingredients.at(i).at(0)) {
       result = false;
     }
   }
   products.resize(1);
-  products.at(0).push_back(result);  // boolean must be a positive integer
+  products.at(0).push_back(result);
   break;
 }
 
@@ -200,12 +190,12 @@ case GREATER_OR_EQUAL: {
     assert(ingredients.at(i).size() == 1);  // scalar
   }
   for (index_t i = /**/1; i < ingredients.size(); ++i) {
-    if (value(ingredients.at(i-1).at(0)) < value(ingredients.at(i).at(0))) {
+    if (ingredients.at(i-1).at(0) < ingredients.at(i).at(0)) {
       result = false;
     }
   }
   products.resize(1);
-  products.at(0).push_back(result);  // boolean must be a positive integer
+  products.at(0).push_back(result);
   break;
 }
 
@@ -274,12 +264,12 @@ case LESSER_OR_EQUAL: {
     assert(ingredients.at(i).size() == 1);  // scalar
   }
   for (index_t i = /**/1; i < ingredients.size(); ++i) {
-    if (value(ingredients.at(i-1).at(0)) > value(ingredients.at(i).at(0))) {
+    if (ingredients.at(i-1).at(0) > ingredients.at(i).at(0)) {
       result = false;
     }
   }
   products.resize(1);
-  products.at(0).push_back(result);  // boolean must be a positive integer
+  products.at(0).push_back(result);
   break;
 }
 
diff --git a/027debug.cc b/027debug.cc
index 004dd68d..bbce5d6e 100644
--- a/027debug.cc
+++ b/027debug.cc
@@ -15,7 +15,7 @@ case _PRINT: {
       for (index_t j = 0; j < ingredients.at(i).size(); ++j) {
         trace("run") << "$print: " << ingredients.at(i).at(j);
         if (j > 0) cout << " ";
-        cout << value(ingredients.at(i).at(j));
+        cout << ingredients.at(i).at(j);
       }
     }
   }
diff --git a/030container.cc b/030container.cc
index 042c0b5a..edde3395 100644
--- a/030container.cc
+++ b/030container.cc
@@ -110,8 +110,7 @@ Recipe_number["get"] = GET;
 :(before "End Primitive Recipe Implementations")
 case GET: {
   reagent base = current_instruction().ingredients.at(0);
-  assert(!is_negative(base.value));
-  index_t base_address = value(base.value);
+  index_t base_address = base.value;
   type_number base_type = base.types.at(0);
   assert(Type[base_type].kind == container);
   assert(isa_literal(current_instruction().ingredients.at(1)));
@@ -127,7 +126,7 @@ case GET: {
   type_number src_type = Type[base_type].elements.at(offset).at(0);
   trace("run") << "its type is " << src_type;
   reagent tmp;
-  tmp.set_value(mu_integer(src));
+  tmp.set_value(src);
   tmp.types.push_back(src_type);
   products.push_back(read_memory(tmp));
   break;
@@ -175,8 +174,7 @@ Recipe_number["get-address"] = GET_ADDRESS;
 :(before "End Primitive Recipe Implementations")
 case GET_ADDRESS: {
   reagent base = current_instruction().ingredients.at(0);
-  assert(!is_negative(base.value));
-  index_t base_address = value(base.value);
+  index_t base_address = base.value;
   type_number base_type = base.types.at(0);
   assert(Type[base_type].kind == container);
   assert(isa_literal(current_instruction().ingredients.at(1)));
@@ -188,6 +186,6 @@ case GET_ADDRESS: {
   }
   trace("run") << "address to copy is " << result;
   products.resize(1);
-  products.at(0).push_back(mu_integer(result));  // address must be a positive integer
+  products.at(0).push_back(result);
   break;
 }
diff --git a/031address.cc b/031address.cc
index 259ea976..58d93466 100644
--- a/031address.cc
+++ b/031address.cc
@@ -48,7 +48,7 @@ reagent deref(reagent x) {
   assert(x.types.at(0) == ADDRESS);
 
   // compute value
-  result.set_value(mu_integer(value(Memory[x.value])));  // address must be a positive integer
+  result.set_value(Memory[x.value]);
   trace("mem") << "location " << x.value << " is " << result.value;
 
   // populate types
diff --git a/032array.cc b/032array.cc
index 19a4ac50..67b03293 100644
--- a/032array.cc
+++ b/032array.cc
@@ -53,7 +53,7 @@ if (x.types.at(0) != Type_number["array"] && size_of(x) != data.size())
   if (r.types.at(0) == Type_number["array"]) {
     assert(r.types.size() > 1);
     // skip the 'array' type to get at the element type
-    return 1 + value(Memory[r.value])*size_of(array_element(r.types));
+    return 1 + Memory[r.value]*size_of(array_element(r.types));
   }
 
 //:: To access elements of an array, use 'index'
@@ -98,8 +98,7 @@ case INDEX: {
 //?   if (Trace_stream) Trace_stream->dump_layer = "run"; //? 1
   reagent base = canonize(current_instruction().ingredients.at(0));
 //?   trace("run") << "ingredient 0 after canonize: " << base.to_string(); //? 1
-  assert(!is_negative(base.value));
-  index_t base_address = value(base.value);
+  index_t base_address = base.value;
   assert(base.types.at(0) == Type_number["array"]);
   reagent offset = canonize(current_instruction().ingredients.at(1));
 //?   trace("run") << "ingredient 1 after canonize: " << offset.to_string(); //? 1
@@ -107,12 +106,11 @@ case INDEX: {
   vector<type_number> element_type = array_element(base.types);
 //?   trace("run") << "offset: " << offset_val.at(0); //? 1
 //?   trace("run") << "size of elements: " << size_of(element_type); //? 1
-  assert(offset_val.size() == 1);  // scalar
-  index_t src = base_address + 1 + value(offset_val.at(0))*size_of(element_type);
+  index_t src = base_address + 1 + offset_val.at(0)*size_of(element_type);
   trace("run") << "address to copy is " << src;
   trace("run") << "its type is " << element_type.at(0);
   reagent tmp;
-  tmp.set_value(mu_integer(src));
+  tmp.set_value(src);
   copy(element_type.begin(), element_type.end(), inserter(tmp.types, tmp.types.begin()));
   products.push_back(read_memory(tmp));
   break;
@@ -155,14 +153,13 @@ Recipe_number["index-address"] = INDEX_ADDRESS;
 :(before "End Primitive Recipe Implementations")
 case INDEX_ADDRESS: {
   reagent base = canonize(current_instruction().ingredients.at(0));
-  assert(!is_negative(base.value));
-  index_t base_address = value(base.value);
+  index_t base_address = base.value;
   assert(base.types.at(0) == Type_number["array"]);
-  vector<long long int>& offset_val = ingredients.at(1);
-  assert(offset_val.size() == 1);
+  reagent offset = canonize(current_instruction().ingredients.at(1));
+  vector<long long int> offset_val(read_memory(offset));
   vector<type_number> element_type = array_element(base.types);
-  index_t result = base_address + 1 + value(offset_val.at(0))*size_of(element_type);
+  index_t result = base_address + 1 + offset_val.at(0)*size_of(element_type);
   products.resize(1);
-  products.at(0).push_back(mu_integer(result));  // address must be a positive integer
+  products.at(0).push_back(result);
   break;
 }
diff --git a/033length.cc b/033length.cc
index 8f18180e..2268611a 100644
--- a/033length.cc
+++ b/033length.cc
@@ -23,8 +23,6 @@ case LENGTH: {
     break;
   }
   products.resize(1);
-  assert(is_integer(Memory[x.value]));
-  assert(!is_negative(Memory[x.value]));
-  products.at(0).push_back(Memory[x.value]);  // length must be a positive integer
+  products.at(0).push_back(Memory[x.value]);
   break;
 }
diff --git a/034exclusive_container.cc b/034exclusive_container.cc
index 5b849916..b2855f79 100644
--- a/034exclusive_container.cc
+++ b/034exclusive_container.cc
@@ -89,20 +89,19 @@ Recipe_number["maybe-convert"] = MAYBE_CONVERT;
 :(before "End Primitive Recipe Implementations")
 case MAYBE_CONVERT: {
   reagent base = canonize(current_instruction().ingredients.at(0));
-  assert(!is_negative(base.value));
-  index_t base_address = value(base.value);
+  index_t base_address = base.value;
   type_number base_type = base.types.at(0);
   assert(Type[base_type].kind == exclusive_container);
   assert(isa_literal(current_instruction().ingredients.at(1)));
   index_t tag = current_instruction().ingredients.at(1).value;
   long long int result;
-  if (tag == static_cast<index_t>(value(Memory[base_address]))) {
+  if (tag == static_cast<index_t>(Memory[base_address])) {
     result = base_address+1;
   }
   else {
     result = 0;
   }
   products.resize(1);
-  products.at(0).push_back(mu_integer(result));  // address must be a positive integer
+  products.at(0).push_back(result);
   break;
 }
diff --git a/036call_ingredient.cc b/036call_ingredient.cc
index f5964e4b..5c321ef9 100644
--- a/036call_ingredient.cc
+++ b/036call_ingredient.cc
@@ -105,14 +105,14 @@ case INGREDIENT: {
     products.push_back(
         Current_routine->calls.top().ingredient_atoms.at(Current_routine->calls.top().next_ingredient_to_process));
     assert(products.size() == 1);  products.resize(2);  // push a new vector
-    products.at(1).push_back(1);  // non-negative integer
+    products.at(1).push_back(1);
     ++Current_routine->calls.top().next_ingredient_to_process;
   }
   else {
     if (current_instruction().products.size() > 1) {
       products.resize(2);
       products.at(0).push_back(0);  // todo: will fail noisily if we try to read a compound value
-      products.at(1).push_back(0);  // non-negative integer
+      products.at(1).push_back(0);
     }
   }
   break;
diff --git a/038scheduler.cc b/038scheduler.cc
index 64889f31..99ced920 100644
--- a/038scheduler.cc
+++ b/038scheduler.cc
@@ -135,7 +135,7 @@ case START_RUNNING: {
     new_routine->calls.top().ingredient_atoms.push_back(ingredients.at(i));
   Routines.push_back(new_routine);
   products.resize(1);
-  products.at(0).push_back(new_routine->id);  // routine ids are positive integers
+  products.at(0).push_back(new_routine->id);
   break;
 }
 
@@ -301,7 +301,7 @@ case ROUTINE_STATE: {
     }
   }
   products.resize(1);
-  products.at(0).push_back(result);  // routine states are positive integers
+  products.at(0).push_back(result);
   break;
 }
 
diff --git a/039wait.cc b/039wait.cc
index a674ad25..82354a53 100644
--- a/039wait.cc
+++ b/039wait.cc
@@ -24,7 +24,7 @@ WAITING,
 :(before "End routine Fields")
 // only if state == WAITING
 index_t waiting_on_location;
-double old_value_of_waiting_location;
+int old_value_of_waiting_location;
 :(before "End routine Constructor")
 waiting_on_location = old_value_of_waiting_location = 0;
 
@@ -39,9 +39,9 @@ case WAIT_FOR_LOCATION: {
   reagent loc = canonize(current_instruction().ingredients.at(0));
   Current_routine->state = WAITING;
   Current_routine->waiting_on_location = loc.value;
-  Current_routine->old_value_of_waiting_location = value(Memory[loc.value]);
-  trace("run") << "waiting for location " << loc.value << " to change from " << value(Memory[loc.value]);
-//?   trace("schedule") << Current_routine->id << ": waiting for location " << loc.value << " to change from " << value(Memory[loc.value]); //? 2
+  Current_routine->old_value_of_waiting_location = Memory[loc.value];
+  trace("run") << "waiting for location " << loc.value << " to change from " << Memory[loc.value];
+//?   trace("schedule") << Current_routine->id << ": waiting for location " << loc.value << " to change from " << Memory[loc.value]; //? 2
   break;
 }
 
@@ -54,9 +54,9 @@ for (index_t i = 0; i < Routines.size(); ++i) {
 //?   trace("schedule") << "waiting on location: " << Routines.at(i)->waiting_on_location; //? 1
 //?   if (Routines.at(i)->waiting_on_location) //? 2
 //?     trace("schedule") << "checking routine " << Routines.at(i)->id << " waiting on location " //? 2
-//?       << Routines.at(i)->waiting_on_location << ": " << value(Memory[Routines.at(i)->waiting_on_location]) << " vs " << Routines.at(i)->old_value_of_waiting_location; //? 2
+//?       << Routines.at(i)->waiting_on_location << ": " << Memory[Routines.at(i)->waiting_on_location] << " vs " << Routines.at(i)->old_value_of_waiting_location; //? 2
   if (Routines.at(i)->waiting_on_location &&
-      value(Memory[Routines.at(i)->waiting_on_location]) != Routines.at(i)->old_value_of_waiting_location) {
+      Memory[Routines.at(i)->waiting_on_location] != Routines.at(i)->old_value_of_waiting_location) {
     trace("schedule") << "waking up routine\n";
     Routines.at(i)->state = RUNNING;
     Routines.at(i)->waiting_on_location = Routines.at(i)->old_value_of_waiting_location = 0;
diff --git a/040brace.cc b/040brace.cc
index f4c493c9..224dbf96 100644
--- a/040brace.cc
+++ b/040brace.cc
@@ -69,10 +69,10 @@ void transform_braces(const recipe_number r) {
       }
       else {
         reagent ing;
-        ing.set_value(mu_integer(open_braces.top()-index));
+        ing.set_value(open_braces.top()-index);
         ing.types.push_back(Type_number["offset"]);
         inst.ingredients.push_back(ing);
-        trace("after-brace") << "jump " << to_int(ing.value) << ":offset";
+        trace("after-brace") << "jump " << ing.value << ":offset";
         trace("after-brace") << index << ": " << ing.to_string();
         trace("after-brace") << index << ": " << Recipe[r].steps.at(index).ingredients.at(0).to_string();
       }
@@ -85,10 +85,10 @@ void transform_braces(const recipe_number r) {
       }
       else {
         reagent ing;
-        ing.set_value(mu_integer(matching_brace(open_braces.top(), braces) - index - 1));
+        ing.set_value(matching_brace(open_braces.top(), braces) - index - 1);
         ing.types.push_back(Type_number["offset"]);
         inst.ingredients.push_back(ing);
-        trace("after-brace") << "jump " << to_int(ing.value) << ":offset";
+        trace("after-brace") << "jump " << ing.value << ":offset";
       }
     }
     else if (inst.operation == Recipe_number["loop-if"]) {
@@ -99,10 +99,10 @@ void transform_braces(const recipe_number r) {
       }
       else {
         reagent ing;
-        ing.set_value(mu_integer(open_braces.top()-index));
+        ing.set_value(open_braces.top()-index);
         ing.types.push_back(Type_number["offset"]);
         inst.ingredients.push_back(ing);
-        trace("after-brace") << "jump-if " << inst.ingredients.at(0).name << ", " << to_int(ing.value) << ":offset";
+        trace("after-brace") << "jump-if " << inst.ingredients.at(0).name << ", " << ing.value << ":offset";
       }
     }
     else if (inst.operation == Recipe_number["break-if"]) {
@@ -113,10 +113,10 @@ void transform_braces(const recipe_number r) {
       }
       else {
         reagent ing;
-        ing.set_value(mu_integer(matching_brace(open_braces.top(), braces) - index - 1));
+        ing.set_value(matching_brace(open_braces.top(), braces) - index - 1);
         ing.types.push_back(Type_number["offset"]);
         inst.ingredients.push_back(ing);
-        trace("after-brace") << "jump-if " << inst.ingredients.at(0).name << ", " << to_int(ing.value) << ":offset";
+        trace("after-brace") << "jump-if " << inst.ingredients.at(0).name << ", " << ing.value << ":offset";
       }
     }
     else if (inst.operation == Recipe_number["loop-unless"]) {
@@ -127,10 +127,10 @@ void transform_braces(const recipe_number r) {
       }
       else {
         reagent ing;
-        ing.set_value(mu_integer(open_braces.top()-index));
+        ing.set_value(open_braces.top()-index);
         ing.types.push_back(Type_number["offset"]);
         inst.ingredients.push_back(ing);
-        trace("after-brace") << "jump-unless " << inst.ingredients.at(0).name << ", " << to_int(ing.value) << ":offset";
+        trace("after-brace") << "jump-unless " << inst.ingredients.at(0).name << ", " << ing.value << ":offset";
       }
     }
     else if (inst.operation == Recipe_number["break-unless"]) {
@@ -142,10 +142,10 @@ void transform_braces(const recipe_number r) {
       }
       else {
         reagent ing;
-        ing.set_value(mu_integer(matching_brace(open_braces.top(), braces) - index - 1));
+        ing.set_value(matching_brace(open_braces.top(), braces) - index - 1);
         ing.types.push_back(Type_number["offset"]);
         inst.ingredients.push_back(ing);
-        trace("after-brace") << "jump-unless " << inst.ingredients.at(0).name << ", " << to_int(ing.value) << ":offset";
+        trace("after-brace") << "jump-unless " << inst.ingredients.at(0).name << ", " << ing.value << ":offset";
       }
     }
     else {
@@ -380,14 +380,13 @@ recipe test-factorial [
   1:integer <- copy 5:literal
   2:integer <- copy 1:literal
   {
-    3:boolean <- equal 1:integer, 1:literal
+    3:boolean <- equal 1:integer 1:literal
     break-if 3:boolean
-#?     $print 1:integer, [ ], 2:integer, [
-#? ]
 #    $print 1:integer
     2:integer <- multiply 2:integer, 1:integer
     1:integer <- subtract 1:integer, 1:literal
     loop
   }
+  4:integer <- copy 2:integer  # trigger a read
 ]
-+mem: storing 120 in location 2
++mem: location 2 is 120
diff --git a/041name.cc b/041name.cc
index ff2b811c..e5e9449b 100644
--- a/041name.cc
+++ b/041name.cc
@@ -46,7 +46,7 @@ void transform_names(const recipe_number r) {
       if (!already_transformed(inst.ingredients.at(in), names)) {
         raise << "use before set: " << inst.ingredients.at(in).name << " in " << Recipe[r].name << '\n';
       }
-      inst.ingredients.at(in).set_value(mu_integer(lookup_name(inst.ingredients.at(in), r)));  // must be a positive integer
+      inst.ingredients.at(in).set_value(lookup_name(inst.ingredients.at(in), r));
     }
     for (index_t out = 0; out < inst.products.size(); ++out) {
       if (is_numeric_location(inst.products.at(out))) numeric_locations_used = true;
@@ -57,7 +57,7 @@ void transform_names(const recipe_number r) {
         names[inst.products.at(out).name] = curr_idx;
         curr_idx += size_of(inst.products.at(out));
       }
-      inst.products.at(out).set_value(mu_integer(lookup_name(inst.products.at(out), r)));  // must be a positive integer
+      inst.products.at(out).set_value(lookup_name(inst.products.at(out), r));
     }
   }
   if (names_used && numeric_locations_used)
@@ -220,7 +220,7 @@ if (inst.operation == Recipe_number["get"]
   if (inst.ingredients.at(1).name.find_first_not_of("0123456789") == string::npos) continue;
   // since first non-address in base type must be a container, we don't have to canonize
   type_number base_type = skip_addresses(inst.ingredients.at(0).types);
-  inst.ingredients.at(1).set_value(mu_integer(find_element_name(base_type, inst.ingredients.at(1).name)));  // must be a positive integer
+  inst.ingredients.at(1).set_value(find_element_name(base_type, inst.ingredients.at(1).name));
   trace("name") << "element " << inst.ingredients.at(1).name << " of type " << Type[base_type].name << " is at offset " << inst.ingredients.at(1).value;
 }
 
@@ -256,6 +256,6 @@ if (inst.operation == Recipe_number["maybe-convert"]) {
   if (inst.ingredients.at(1).name.find_first_not_of("0123456789") == string::npos) continue;
   // since first non-address in base type must be an exclusive container, we don't have to canonize
   type_number base_type = skip_addresses(inst.ingredients.at(0).types);
-  inst.ingredients.at(1).set_value(mu_integer(find_element_name(base_type, inst.ingredients.at(1).name)));  // must be a positive integer
+  inst.ingredients.at(1).set_value(find_element_name(base_type, inst.ingredients.at(1).name));
   trace("name") << "variant " << inst.ingredients.at(1).name << " of type " << Type[base_type].name << " has tag " << inst.ingredients.at(1).value;
 }
diff --git a/042new.cc b/042new.cc
index c960210b..754091c8 100644
--- a/042new.cc
+++ b/042new.cc
@@ -37,7 +37,7 @@ if (inst.operation == Recipe_number["new"]) {
 //?   cout << inst.ingredients.at(0).to_string() << '\n'; //? 1
   assert(isa_literal(inst.ingredients.at(0)));
   if (inst.ingredients.at(0).properties.at(0).second.at(0) == "type") {
-    inst.ingredients.at(0).set_value(mu_integer(Type_number[inst.ingredients.at(0).name]));  // type numbers must be positive integers
+    inst.ingredients.at(0).set_value(Type_number[inst.ingredients.at(0).name]);
   }
   trace("new") << inst.ingredients.at(0).name << " -> " << inst.ingredients.at(0).value;
 }
@@ -51,16 +51,15 @@ Recipe_number["new"] = NEW;
 :(before "End Primitive Recipe Implementations")
 case NEW: {
   // compute the space we need
-//?   cerr << current_instruction().to_string() << '\n'; //? 1
   size_t size = 0;
   size_t array_length = 0;
   {
     vector<type_number> type;
     assert(isa_literal(current_instruction().ingredients.at(0)));
-    type.push_back(value(current_instruction().ingredients.at(0).value));  // type numbers must be positive integers
+    type.push_back(current_instruction().ingredients.at(0).value);
     if (current_instruction().ingredients.size() > 1) {
       // array
-      array_length = value(ingredients.at(1).at(0));
+      array_length = ingredients.at(1).at(0);
       trace("mem") << "array size is " << array_length;
       size = array_length*size_of(type) + /*space for length*/1;
     }
@@ -79,7 +78,7 @@ case NEW: {
   products.at(0).push_back(result);
   // initialize array if necessary
   if (current_instruction().ingredients.size() > 1) {
-    Memory[result] = mu_integer(array_length);  // array lengths must be positive integers
+    Memory[result] = array_length;
   }
   // bump
   Current_routine->alloc += size;
@@ -90,7 +89,6 @@ case NEW: {
 
 :(code)
 void ensure_space(size_t size) {
-//?   cerr << size << '\n'; //? 1
   assert(size <= Initial_memory_per_routine);
 //?   cout << Current_routine->alloc << " " << Current_routine->alloc_max << " " << size << '\n'; //? 1
   if (Current_routine->alloc + size > Current_routine->alloc_max) {
@@ -160,7 +158,6 @@ if (isa_literal(current_instruction().ingredients.at(0))
   // allocate an array just large enough for it
   size_t string_length = current_instruction().ingredients.at(0).name.size();
 //?   cout << "string_length is " << string_length << '\n'; //? 1
-//?   cerr << "AAA\n"; //? 1
   ensure_space(string_length+1);  // don't forget the extra location for array size
   products.resize(1);
   products.at(0).push_back(Current_routine->alloc);
diff --git a/043space.cc b/043space.cc
index 24d63505..b0ee7f85 100644
--- a/043space.cc
+++ b/043space.cc
@@ -42,7 +42,7 @@ reagent absolutize(reagent x) {
 //?   cout << "not raw: " << x.to_string() << '\n'; //? 1
   assert(x.initialized);
   reagent r = x;
-  r.set_value(mu_integer(address(r.value, space_base(r))));  // must be a positive integer
+  r.set_value(address(r.value, space_base(r)));
 //?   cout << "after absolutize: " << r.value << '\n'; //? 1
   r.properties.push_back(pair<string, vector<string> >("raw", vector<string>()));
   assert(is_raw(r));
@@ -100,11 +100,11 @@ index_t space_base(const reagent& x) {
 index_t address(index_t offset, index_t base) {
   if (base == 0) return offset;  // raw
 //?   cout << base << '\n'; //? 2
-  if (value(offset) >= value(Memory[base])) {
+  if (offset >= static_cast<index_t>(Memory[base])) {
     // todo: test
-    raise << "location " << value(offset) << " is out of bounds " << value(Memory[base]) << '\n';
+    raise << "location " << offset << " is out of bounds " << Memory[base] << '\n';
   }
-  return value(base)+1 + value(offset);
+  return base+1 + offset;
 }
 
 :(after "void write_memory(reagent x, vector<long long int> data)")
diff --git a/044space_surround.cc b/044space_surround.cc
index 30d4c3f2..b1e4c5e7 100644
--- a/044space_surround.cc
+++ b/044space_surround.cc
@@ -36,8 +36,8 @@ index_t space_base(const reagent& x, index_t space_index, index_t base) {
 //?     trace("foo") << "base of space " << space_index << " is " << base << '\n'; //? 1
     return base;
   }
-//?   trace("foo") << "base of space " << space_index << " is " << value(Memory[base+1]) << '\n'; //? 1
-  index_t result = space_base(x, space_index-1, value(Memory[base+1]));
+//?   trace("foo") << "base of space " << space_index << " is " << Memory[base+1] << '\n'; //? 1
+  index_t result = space_base(x, space_index-1, Memory[base+1]);
   return result;
 }
 
diff --git a/047jump_label.cc b/047jump_label.cc
index b03d8b73..c9dcb4f5 100644
--- a/047jump_label.cc
+++ b/047jump_label.cc
@@ -52,7 +52,7 @@ void replace_offset(reagent& x, /*const*/ map<string, index_t>& offset, const in
 //?   cerr << "DDD " << x.to_string() << '\n'; //? 1
   if (offset.find(x.name) == offset.end())
     raise << "can't find label " << x.name << " in routine " << Recipe[r].name << '\n';
-  x.set_value(mu_integer(offset[x.name]-current_offset));
+  x.set_value(offset[x.name]-current_offset);
 }
 
 :(scenario break_to_label)
diff --git a/050scenario.cc b/050scenario.cc
index 3aa34089..c5ff2765 100644
--- a/050scenario.cc
+++ b/050scenario.cc
@@ -88,7 +88,7 @@ time_t mu_time; time(&mu_time);
 cerr << "\nMu tests: " << ctime(&mu_time);
 for (index_t i = 0; i < Scenarios.size(); ++i) {
 //?   cerr << Passed << '\n'; //? 1
-//?   cerr << i << ": " << Scenarios.at(i).name << '\n'; //? 3
+//?   cerr << i << ": " << Scenarios.at(i).name << '\n'; //? 2
   run_mu_scenario(Scenarios.at(i));
   if (Passed) cerr << ".";
 }
@@ -215,15 +215,15 @@ void check_memory(const string& s) {
     skip_whitespace_and_comments(in);
     string _assign;  in >> _assign;  assert(_assign == "<-");
     skip_whitespace_and_comments(in);
-    int expected_value = 0;  in >> expected_value;
+    int value = 0;  in >> value;
     if (locations_checked.find(address) != locations_checked.end())
       raise << "duplicate expectation for location " << address << '\n';
     trace("run") << "checking location " << address;
-    if (value(Memory[address]) != expected_value) {
+    if (Memory[address] != value) {
       if (Current_scenario)
-        raise << "\nF - " << Current_scenario->name << ": expected location " << address << " to contain " << expected_value << " but saw " << value(Memory[address]) << '\n';
+        raise << "\nF - " << Current_scenario->name << ": expected location " << address << " to contain " << value << " but saw " << Memory[address] << '\n';
       else
-        raise << "expected location " << address << " to contain " << expected_value << " but saw " << value(Memory[address]) << '\n';
+        raise << "expected location " << address << " to contain " << value << " but saw " << Memory[address] << '\n';
       Passed = false;
       return;
     }
@@ -234,7 +234,7 @@ void check_memory(const string& s) {
 void check_type(const string& lhs, istream& in) {
   reagent x(lhs);
   if (x.properties.at(0).second.at(0) == "string") {
-    x.set_value(mu_integer(to_number(x.name)));  // address must be a positive integer
+    x.set_value(to_number(x.name));
     skip_whitespace_and_comments(in);
     string _assign = next_word(in);
     assert(_assign == "<-");
@@ -252,13 +252,13 @@ void check_type(const string& lhs, istream& in) {
 
 void check_string(index_t address, const string& literal) {
   trace("run") << "checking string length at " << address;
-  if (value(Memory[address]) != static_cast<signed>(literal.size()))
-    raise << "expected location " << address << " to contain length " << literal.size() << " of string [" << literal << "] but saw " << value(Memory[address]) << '\n';
+  if (Memory[address] != static_cast<signed>(literal.size()))
+    raise << "expected location " << address << " to contain length " << literal.size() << " of string [" << literal << "] but saw " << Memory[address] << '\n';
   ++address;  // now skip length
   for (index_t i = 0; i < literal.size(); ++i) {
     trace("run") << "checking location " << address+i;
-    if (value(Memory[address+i]) != literal.at(i))
-      raise << "expected location " << (address+i) << " to contain " << literal.at(i) << " but saw " << value(Memory[address+i]) << '\n';
+    if (Memory[address+i] != literal.at(i))
+      raise << "expected location " << (address+i) << " to contain " << literal.at(i) << " but saw " << Memory[address+i] << '\n';
   }
 }
 
diff --git a/060string.mu b/060string.mu
index c2b4e356..6b38803b 100644
--- a/060string.mu
+++ b/060string.mu
@@ -156,8 +156,6 @@ recipe buffer-append [
   default-space:address:array:location <- new location:type, 30:literal
   in:address:buffer <- next-ingredient
   c:character <- next-ingredient
-#?   $print c:character, [  #? 1
-#? ] #? 1
   {
     # grow buffer if necessary
     full?:boolean <- buffer-full? in:address:buffer
@@ -177,12 +175,8 @@ scenario buffer-append-works [
     default-space:address:array:location <- new location:type, 30:literal
     x:address:buffer <- init-buffer 3:literal
     s1:address:array:character <- get x:address:buffer/deref, data:offset
-#?     $start-tracing #? 1
     x:address:buffer <- buffer-append x:address:buffer, 97:literal  # 'a'
-#?     $exit #? 1
-#?     $start-tracing #? 1
     x:address:buffer <- buffer-append x:address:buffer, 98:literal  # 'b'
-#?     $exit #? 1
     x:address:buffer <- buffer-append x:address:buffer, 99:literal  # 'c'
     s2:address:array:character <- get x:address:buffer/deref, data:offset
     1:boolean/raw <- equal s1:address:array:character, s2:address:array:character
@@ -200,9 +194,7 @@ scenario buffer-append-works [
 #? ]
 #?     $print 1065:integer/raw, [
 #? ]
-#?     $start-tracing #? 1
     2:array:character/raw <- copy s2:address:array:character/deref
-#?     $exit #? 1
     +buffer-filled
     x:address:buffer <- buffer-append x:address:buffer, 100:literal  # 'd'
     s3:address:array:character <- get x:address:buffer/deref, data:offset
@@ -269,8 +261,6 @@ recipe integer-to-decimal-string [
   buf:address:array:character <- get tmp:address:buffer/deref, data:offset
   result:address:array:character <- new character:type, len:integer
   i:integer <- subtract len:integer, 1:literal
-#?   $print len:integer, [ - 1 = ], i:integer, [  #? 1
-#? ] #? 1
   j:integer <- copy 0:literal
   {
     # while i >= 0
@@ -281,11 +271,7 @@ recipe integer-to-decimal-string [
     dest:address:character <- index-address result:address:array:character/deref, j:integer
     dest:address:character/deref <- copy src:character
     # ++i
-#?     $print [aaa: ], i:integer, [  #? 1
-#? ] #? 1
     i:integer <- subtract i:integer, 1:literal
-#?     $print [bbb: ], i:integer, [  #? 1
-#? ] #? 1
     # --j
     j:integer <- add j:integer, 1:literal
     loop
@@ -304,7 +290,6 @@ scenario integer-to-decimal-digit-zero [
 ]
 
 scenario integer-to-decimal-digit-positive [
-#?   $start-tracing #? 1
   run [
     1:address:array:character/raw <- integer-to-decimal-string 234:literal
     2:array:character/raw <- copy 1:address:array:character/deref/raw
@@ -315,7 +300,6 @@ scenario integer-to-decimal-digit-positive [
 ]
 
 scenario integer-to-decimal-digit-negative [
-#?   $start-tracing #? 1
   run [
     1:address:array:character/raw <- integer-to-decimal-string -1:literal
     2:array:character/raw <- copy 1:address:array:character/deref/raw
diff --git a/070display.cc b/070display.cc
index 7c850ef8..8a782f87 100644
--- a/070display.cc
+++ b/070display.cc
@@ -70,7 +70,7 @@ case PRINT_CHARACTER_TO_DISPLAY: {
   size_t height = (h >= 0) ? h : 0;
   size_t width = (w >= 0) ? w : 0;
   assert(ingredients.at(0).size() == 1);  // scalar
-  long long int c = value(ingredients.at(0).at(0));  // unicode code-point will probably always be a positive integer
+  long long int c = ingredients.at(0).at(0);
   if (c == '\n' || c == '\r') {
     if (Display_row < height-1) {
       Display_column = 0;
@@ -117,9 +117,9 @@ Recipe_number["move-cursor-on-display"] = MOVE_CURSOR_ON_DISPLAY;
 :(before "End Primitive Recipe Implementations")
 case MOVE_CURSOR_ON_DISPLAY: {
   assert(ingredients.at(0).size() == 1);  // scalar
-  Display_row = ingredients.at(0).at(0);  // screen coordinate will always be a non-negative integer
+  Display_row = ingredients.at(0).at(0);
   assert(ingredients.at(1).size() == 1);  // scalar
-  Display_column = ingredients.at(1).at(0);  // screen coordinate will always be a non-negative integer
+  Display_column = ingredients.at(1).at(0);
   tb_set_cursor(Display_column, Display_row);
   tb_present();
   break;
diff --git a/071print.mu b/071print.mu
index 487608a2..d6c72b32 100644
--- a/071print.mu
+++ b/071print.mu
@@ -41,7 +41,7 @@ recipe clear-screen [
       done?:boolean <- greater-or-equal i:integer, max:integer
       break-if done?:boolean
       c:address:character <- index-address buf:address:array:character/deref, i:integer
-      c:address:character/deref <- copy [ ]  # hack: can't copy any literal string except a single space
+      c:address:character/deref <- copy [ ]
       i:integer <- add i:integer, 1:literal
       loop
     }
diff --git a/072scenario_screen.cc b/072scenario_screen.cc
index 5d57c199..f75e7fdc 100644
--- a/072scenario_screen.cc
+++ b/072scenario_screen.cc
@@ -6,7 +6,7 @@
 :(scenarios run_mu_scenario)
 :(scenario screen_in_scenario)
 scenario screen-in-scenario [
-#?   $start-tracing #? 3
+#?   $start-tracing
   assume-screen 5:literal/width, 3:literal/height
   run [
     screen:address <- print-character screen:address, 97:literal  # 'a'
@@ -35,7 +35,6 @@ scenario screen-in-scenario-error [
     .     .
   ]
 ]
-# manual test: modifying the trace line below should cause a failure
 +warn: expected screen location (0, 0) to contain 'b' instead of 'a'
 
 :(before "End Globals")
@@ -67,7 +66,7 @@ if (curr.name == "assume-screen") {
   curr.operation = Recipe_number["init-fake-screen"];
   assert(curr.products.empty());
   curr.products.push_back(reagent("screen:address"));
-  curr.products.at(0).set_value(mu_integer(SCREEN));  // address must be a positive integer
+  curr.products.at(0).set_value(SCREEN);
 //? cout << "after: " << curr.to_string() << '\n'; //? 1
 //? cout << "AAA " << Recipe_number["init-fake-screen"] << '\n'; //? 1
 }
@@ -87,15 +86,15 @@ case SCREEN_SHOULD_CONTAIN: {
 :(code)
 void check_screen(const string& contents) {
   assert(!Current_routine->calls.top().default_space);  // not supported
-  index_t screen_location = value(Memory[SCREEN]);
+  index_t screen_location = Memory[SCREEN];
   int data_offset = find_element_name(Type_number["screen"], "data");
   assert(data_offset >= 0);
   index_t screen_data_location = screen_location+data_offset;  // type: address:array:character
-  index_t screen_data_start = value(Memory[screen_data_location]);  // type: array:character
+  index_t screen_data_start = Memory[screen_data_location];  // type: array:character
   int width_offset = find_element_name(Type_number["screen"], "num-columns");
-  size_t screen_width = value(Memory[screen_location+width_offset]);
+  size_t screen_width = Memory[screen_location+width_offset];
   int height_offset = find_element_name(Type_number["screen"], "num-rows");
-  size_t screen_height = value(Memory[screen_location+height_offset]);
+  size_t screen_height = Memory[screen_location+height_offset];
   string expected_contents;
   istringstream in(contents);
   in >> std::noskipws;
@@ -113,21 +112,19 @@ void check_screen(const string& contents) {
 //?   assert(in.get() == ']');
   trace("run") << "checking screen size at " << screen_data_start;
 //?   cout << expected_contents.size() << '\n'; //? 1
-  if (value(Memory[screen_data_start]) > static_cast<signed>(expected_contents.size()))
-    raise << "expected contents are larger than screen size " << value(Memory[screen_data_start]) << '\n';
+  if (Memory[screen_data_start] > static_cast<signed>(expected_contents.size()))
+    raise << "expected contents are larger than screen size " << Memory[screen_data_start] << '\n';
   ++screen_data_start;  // now skip length
   for (index_t i = 0; i < expected_contents.size(); ++i) {
     trace("run") << "checking location " << screen_data_start+i;
-//?     cerr << "comparing " << i/screen_width << ", " << i%screen_width << ": " << value(Memory[screen_data_start+i]) << " vs " << (int)expected_contents.at(i) << '\n'; //? 1
-    long long int curr = value(Memory[screen_data_start+i]);
-//?     cerr << curr << " <= " << expected_contents.at(i) << '\n'; //? 1
-    if ((!curr && !isspace(expected_contents.at(i)))  // uninitialized memory => spaces
-        || (curr && value(Memory[screen_data_start+i]) != expected_contents.at(i))) {
+//?     cerr << "comparing " << i/screen_width << ", " << i%screen_width << ": " << Memory[screen_data_start+i] << " vs " << (int)expected_contents.at(i) << '\n'; //? 1
+    if ((!Memory[screen_data_start+i] && !isspace(expected_contents.at(i)))  // uninitialized memory => spaces
+        || (Memory[screen_data_start+i] && Memory[screen_data_start+i] != expected_contents.at(i))) {
 //?       cerr << "CCC " << Trace_stream << " " << Hide_warnings << '\n'; //? 1
       if (Current_scenario && !Hide_warnings)  // Hide_warnings indicates we're checking for the warning at the C++ level rather than raising a test failure at the mu level
-        raise << "\nF - " << Current_scenario->name << ": expected screen location (" << i/screen_width << ", " << i%screen_width << ") to contain '" << expected_contents.at(i) << "' instead of '" << static_cast<char>(value(Memory[screen_data_start+i])) << "'\n";
+        raise << "\nF - " << Current_scenario->name << ": expected screen location (" << i/screen_width << ", " << i%screen_width << ") to contain '" << expected_contents.at(i) << "' instead of '" << static_cast<char>(Memory[screen_data_start+i]) << "'\n";
       else
-        raise << "expected screen location (" << i/screen_width << ", " << i%screen_width << ") to contain '" << expected_contents.at(i) << "' instead of '" << static_cast<char>(value(Memory[screen_data_start+i])) << "'\n";
+        raise << "expected screen location (" << i/screen_width << ", " << i%screen_width << ") to contain '" << expected_contents.at(i) << "' instead of '" << static_cast<char>(Memory[screen_data_start+i]) << "'\n";
       Passed = false;
       return;
     }
diff --git a/075scenario_keyboard.cc b/075scenario_keyboard.cc
index 3d816c2a..0de6a2eb 100644
--- a/075scenario_keyboard.cc
+++ b/075scenario_keyboard.cc
@@ -41,15 +41,15 @@ if (curr.name == "assume-keyboard") {
   curr.operation = Recipe_number["new"];
   assert(curr.products.empty());
   curr.products.push_back(reagent("keyboard:address"));
-  curr.products.at(0).set_value(mu_integer(KEYBOARD));  // address must be a positive integer
+  curr.products.at(0).set_value(KEYBOARD);
   result.steps.push_back(curr);  // hacky that "Rewrite Instruction" is converting to multiple instructions
   // leave second instruction in curr
   curr.clear();
   curr.operation = Recipe_number["init-fake-keyboard"];
   assert(curr.ingredients.empty());
   curr.ingredients.push_back(reagent("keyboard:address"));
-  curr.ingredients.at(0).set_value(mu_integer(KEYBOARD));  // address must be a positive integer
+  curr.ingredients.at(0).set_value(KEYBOARD);
   assert(curr.products.empty());
   curr.products.push_back(reagent("keyboard:address"));
-  curr.products.at(0).set_value(mu_integer(KEYBOARD));  // address must be a positive integer
+  curr.products.at(0).set_value(KEYBOARD);
 }