about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--001help.cc36
-rw-r--r--002test.cc6
-rw-r--r--003trace.cc50
-rw-r--r--010vm.cc28
-rw-r--r--011load.cc8
-rw-r--r--012transform.cc10
-rw-r--r--013literal_string.cc2
-rw-r--r--014literal_noninteger.cc4
-rw-r--r--020run.cc32
-rw-r--r--021arithmetic.cc28
-rw-r--r--022boolean.cc12
-rw-r--r--023jump.cc16
-rw-r--r--024compare.cc26
-rw-r--r--026assert.cc4
-rw-r--r--027debug.cc4
-rw-r--r--030container.cc32
-rw-r--r--031address.cc12
-rw-r--r--032array.cc16
-rw-r--r--034exclusive_container.cc20
-rw-r--r--035call.cc8
-rw-r--r--036call_ingredient.cc16
-rw-r--r--037call_reply.cc8
-rw-r--r--038scheduler.cc52
-rw-r--r--039wait.cc20
-rw-r--r--040brace.cc16
-rw-r--r--041name.cc34
-rw-r--r--042new.cc28
-rw-r--r--043space.cc10
-rw-r--r--044space_surround.cc14
-rw-r--r--045closure_name.cc28
-rw-r--r--046tangle.cc4
-rw-r--r--047jump_label.cc12
-rw-r--r--048continuation.cc8
-rw-r--r--050scenario.cc28
-rw-r--r--070display.cc20
-rw-r--r--072scenario_screen.cc42
-rw-r--r--075scenario_keyboard.cc2
37 files changed, 365 insertions, 331 deletions
diff --git a/001help.cc b/001help.cc
index de81fbcc..25150f92 100644
--- a/001help.cc
+++ b/001help.cc
@@ -29,6 +29,37 @@ bool is_equal(char* s, const char* lit) {
   return strncmp(s, lit, strlen(lit)) == 0;
 }
 
+// I'll throw some style conventions here for want of a better place for them.
+// As a rule I hate style guides. Do what you want, that's my motto. But since
+// we're dealing with C/C++, the one big thing we want to avoid is undefined
+// behavior. So, conventions:
+
+// 0. Initialize all primitive variables in methods and constructors.
+
+// 1. Avoid 'new' and 'delete' as far as possible. Rely on STL to perform
+// memory management to avoid use-after-free issues (and memory leaks).
+
+// 2. Avoid arrays to avoid out-of-bounds access. Never use operator[] except
+// with map. Use at() with STL vectors and so on.
+
+// 3. Valgrind all the things.
+
+// 4. Avoid unsigned numbers. Not strictly an undefined-behavior issue, but
+// the extra range doesn't matter, and it's one less confusing category of
+// interaction gotchas to worry about.
+//
+// We're screwed on overflow (undefined behavior). Use a decent compiler. But
+// we're more likely to try to subtract unsigned 2 from 1 than we are to
+// create integers that don't fit in 64 bits.
+//
+// Corollary: don't use the size() method on containers, since it returns an
+// unsigned and that'll cause warnings about mixing signed and unsigned,
+// yadda-yadda. Instead use this macro below to perform an unsafe cast to
+// signed. (Implementation-defined behavior, so not as bad as undefined;
+// should cause immediate failures on overflow by failing to enter loops.)
+:(before "End Includes")
+#define SIZE(X) static_cast<long long int>(X.size())
+
 :(before "End Includes")
 #include<assert.h>
 
@@ -43,8 +74,3 @@ using std::cerr;
 #include<cstring>
 #include<string>
 using std::string;
-typedef size_t index_t;
-const index_t NOT_FOUND = string::npos;
-:(after "int main(int argc, char* argv[])")
-assert(sizeof(string::size_type) == sizeof(size_t));
-assert(sizeof(index_t) == sizeof(size_t));
diff --git a/002test.cc b/002test.cc
index 81bcba6d..76bf02cf 100644
--- a/002test.cc
+++ b/002test.cc
@@ -53,7 +53,7 @@ if (Run_tests) {
   // End Test Run Initialization
   time_t t; time(&t);
   cerr << "C tests: " << ctime(&t);
-  for (index_t i=0; i < sizeof(Tests)/sizeof(Tests[0]); ++i) {
+  for (size_t i=0; i < sizeof(Tests)/sizeof(Tests[0]); ++i) {
     run_test(i);
   }
   // End Tests
@@ -68,7 +68,7 @@ if (Run_tests) {
 }
 
 :(code)
-void run_test(index_t i) {
+void run_test(size_t i) {
   if (i >= sizeof(Tests)/sizeof(Tests[0])) {
     cerr << "no test " << i << '\n';
     return;
@@ -81,7 +81,7 @@ void run_test(index_t i) {
 }
 
 bool is_integer(const string& s) {
-  return s.find_first_not_of("0123456789-") == NOT_FOUND;
+  return s.find_first_not_of("0123456789-") == string::npos;
 }
 
 long long int to_integer(string n) {
diff --git a/003trace.cc b/003trace.cc
index 6fb6dfa7..cdef3c0f 100644
--- a/003trace.cc
+++ b/003trace.cc
@@ -215,10 +215,10 @@ void trace_all(const string& label, const list<string>& in) {
 
 bool check_trace_contents(string FUNCTION, string FILE, int LINE, string expected) {  // missing layer == anywhere, frame, hierarchical layers
   vector<string> expected_lines = split(expected, "");
-  index_t curr_expected_line = 0;
-  while (curr_expected_line < expected_lines.size() && expected_lines.at(curr_expected_line).empty())
+  long long int curr_expected_line = 0;
+  while (curr_expected_line < SIZE(expected_lines) && expected_lines.at(curr_expected_line).empty())
     ++curr_expected_line;
-  if (curr_expected_line == expected_lines.size()) return true;
+  if (curr_expected_line == SIZE(expected_lines)) return true;
   Trace_stream->newline();
   string layer, frame, contents;
   parse_layer_frame_contents(expected_lines.at(curr_expected_line), &layer, &frame, &contents);
@@ -233,9 +233,9 @@ bool check_trace_contents(string FUNCTION, string FILE, int LINE, string expecte
       continue;
 
     ++curr_expected_line;
-    while (curr_expected_line < expected_lines.size() && expected_lines.at(curr_expected_line).empty())
+    while (curr_expected_line < SIZE(expected_lines) && expected_lines.at(curr_expected_line).empty())
       ++curr_expected_line;
-    if (curr_expected_line == expected_lines.size()) return true;
+    if (curr_expected_line == SIZE(expected_lines)) return true;
     parse_layer_frame_contents(expected_lines.at(curr_expected_line), &layer, &frame, &contents);
   }
 
@@ -253,20 +253,20 @@ void parse_layer_frame_contents(const string& orig, string* layer, string* frame
 }
 
 void parse_contents(const string& s, const string& delim, string* prefix, string* contents) {
-  index_t pos = s.find(delim);
-  if (pos == NOT_FOUND) {
+  size_t pos = s.find(delim);
+  if (pos == string::npos) {
     *prefix = "";
     *contents = s;
   }
   else {
     *prefix = s.substr(0, pos);
-    *contents = s.substr(pos+delim.size());
+    *contents = s.substr(pos+SIZE(delim));
   }
 }
 
 void parse_layer_and_frame(const string& orig, string* layer, string* frame) {
-  index_t last_slash = orig.rfind('/');
-  if (last_slash == NOT_FOUND
+  size_t last_slash = orig.rfind('/');
+  if (last_slash == string::npos
       || orig.find_last_not_of("0123456789") != last_slash) {
     *layer = orig;
     *frame = "";
@@ -281,10 +281,10 @@ void parse_layer_and_frame(const string& orig, string* layer, string* frame) {
 
 bool check_trace_contents(string FUNCTION, string FILE, int LINE, string layer, string expected) {  // empty layer == everything, multiple layers, hierarchical layers
   vector<string> expected_lines = split(expected, "");
-  index_t curr_expected_line = 0;
-  while (curr_expected_line < expected_lines.size() && expected_lines.at(curr_expected_line).empty())
+  long long int curr_expected_line = 0;
+  while (curr_expected_line < SIZE(expected_lines) && expected_lines.at(curr_expected_line).empty())
     ++curr_expected_line;
-  if (curr_expected_line == expected_lines.size()) return true;
+  if (curr_expected_line == SIZE(expected_lines)) return true;
   Trace_stream->newline();
   vector<string> layers = split(layer, ",");
   for (vector<pair<string, pair<int, string> > >::iterator p = Trace_stream->past_lines.begin(); p != Trace_stream->past_lines.end(); ++p) {
@@ -293,9 +293,9 @@ bool check_trace_contents(string FUNCTION, string FILE, int LINE, string layer,
     if (p->second.second != expected_lines.at(curr_expected_line))
       continue;
     ++curr_expected_line;
-    while (curr_expected_line < expected_lines.size() && expected_lines.at(curr_expected_line).empty())
+    while (curr_expected_line < SIZE(expected_lines) && expected_lines.at(curr_expected_line).empty())
       ++curr_expected_line;
-    if (curr_expected_line == expected_lines.size()) return true;
+    if (curr_expected_line == SIZE(expected_lines)) return true;
   }
 
   ++Num_failures;
@@ -380,10 +380,10 @@ struct lease_trace_frame {
 
 bool check_trace_contents(string FUNCTION, string FILE, int LINE, string layer, int frame, string expected) {  // multiple layers, hierarchical layers
   vector<string> expected_lines = split(expected, "");  // hack: doesn't handle newlines in embedded in lines
-  index_t curr_expected_line = 0;
-  while (curr_expected_line < expected_lines.size() && expected_lines.at(curr_expected_line).empty())
+  long long int curr_expected_line = 0;
+  while (curr_expected_line < SIZE(expected_lines) && expected_lines.at(curr_expected_line).empty())
     ++curr_expected_line;
-  if (curr_expected_line == expected_lines.size()) return true;
+  if (curr_expected_line == SIZE(expected_lines)) return true;
   Trace_stream->newline();
   vector<string> layers = split(layer, ",");
   for (vector<pair<string, pair<int, string> > >::iterator p = Trace_stream->past_lines.begin(); p != Trace_stream->past_lines.end(); ++p) {
@@ -394,9 +394,9 @@ bool check_trace_contents(string FUNCTION, string FILE, int LINE, string layer,
     if (p->second.second != expected_lines.at(curr_expected_line))
       continue;
     ++curr_expected_line;
-    while (curr_expected_line < expected_lines.size() && expected_lines.at(curr_expected_line).empty())
+    while (curr_expected_line < SIZE(expected_lines) && expected_lines.at(curr_expected_line).empty())
       ++curr_expected_line;
-    if (curr_expected_line == expected_lines.size()) return true;
+    if (curr_expected_line == SIZE(expected_lines)) return true;
   }
 
   ++Num_failures;
@@ -412,14 +412,14 @@ bool check_trace_contents(string FUNCTION, string FILE, int LINE, string layer,
 
 vector<string> split(string s, string delim) {
   vector<string> result;
-  index_t begin=0, end=s.find(delim);
+  size_t begin=0, end=s.find(delim);
   while (true) {
-    if (end == NOT_FOUND) {
-      result.push_back(string(s, begin, NOT_FOUND));
+    if (end == string::npos) {
+      result.push_back(string(s, begin, string::npos));
       break;
     }
     result.push_back(string(s, begin, end-begin));
-    begin = end+delim.size();
+    begin = SIZE(end+delim);
     end = s.find(delim, begin);
   }
   return result;
@@ -444,7 +444,7 @@ bool prefix_match(const string& pat, const string& needle) {
 }
 
 bool headmatch(const string& s, const string& pat) {
-  if (pat.size() > s.size()) return false;
+  if (SIZE(pat) > SIZE(s)) return false;
   return std::mismatch(pat.begin(), pat.end(), s.begin()).first == pat.end();
 }
 
diff --git a/010vm.cc b/010vm.cc
index 6b94e4a3..3399a539 100644
--- a/010vm.cc
+++ b/010vm.cc
@@ -1,6 +1,6 @@
 :(after "Types")
 // A program is a book of 'recipes' (functions)
-typedef size_t recipe_number;
+typedef long long int recipe_number;
 :(before "End Globals")
 map<string, recipe_number> Recipe_number;
 map<recipe_number, recipe> Recipe;
@@ -57,7 +57,7 @@ struct property {
 
 :(before "End Globals")
 // Locations refer to a common 'memory'. Each location can store a number.
-map<index_t, double> Memory;
+map<long long int, double> Memory;
 :(before "End Setup")
 Memory.clear();
 
@@ -70,7 +70,7 @@ Memory.clear();
 // Unlike most computers today, mu stores types in a single big table, shared
 // by all the mu programs on the computer. This is useful in providing a
 // seamless experience to help understand arbitrary mu programs.
-typedef size_t type_number;
+typedef long long int type_number;
 :(before "End Globals")
 map<string, type_number> Type_number;
 map<type_number, type_info> Type;
@@ -119,7 +119,7 @@ enum kind_of_type {
 struct type_info {
   string name;
   kind_of_type kind;
-  size_t size;  // only if type is not primitive; primitives and addresses have size 1 (except arrays are dynamic)
+  long long int size;  // only if type is not primitive; primitives and addresses have size 1 (except arrays are dynamic)
   vector<vector<type_number> > elements;
   vector<string> element_names;
   // End type_info Fields
@@ -182,7 +182,7 @@ reagent::reagent(string s) :value(0), initialized(false) {
   }
   // structures for the first row of properties
   name = properties.at(0).first;
-  for (index_t i = 0; i < properties.at(0).second.size(); ++i) {
+  for (long long int i = 0; i < SIZE(properties.at(0).second); ++i) {
     string type = properties.at(0).second.at(i);
     if (Type_number.find(type) == Type_number.end())
       raise << "unknown type: " << type << '\n';
@@ -202,19 +202,19 @@ reagent::reagent() :value(0), initialized(false) {
 string reagent::to_string() const {
   ostringstream out;
   out << "{name: \"" << name << "\", value: " << value << ", type: ";
-  for (index_t i = 0; i < types.size(); ++i) {
+  for (long long int i = 0; i < SIZE(types); ++i) {
+    if (i > 0) out << '-';
     out << types.at(i);
-    if (i < types.size()-1) out << "-";
   }
   if (!properties.empty()) {
     out << ", properties: [";
-    for (index_t i = 0; i < properties.size(); ++i) {
+    for (long long int i = 0; i < SIZE(properties); ++i) {
       out << "\"" << properties.at(i).first << "\": ";
-      for (index_t j = 0; j < properties.at(i).second.size(); ++j) {
+      for (long long int j = 0; j < SIZE(properties.at(i).second); ++j) {
+        if (j > 0) out << ':';
         out << "\"" << properties.at(i).second.at(j) << "\"";
-        if (j < properties.at(i).second.size()-1) out << ":";
       }
-      if (i < properties.size()-1) out << ", ";
+      if (i < SIZE(properties)-1) out << ", ";
       else out << "]";
     }
   }
@@ -225,13 +225,13 @@ string reagent::to_string() const {
 string instruction::to_string() const {
   if (is_label) return label;
   ostringstream out;
-  for (index_t i = 0; i < products.size(); ++i) {
+  for (long long int i = 0; i < SIZE(products); ++i) {
     if (i > 0) out << ", ";
     out << products.at(i).to_string();
   }
   if (!products.empty()) out << " <- ";
   out << name << '/' << operation << ' ';
-  for (index_t i = 0; i < ingredients.size(); ++i) {
+  for (long long int i = 0; i < SIZE(ingredients); ++i) {
     if (i > 0) out << ", ";
     out << ingredients.at(i).to_string();
   }
@@ -252,7 +252,7 @@ string slurp_until(istream& in, char delim) {
 }
 
 void dump_memory() {
-  for (map<index_t, double>::iterator p = Memory.begin(); p != Memory.end(); ++p) {
+  for (map<long long int, double>::iterator p = Memory.begin(); p != Memory.end(); ++p) {
     cout << p->first << ": " << p->second << '\n';
   }
 }
diff --git a/011load.cc b/011load.cc
index 9644eda3..662089e2 100644
--- a/011load.cc
+++ b/011load.cc
@@ -82,13 +82,13 @@ bool next_instruction(istream& in, instruction* curr) {
   }
   skip_whitespace_and_comments(in);  if (in.eof()) return false;
 
-//?   if (words.size() == 1) cout << words.at(0) << ' ' << words.at(0).size() << '\n'; //? 1
-  if (words.size() == 1 && words.at(0) == "]") {
+//?   if (SIZE(words) == 1) cout << words.at(0) << ' ' << SIZE(words.at(0)) << '\n'; //? 1
+  if (SIZE(words) == 1 && words.at(0) == "]") {
 //?     cout << "AAA\n"; //? 1
     return false;  // end of recipe
   }
 
-  if (words.size() == 1 && !isalnum(words.at(0).at(0)) && words.at(0).at(0) != '$') {
+  if (SIZE(words) == 1 && !isalnum(words.at(0).at(0)) && words.at(0).at(0) != '$') {
     curr->is_label = true;
     curr->label = words.at(0);
     trace("parse") << "label: " << curr->label;
@@ -203,7 +203,7 @@ void show_rest_of_stream(istream& in) {
 :(before "End Globals")
 vector<recipe_number> recently_added_recipes;
 :(before "End Setup")
-for (index_t i = 0; i < recently_added_recipes.size(); ++i) {
+for (long long int i = 0; i < SIZE(recently_added_recipes); ++i) {
 //?   cout << "AAA clearing " << Recipe[recently_added_recipes.at(i)].name << '\n'; //? 2
   Recipe_number.erase(Recipe[recently_added_recipes.at(i)].name);
   Recipe.erase(recently_added_recipes.at(i));
diff --git a/012transform.cc b/012transform.cc
index c7d9b313..731156a9 100644
--- a/012transform.cc
+++ b/012transform.cc
@@ -4,7 +4,7 @@
 //: deconstructed alternative to conventional compilers.
 
 :(before "End recipe Fields")
-index_t transformed_until;
+long long int transformed_until;
   recipe() :transformed_until(-1) {}
 
 :(before "End Types")
@@ -16,7 +16,7 @@ vector<transform_fn> Transform;
 :(code)
 void transform_all() {
 //?   cout << "AAA transform_all\n"; //? 1
-  for (index_t t = 0; t < Transform.size(); ++t) {
+  for (long long int t = 0; t < SIZE(Transform); ++t) {
     for (map<recipe_number, recipe>::iterator p = Recipe.begin(); p != Recipe.end(); ++p) {
       recipe& r = p->second;
       if (r.steps.empty()) continue;
@@ -33,12 +33,12 @@ void parse_int_reagents() {
   for (map<recipe_number, recipe>::iterator p = Recipe.begin(); p != Recipe.end(); ++p) {
     recipe& r = p->second;
     if (r.steps.empty()) continue;
-    for (index_t index = 0; index < r.steps.size(); ++index) {
+    for (long long int index = 0; index < SIZE(r.steps); ++index) {
       instruction& inst = r.steps.at(index);
-      for (index_t i = 0; i < inst.ingredients.size(); ++i) {
+      for (long long int i = 0; i < SIZE(inst.ingredients); ++i) {
         populate_value(inst.ingredients.at(i));
       }
-      for (index_t i = 0; i < inst.products.size(); ++i) {
+      for (long long int i = 0; i < SIZE(inst.products); ++i) {
         populate_value(inst.products.at(i));
       }
     }
diff --git a/013literal_string.cc b/013literal_string.cc
index 9e492fbb..44a94db2 100644
--- a/013literal_string.cc
+++ b/013literal_string.cc
@@ -53,7 +53,7 @@ string slurp_quoted(istream& in) {
     assert(*s.rbegin() == ']');
     // delete [] delimiters
     s.erase(0, 1);
-    s.erase(s.size()-1, s.size());
+    s.erase(SIZE(s)-1, SIZE(s));
     name = s;
     types.push_back(0);
     properties.push_back(pair<string, vector<string> >(name, vector<string>()));
diff --git a/014literal_noninteger.cc b/014literal_noninteger.cc
index 94242f41..a5e9cd12 100644
--- a/014literal_noninteger.cc
+++ b/014literal_noninteger.cc
@@ -20,8 +20,8 @@ recipe main [
 
 :(code)
 bool is_noninteger(const string& s) {
-  return s.find_first_not_of("0123456789-.") == NOT_FOUND
-      && s.find('.') != NOT_FOUND;
+  return s.find_first_not_of("0123456789-.") == string::npos
+      && s.find('.') != string::npos;
 }
 
 double to_double(string n) {
diff --git a/020run.cc b/020run.cc
index 32981fa6..f0acfb86 100644
--- a/020run.cc
+++ b/020run.cc
@@ -41,7 +41,7 @@ recipe main [
 //: Later layers will change this.
 struct routine {
   recipe_number running_recipe;
-  index_t running_step_index;
+  long long int running_step_index;
   routine(recipe_number r) :running_recipe(r), running_step_index(0) {}
   bool completed() const;
 };
@@ -69,13 +69,13 @@ void run_current_routine()
     // Each ingredient loads a vector of values rather than a single value; mu
     // permits operating on reagents spanning multiple locations.
     vector<vector<double> > ingredients;
-    for (index_t i = 0; i < current_instruction().ingredients.size(); ++i) {
+    for (long long int i = 0; i < SIZE(current_instruction().ingredients); ++i) {
       trace("run") << "ingredient " << i << " is " << current_instruction().ingredients.at(i).name;
       ingredients.push_back(read_memory(current_instruction().ingredients.at(i)));
     }
     // Instructions below will write to 'products' or to 'instruction_counter'.
     vector<vector<double> > products;
-    index_t instruction_counter = current_step_index();
+    long long int instruction_counter = current_step_index();
 //?     cout << "AAA: " << current_instruction().to_string() << '\n'; //? 1
     switch (current_instruction().operation) {
       // Primitive Recipe Implementations
@@ -89,10 +89,10 @@ void run_current_routine()
       }
     }
 //?     cout << "BBB: " << current_instruction().to_string() << '\n'; //? 1
-    if (products.size() < current_instruction().products.size())
+    if (SIZE(products) < SIZE(current_instruction().products))
       raise << "failed to write to all products! " << current_instruction().to_string();
 //?     cout << "CCC: " << current_instruction().to_string() << '\n'; //? 1
-    for (index_t i = 0; i < current_instruction().products.size(); ++i) {
+    for (long long int i = 0; i < SIZE(current_instruction().products); ++i) {
       trace("run") << "product " << i << " is " << current_instruction().products.at(i).name;
       write_memory(current_instruction().products.at(i), products.at(i));
     }
@@ -107,7 +107,7 @@ void run_current_routine()
 //: We'll need to override these later as we change the definition of routine.
 //: Important that they return referrences into the routine.
 
-inline index_t& current_step_index() {
+inline long long int& current_step_index() {
   return Current_routine->running_step_index;
 }
 
@@ -120,7 +120,7 @@ inline const instruction& current_instruction() {
 }
 
 inline bool routine::completed() const {
-  return running_step_index >= Recipe[running_recipe].steps.size();
+  return running_step_index >= SIZE(Recipe[running_recipe].steps);
 }
 
 :(before "End Commandline Parsing")
@@ -186,9 +186,9 @@ vector<double> read_memory(reagent x) {
     result.push_back(x.value);
     return result;
   }
-  index_t base = x.value;
-  size_t size = size_of(x);
-  for (index_t offset = 0; offset < size; ++offset) {
+  long long int base = x.value;
+  long long int size = size_of(x);
+  for (long long int offset = 0; offset < size; ++offset) {
     double val = Memory[base+offset];
     trace("mem") << "location " << base+offset << " is " << val;
     result.push_back(val);
@@ -198,20 +198,20 @@ vector<double> read_memory(reagent x) {
 
 void write_memory(reagent x, vector<double> data) {
   if (is_dummy(x)) return;
-  index_t base = x.value;
-  if (size_of(x) != data.size())
+  long long int base = x.value;
+  if (size_of(x) != SIZE(data))
     raise << "size mismatch in storing to " << x.to_string() << '\n';
-  for (index_t offset = 0; offset < data.size(); ++offset) {
+  for (long long int offset = 0; offset < SIZE(data); ++offset) {
     trace("mem") << "storing " << data.at(offset) << " in location " << base+offset;
     Memory[base+offset] = data.at(offset);
   }
 }
 
 :(code)
-size_t size_of(const reagent& r) {
+long long int size_of(const reagent& r) {
   return size_of(r.types);
 }
-size_t size_of(const vector<type_number>& types) {
+long long int size_of(const vector<type_number>& types) {
   // End size_of(types) Cases
   return 1;
 }
@@ -221,7 +221,7 @@ bool is_dummy(const reagent& x) {
 }
 
 bool isa_literal(const reagent& r) {
-  return r.types.size() == 1 && r.types.at(0) == 0;
+  return SIZE(r.types) == 1 && r.types.at(0) == 0;
 }
 
 :(scenario run_label)
diff --git a/021arithmetic.cc b/021arithmetic.cc
index 2bb330a4..667fa541 100644
--- a/021arithmetic.cc
+++ b/021arithmetic.cc
@@ -7,8 +7,8 @@ Recipe_number["add"] = ADD;
 :(before "End Primitive Recipe Implementations")
 case ADD: {
   double result = 0;
-  for (index_t i = 0; i < ingredients.size(); ++i) {
-    assert(ingredients.at(i).size() == 1);  // scalar
+  for (long long int i = 0; i < SIZE(ingredients); ++i) {
+    assert(scalar(ingredients.at(i)));
     result += ingredients.at(i).at(0);
   }
   products.resize(1);
@@ -52,10 +52,10 @@ SUBTRACT,
 Recipe_number["subtract"] = SUBTRACT;
 :(before "End Primitive Recipe Implementations")
 case SUBTRACT: {
-  assert(ingredients.at(0).size() == 1);  // scalar
+  assert(scalar(ingredients.at(0)));
   double result = ingredients.at(0).at(0);
-  for (index_t i = 1; i < ingredients.size(); ++i) {
-    assert(ingredients.at(i).size() == 1);  // scalar
+  for (long long int i = 1; i < SIZE(ingredients); ++i) {
+    assert(scalar(ingredients.at(i)));
     result -= ingredients.at(i).at(0);
   }
   products.resize(1);
@@ -100,8 +100,8 @@ Recipe_number["multiply"] = MULTIPLY;
 :(before "End Primitive Recipe Implementations")
 case MULTIPLY: {
   double result = 1;
-  for (index_t i = 0; i < ingredients.size(); ++i) {
-    assert(ingredients.at(i).size() == 1);  // scalar
+  for (long long int i = 0; i < SIZE(ingredients); ++i) {
+    assert(scalar(ingredients.at(i)));
     result *= ingredients.at(i).at(0);
   }
   products.resize(1);
@@ -145,10 +145,10 @@ DIVIDE,
 Recipe_number["divide"] = DIVIDE;
 :(before "End Primitive Recipe Implementations")
 case DIVIDE: {
-  assert(ingredients.at(0).size() == 1);  // scalar
+  assert(scalar(ingredients.at(0)));
   double result = ingredients.at(0).at(0);
-  for (index_t i = 1; i < ingredients.size(); ++i) {
-    assert(ingredients.at(i).size() == 1);  // scalar
+  for (long long int i = 1; i < SIZE(ingredients); ++i) {
+    assert(scalar(ingredients.at(i)));
     result /= ingredients.at(i).at(0);
   }
   products.resize(1);
@@ -237,3 +237,11 @@ recipe main [
   1:number <- divide 5:literal, 2:literal
 ]
 +mem: storing 2.5 in location 1
+
+:(code)
+inline bool scalar(vector<long long int>& x) {
+  return SIZE(x) == 1;
+}
+inline bool scalar(vector<double>& x) {
+  return SIZE(x) == 1;
+}
diff --git a/022boolean.cc b/022boolean.cc
index 9334ed6a..20571734 100644
--- a/022boolean.cc
+++ b/022boolean.cc
@@ -7,8 +7,8 @@ Recipe_number["and"] = AND;
 :(before "End Primitive Recipe Implementations")
 case AND: {
   bool result = true;
-  for (index_t i = 0; i < ingredients.size(); ++i) {
-    assert(ingredients.at(i).size() == 1);  // scalar
+  for (long long int i = 0; i < SIZE(ingredients); ++i) {
+    assert(scalar(ingredients.at(i)));
     result = result && ingredients.at(i).at(0);
   }
   products.resize(1);
@@ -55,8 +55,8 @@ Recipe_number["or"] = OR;
 :(before "End Primitive Recipe Implementations")
 case OR: {
   bool result = false;
-  for (index_t i = 0; i < ingredients.size(); ++i) {
-    assert(ingredients.at(i).size() == 1);  // scalar
+  for (long long int i = 0; i < SIZE(ingredients); ++i) {
+    assert(scalar(ingredients.at(i)));
     result = result || ingredients.at(i).at(0);
   }
   products.resize(1);
@@ -103,8 +103,8 @@ Recipe_number["not"] = NOT;
 :(before "End Primitive Recipe Implementations")
 case NOT: {
   products.resize(ingredients.size());
-  for (index_t i = 0; i < ingredients.size(); ++i) {
-    assert(ingredients.at(i).size() == 1);  // scalar
+  for (long long int i = 0; i < SIZE(ingredients); ++i) {
+    assert(scalar(ingredients.at(i)));
     products.at(i).push_back(!ingredients.at(i).at(0));
   }
   break;
diff --git a/023jump.cc b/023jump.cc
index b847a66c..e0312269 100644
--- a/023jump.cc
+++ b/023jump.cc
@@ -17,8 +17,8 @@ Recipe_number["jump"] = JUMP;
 :(before "End Primitive Recipe Implementations")
 case JUMP: {
   assert(current_instruction().ingredients.at(0).initialized);
-  assert(ingredients.size() == 1);
-  assert(ingredients.at(0).size() == 1);  // scalar
+  assert(SIZE(ingredients) == 1);
+  assert(scalar(ingredients.at(0)));
   instruction_counter += ingredients.at(0).at(0);
   trace("run") << "jumping to instruction " << instruction_counter+1;
   break;
@@ -46,13 +46,13 @@ Recipe_number["jump-if"] = JUMP_IF;
 :(before "End Primitive Recipe Implementations")
 case JUMP_IF: {
   assert(current_instruction().ingredients.at(1).initialized);
-  assert(ingredients.size() == 2);
-  assert(ingredients.at(0).size() == 1);  // scalar
+  assert(SIZE(ingredients) == 2);
+  assert(scalar(ingredients.at(0)));
   if (!ingredients.at(0).at(0)) {
     trace("run") << "jump-if fell through";
     break;
   }
-  assert(ingredients.at(1).size() == 1);  // scalar
+  assert(scalar(ingredients.at(1)));
   instruction_counter += ingredients.at(1).at(0);
   trace("run") << "jumping to instruction " << instruction_counter+1;
   break;
@@ -86,13 +86,13 @@ Recipe_number["jump-unless"] = JUMP_UNLESS;
 :(before "End Primitive Recipe Implementations")
 case JUMP_UNLESS: {
   assert(current_instruction().ingredients.at(1).initialized);
-  assert(ingredients.size() == 2);
-  assert(ingredients.at(0).size() == 1);  // scalar
+  assert(SIZE(ingredients) == 2);
+  assert(scalar(ingredients.at(0)));
   if (ingredients.at(0).at(0)) {
     trace("run") << "jump-unless fell through";
     break;
   }
-  assert(ingredients.at(1).size() == 1);  // scalar
+  assert(scalar(ingredients.at(1)));
   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 13732980..d840b2ba 100644
--- a/024compare.cc
+++ b/024compare.cc
@@ -8,7 +8,7 @@ Recipe_number["equal"] = EQUAL;
 case EQUAL: {
   vector<double>& exemplar = ingredients.at(0);
   bool result = true;
-  for (index_t i = 1; i < ingredients.size(); ++i) {
+  for (long long int i = 1; i < SIZE(ingredients); ++i) {
     if (!equal(ingredients.at(i).begin(), ingredients.at(i).end(), exemplar.begin())) {
       result = false;
       break;
@@ -66,10 +66,10 @@ Recipe_number["greater-than"] = GREATER_THAN;
 :(before "End Primitive Recipe Implementations")
 case GREATER_THAN: {
   bool result = true;
-  for (index_t i = 0; i < ingredients.size(); ++i) {
-    assert(ingredients.at(i).size() == 1);  // scalar
+  for (long long int i = 0; i < SIZE(ingredients); ++i) {
+    assert(scalar(ingredients.at(i)));
   }
-  for (index_t i = /**/1; i < ingredients.size(); ++i) {
+  for (long long int i = /**/1; i < SIZE(ingredients); ++i) {
     if (ingredients.at(i-1).at(0) <= ingredients.at(i).at(0)) {
       result = false;
     }
@@ -126,10 +126,10 @@ Recipe_number["lesser-than"] = LESSER_THAN;
 :(before "End Primitive Recipe Implementations")
 case LESSER_THAN: {
   bool result = true;
-  for (index_t i = 0; i < ingredients.size(); ++i) {
-    assert(ingredients.at(i).size() == 1);  // scalar
+  for (long long int i = 0; i < SIZE(ingredients); ++i) {
+    assert(scalar(ingredients.at(i)));
   }
-  for (index_t i = /**/1; i < ingredients.size(); ++i) {
+  for (long long int i = /**/1; i < SIZE(ingredients); ++i) {
     if (ingredients.at(i-1).at(0) >= ingredients.at(i).at(0)) {
       result = false;
     }
@@ -186,10 +186,10 @@ Recipe_number["greater-or-equal"] = GREATER_OR_EQUAL;
 :(before "End Primitive Recipe Implementations")
 case GREATER_OR_EQUAL: {
   bool result = true;
-  for (index_t i = 0; i < ingredients.size(); ++i) {
-    assert(ingredients.at(i).size() == 1);  // scalar
+  for (long long int i = 0; i < SIZE(ingredients); ++i) {
+    assert(scalar(ingredients.at(i)));
   }
-  for (index_t i = /**/1; i < ingredients.size(); ++i) {
+  for (long long int i = /**/1; i < SIZE(ingredients); ++i) {
     if (ingredients.at(i-1).at(0) < ingredients.at(i).at(0)) {
       result = false;
     }
@@ -260,10 +260,10 @@ Recipe_number["lesser-or-equal"] = LESSER_OR_EQUAL;
 :(before "End Primitive Recipe Implementations")
 case LESSER_OR_EQUAL: {
   bool result = true;
-  for (index_t i = 0; i < ingredients.size(); ++i) {
-    assert(ingredients.at(i).size() == 1);  // scalar
+  for (long long int i = 0; i < SIZE(ingredients); ++i) {
+    assert(scalar(ingredients.at(i)));
   }
-  for (index_t i = /**/1; i < ingredients.size(); ++i) {
+  for (long long int i = /**/1; i < SIZE(ingredients); ++i) {
     if (ingredients.at(i-1).at(0) > ingredients.at(i).at(0)) {
       result = false;
     }
diff --git a/026assert.cc b/026assert.cc
index 5b03e318..9e4e79df 100644
--- a/026assert.cc
+++ b/026assert.cc
@@ -11,8 +11,8 @@ ASSERT,
 Recipe_number["assert"] = ASSERT;
 :(before "End Primitive Recipe Implementations")
 case ASSERT: {
-  assert(ingredients.size() == 2);
-  assert(ingredients.at(0).size() == 1);  // scalar
+  assert(SIZE(ingredients) == 2);
+  assert(scalar(ingredients.at(0)));
   if (!ingredients.at(0).at(0)) {
     assert(isa_literal(current_instruction().ingredients.at(1)));
     raise << current_instruction().ingredients.at(1).name << '\n' << die();
diff --git a/027debug.cc b/027debug.cc
index d472a314..7b96e4e9 100644
--- a/027debug.cc
+++ b/027debug.cc
@@ -6,13 +6,13 @@ _PRINT,
 Recipe_number["$print"] = _PRINT;
 :(before "End Primitive Recipe Implementations")
 case _PRINT: {
-  for (index_t i = 0; i < ingredients.size(); ++i) {
+  for (long long int i = 0; i < SIZE(ingredients); ++i) {
     if (isa_literal(current_instruction().ingredients.at(i))) {
       trace("run") << "$print: " << current_instruction().ingredients.at(i).name;
       cout << current_instruction().ingredients.at(i).name;
     }
     else {
-      for (index_t j = 0; j < ingredients.at(i).size(); ++j) {
+      for (long long int j = 0; j < SIZE(ingredients.at(i)); ++j) {
         trace("run") << "$print: " << ingredients.at(i).at(j);
         if (j > 0) cout << " ";
         cout << ingredients.at(i).at(j);
diff --git a/030container.cc b/030container.cc
index 71ef229c..34382295 100644
--- a/030container.cc
+++ b/030container.cc
@@ -80,8 +80,8 @@ recipe main [
 type_info t = Type[types.at(0)];
 if (t.kind == container) {
   // size of a container is the sum of the sizes of its elements
-  size_t result = 0;
-  for (index_t i = 0; i < t.elements.size(); ++i) {
+  long long int result = 0;
+  for (long long int i = 0; i < SIZE(t.elements); ++i) {
     result += size_of(t.elements.at(i));
   }
   return result;
@@ -110,19 +110,19 @@ Recipe_number["get"] = GET;
 :(before "End Primitive Recipe Implementations")
 case GET: {
   reagent base = current_instruction().ingredients.at(0);
-  index_t base_address = base.value;
+  long long int 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)));
-  assert(ingredients.at(1).size() == 1);  // scalar
-  index_t offset = ingredients.at(1).at(0);
-  index_t src = base_address;
-  for (index_t i = 0; i < offset; ++i) {
+  assert(scalar(ingredients.at(1)));
+  long long int offset = ingredients.at(1).at(0);
+  long long int src = base_address;
+  for (long long int i = 0; i < offset; ++i) {
     src += size_of(Type[base_type].elements.at(i));
   }
   trace("run") << "address to copy is " << src;
   assert(Type[base_type].kind == container);
-  assert(Type[base_type].elements.size() > offset);
+  assert(SIZE(Type[base_type].elements) > offset);
   type_number src_type = Type[base_type].elements.at(offset).at(0);
   trace("run") << "its type is " << src_type;
   reagent tmp;
@@ -169,14 +169,14 @@ Recipe_number["get-address"] = GET_ADDRESS;
 :(before "End Primitive Recipe Implementations")
 case GET_ADDRESS: {
   reagent base = current_instruction().ingredients.at(0);
-  index_t base_address = base.value;
+  long long int 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)));
-  assert(ingredients.at(1).size() == 1);  // scalar
-  index_t offset = ingredients.at(1).at(0);
-  index_t result = base_address;
-  for (index_t i = 0; i < offset; ++i) {
+  assert(scalar(ingredients.at(1)));
+  long long int offset = ingredients.at(1).at(0);
+  long long int result = base_address;
+  for (long long int i = 0; i < offset; ++i) {
     result += size_of(Type[base_type].elements.at(i));
   }
   trace("run") << "address to copy is " << result;
@@ -239,8 +239,8 @@ void insert_container(const string& command, kind_of_type kind, istream& in) {
     }
     t.elements.push_back(types);
   }
-  assert(t.elements.size() == t.element_names.size());
-  t.size = t.elements.size();
+  assert(SIZE(t.elements) == SIZE(t.element_names));
+  t.size = SIZE(t.elements);
 }
 
 //: ensure types created in one scenario don't leak outside it.
@@ -249,7 +249,7 @@ vector<type_number> recently_added_types;
 :(before "End load_permanently")  //: for non-tests
 recently_added_types.clear();
 :(before "End Setup")  //: for tests
-for (index_t i = 0; i < recently_added_types.size(); ++i) {
+for (long long int i = 0; i < SIZE(recently_added_types); ++i) {
 //?   cout << "erasing " << Type[recently_added_types.at(i)].name << '\n'; //? 1
   Type_number.erase(Type[recently_added_types.at(i)].name);
   Type.erase(recently_added_types.at(i));
diff --git a/031address.cc b/031address.cc
index 0ea74aa1..f38e96ba 100644
--- a/031address.cc
+++ b/031address.cc
@@ -13,7 +13,7 @@ recipe main [
 +mem: location 2 is 34
 +mem: storing 34 in location 3
 
-:(before "index_t base = x.value" following "vector<double> read_memory(reagent x)")
+:(before "long long int base = x.value" following "vector<double> read_memory(reagent x)")
 x = canonize(x);
 
 //: similarly, write to addresses pointing at other locations using the
@@ -27,7 +27,7 @@ recipe main [
 +mem: location 1 is 2
 +mem: storing 34 in location 2
 
-:(before "index_t base = x.value" following "void write_memory(reagent x, vector<double> data)")
+:(before "long long int base = x.value" following "void write_memory(reagent x, vector<double> data)")
 x = canonize(x);
 
 :(code)
@@ -55,8 +55,8 @@ reagent deref(reagent x) {
   copy(++x.types.begin(), x.types.end(), inserter(result.types, result.types.begin()));
 
   // drop-one 'deref'
-  index_t i = 0;
-  size_t len = x.properties.size();
+  long long int i = 0;
+  long long int len = SIZE(x.properties);
   for (i = 0; i < len; ++i) {
     if (x.properties.at(i).first == "deref") break;
     result.properties.push_back(x.properties.at(i));
@@ -115,14 +115,14 @@ base = canonize(base);
 
 :(code)
 bool has_property(reagent x, string name) {
-  for (index_t i = 0; i < x.properties.size(); ++i) {
+  for (long long int i = 0; i < SIZE(x.properties); ++i) {
     if (x.properties.at(i).first == name) return true;
   }
   return false;
 }
 
 vector<string> property(const reagent& r, const string& name) {
-  for (index_t p = 0; p != r.properties.size(); ++p) {
+  for (long long int p = 0; p != SIZE(r.properties); ++p) {
     if (r.properties.at(p).first == name)
       return r.properties.at(p).second;
   }
diff --git a/032array.cc b/032array.cc
index fd7f9baf..384b2106 100644
--- a/032array.cc
+++ b/032array.cc
@@ -47,11 +47,11 @@ recipe main [
 +mem: storing 16 in location 9
 
 //: disable the size mismatch check since the destination array need not be initialized
-:(replace "if (size_of(x) != data.size())" following "void write_memory(reagent x, vector<double> data)")
-if (x.types.at(0) != Type_number["array"] && size_of(x) != data.size())
-:(after "size_t size_of(const reagent& r)")
+:(replace "if (size_of(x) != SIZE(data))" following "void write_memory(reagent x, vector<double> data)")
+if (x.types.at(0) != Type_number["array"] && size_of(x) != SIZE(data))
+:(after "long long int size_of(const reagent& r)")
   if (r.types.at(0) == Type_number["array"]) {
-    assert(r.types.size() > 1);
+    assert(SIZE(r.types) > 1);
     // skip the 'array' type to get at the element type
     return 1 + Memory[r.value]*size_of(array_element(r.types));
   }
@@ -98,7 +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
-  index_t base_address = base.value;
+  long long int 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
@@ -106,7 +106,7 @@ 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
-  index_t src = base_address + 1 + offset_val.at(0)*size_of(element_type);
+  long long int 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;
@@ -153,12 +153,12 @@ Recipe_number["index-address"] = INDEX_ADDRESS;
 :(before "End Primitive Recipe Implementations")
 case INDEX_ADDRESS: {
   reagent base = canonize(current_instruction().ingredients.at(0));
-  index_t base_address = base.value;
+  long long int base_address = base.value;
   assert(base.types.at(0) == Type_number["array"]);
   reagent offset = canonize(current_instruction().ingredients.at(1));
   vector<double> offset_val(read_memory(offset));
   vector<type_number> element_type = array_element(base.types);
-  index_t result = base_address + 1 + offset_val.at(0)*size_of(element_type);
+  long long int result = base_address + 1 + offset_val.at(0)*size_of(element_type);
   products.resize(1);
   products.at(0).push_back(result);
   break;
diff --git a/034exclusive_container.cc b/034exclusive_container.cc
index 6dc7a82b..6d8e3932 100644
--- a/034exclusive_container.cc
+++ b/034exclusive_container.cc
@@ -11,15 +11,15 @@ type_number tmp = Type_number["number-or-point"] = Next_type_number++;
 Type[tmp].size = 2;
 Type[tmp].kind = exclusive_container;
 Type[tmp].name = "number-or-point";
-//? cout << tmp << ": " << Type[tmp].elements.size() << '\n'; //? 1
+//? cout << tmp << ": " << SIZE(Type[tmp].elements) << '\n'; //? 1
 vector<type_number> t1;
 t1.push_back(number);
 Type[tmp].elements.push_back(t1);
-//? cout << Type[tmp].elements.size() << '\n'; //? 1
+//? cout << SIZE(Type[tmp].elements) << '\n'; //? 1
 vector<type_number> t2;
 t2.push_back(point);
 Type[tmp].elements.push_back(t2);
-//? cout << Type[tmp].elements.size() << '\n'; //? 1
+//? cout << SIZE(Type[tmp].elements) << '\n'; //? 1
 //? cout << "point: " << point << '\n'; //? 1
 Type[tmp].element_names.push_back("i");
 Type[tmp].element_names.push_back("p");
@@ -43,10 +43,10 @@ if (t.kind == exclusive_container) {
   // (So like containers, it can't contain arrays.)
 //?   cout << "--- " << types.at(0) << ' ' << t.size << '\n'; //? 1
 //?   cout << "point: " << Type_number["point"] << " " << Type[Type_number["point"]].name << " " << Type[Type_number["point"]].size << '\n'; //? 1
-//?   cout << t.name << ' ' << t.size << ' ' << t.elements.size() << '\n'; //? 1
-  size_t result = 0;
-  for (index_t i = 0; i < t.size; ++i) {
-    size_t tmp = size_of(t.elements.at(i));
+//?   cout << t.name << ' ' << t.size << ' ' << SIZE(t.elements) << '\n'; //? 1
+  long long int result = 0;
+  for (long long int i = 0; i < t.size; ++i) {
+    long long int tmp = size_of(t.elements.at(i));
 //?     cout << i << ": " << t.elements.at(i).at(0) << ' ' << tmp << ' ' << result << '\n'; //? 1
     if (tmp > result) result = tmp;
   }
@@ -89,13 +89,13 @@ Recipe_number["maybe-convert"] = MAYBE_CONVERT;
 :(before "End Primitive Recipe Implementations")
 case MAYBE_CONVERT: {
   reagent base = canonize(current_instruction().ingredients.at(0));
-  index_t base_address = base.value;
+  long long int 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 tag = current_instruction().ingredients.at(1).value;
   long long int result;
-  if (tag == static_cast<index_t>(Memory[base_address])) {
+  if (tag == static_cast<long long int>(Memory[base_address])) {
     result = base_address+1;
   }
   else {
diff --git a/035call.cc b/035call.cc
index c80331d2..e1d392e7 100644
--- a/035call.cc
+++ b/035call.cc
@@ -33,7 +33,7 @@ recipe f [
 // This requires maintaining a 'stack' of interrupted recipes or 'calls'.
 struct call {
   recipe_number running_recipe;
-  index_t running_step_index;
+  long long int running_step_index;
   // End call Fields
   call(recipe_number r) :running_recipe(r), running_step_index(0) {}
 };
@@ -55,8 +55,8 @@ routine::routine(recipe_number r) {
 
 //:: now update routine's helpers
 
-:(replace{} "inline index_t& current_step_index()")
-inline index_t& current_step_index() {
+:(replace{} "inline long long int& current_step_index()")
+inline long long int& current_step_index() {
   assert(!Current_routine->calls.empty());
   return Current_routine->calls.front().running_step_index;
 }
@@ -97,7 +97,7 @@ inline const vector<instruction>& routine::steps() const {
 :(before "Running One Instruction")
 // when we reach the end of one call, we may reach the end of the one below
 // it, and the one below that, and so on
-while (current_step_index() >= Current_routine->steps().size()) {
+while (current_step_index() >= SIZE(Current_routine->steps())) {
   Current_routine->calls.pop_front();
   if (Current_routine->calls.empty()) return;
   // todo: no results returned warning
diff --git a/036call_ingredient.cc b/036call_ingredient.cc
index a6fbb181..090d86a8 100644
--- a/036call_ingredient.cc
+++ b/036call_ingredient.cc
@@ -24,13 +24,13 @@ recipe f [
 
 :(before "End call Fields")
 vector<vector<double> > ingredient_atoms;
-index_t next_ingredient_to_process;
+long long int next_ingredient_to_process;
 :(replace{} "call(recipe_number r)")
 call(recipe_number r) :running_recipe(r), running_step_index(0), next_ingredient_to_process(0) {}
 
 :(replace "Current_routine->calls.push_front(call(current_instruction().operation))" following "End Primitive Recipe Implementations")
 call callee(current_instruction().operation);
-for (size_t i = 0; i < ingredients.size(); ++i) {
+for (long long int i = 0; i < SIZE(ingredients); ++i) {
   callee.ingredient_atoms.push_back(ingredients.at(i));
 }
 Current_routine->calls.push_front(callee);
@@ -42,10 +42,10 @@ Recipe_number["next-ingredient"] = NEXT_INGREDIENT;
 :(before "End Primitive Recipe Implementations")
 case NEXT_INGREDIENT: {
   assert(!Current_routine->calls.empty());
-  if (Current_routine->calls.front().next_ingredient_to_process < Current_routine->calls.front().ingredient_atoms.size()) {
+  if (Current_routine->calls.front().next_ingredient_to_process < SIZE(Current_routine->calls.front().ingredient_atoms)) {
     products.push_back(
         Current_routine->calls.front().ingredient_atoms.at(Current_routine->calls.front().next_ingredient_to_process));
-    assert(products.size() == 1);  products.resize(2);  // push a new vector
+    assert(SIZE(products) == 1);  products.resize(2);  // push a new vector
     products.at(1).push_back(1);
     ++Current_routine->calls.front().next_ingredient_to_process;
   }
@@ -100,17 +100,17 @@ Recipe_number["ingredient"] = INGREDIENT;
 :(before "End Primitive Recipe Implementations")
 case INGREDIENT: {
   assert(isa_literal(current_instruction().ingredients.at(0)));
-  assert(ingredients.at(0).size() == 1);  // scalar
-  if (static_cast<index_t>(ingredients.at(0).at(0)) < Current_routine->calls.front().ingredient_atoms.size()) {
+  assert(scalar(ingredients.at(0)));
+  if (static_cast<long long int>(ingredients.at(0).at(0)) < SIZE(Current_routine->calls.front().ingredient_atoms)) {
     Current_routine->calls.front().next_ingredient_to_process = ingredients.at(0).at(0);
     products.push_back(
         Current_routine->calls.front().ingredient_atoms.at(Current_routine->calls.front().next_ingredient_to_process));
-    assert(products.size() == 1);  products.resize(2);  // push a new vector
+    assert(SIZE(products) == 1);  products.resize(2);  // push a new vector
     products.at(1).push_back(1);
     ++Current_routine->calls.front().next_ingredient_to_process;
   }
   else {
-    if (current_instruction().products.size() > 1) {
+    if (SIZE(current_instruction().products) > 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);
diff --git a/037call_reply.cc b/037call_reply.cc
index 4eaea444..c6045d9c 100644
--- a/037call_reply.cc
+++ b/037call_reply.cc
@@ -28,11 +28,11 @@ case REPLY: {
   copy(ingredients.begin(), ingredients.end(), inserter(products, products.begin()));
   // check that any reply ingredients with /same-as-ingredient connect up
   // the corresponding ingredient and product in the caller.
-  for (index_t i = 0; i < caller_instruction.products.size(); ++i) {
+  for (long long int i = 0; i < SIZE(caller_instruction.products); ++i) {
     trace("run") << "result " << i << " is " << to_string(ingredients.at(i));
     if (has_property(reply_inst.ingredients.at(i), "same-as-ingredient")) {
       vector<string> tmp = property(reply_inst.ingredients.at(i), "same-as-ingredient");
-      assert(tmp.size() == 1);
+      assert(SIZE(tmp) == 1);
       long long int ingredient_index = to_integer(tmp.at(0));
       if (caller_instruction.products.at(i).value != caller_instruction.ingredients.at(ingredient_index).value)
         raise << "'same-as-ingredient' result " << caller_instruction.products.at(i).value << " must be location " << caller_instruction.ingredients.at(ingredient_index).value << '\n';
@@ -79,12 +79,12 @@ recipe test1 [
 string to_string(const vector<double>& in) {
   if (in.empty()) return "[]";
   ostringstream out;
-  if (in.size() == 1) {
+  if (SIZE(in) == 1) {
     out << in.at(0);
     return out.str();
   }
   out << "[";
-  for (index_t i = 0; i < in.size(); ++i) {
+  for (long long int i = 0; i < SIZE(in); ++i) {
     if (i > 0) out << ", ";
     out << in.at(i);
   }
diff --git a/038scheduler.cc b/038scheduler.cc
index 101d1960..593aad7f 100644
--- a/038scheduler.cc
+++ b/038scheduler.cc
@@ -18,9 +18,9 @@ recipe f2 [
 //: first, add a deadline to run(routine)
 //: these changes are ugly and brittle; just close your nose and get through the next few lines
 :(replace "void run_current_routine()")
-void run_current_routine(size_t time_slice)
-:(replace "while (!Current_routine->completed())" following "void run_current_routine(size_t time_slice)")
-size_t ninstrs = 0;
+void run_current_routine(long long int time_slice)
+:(replace "while (!Current_routine->completed())" following "void run_current_routine(long long int time_slice)")
+long long int ninstrs = 0;
 while (Current_routine->state == RUNNING && ninstrs < time_slice)
 :(after "Running One Instruction")
 ninstrs++;
@@ -40,8 +40,8 @@ state = RUNNING;
 
 :(before "End Globals")
 vector<routine*> Routines;
-index_t Current_routine_index = 0;
-size_t Scheduling_interval = 500;
+long long int Current_routine_index = 0;
+long long int Scheduling_interval = 500;
 :(before "End Setup")
 Scheduling_interval = 500;
 :(replace{} "void run(recipe_number r)")
@@ -70,7 +70,7 @@ void run(recipe_number r) {
 
 :(code)
 bool all_routines_done() {
-  for (index_t i = 0; i < Routines.size(); ++i) {
+  for (long long int i = 0; i < SIZE(Routines); ++i) {
 //?     cout << "routine " << i << ' ' << Routines.at(i)->state << '\n'; //? 1
     if (Routines.at(i)->state == RUNNING) {
       return false;
@@ -82,8 +82,8 @@ bool all_routines_done() {
 // skip Current_routine_index past non-RUNNING routines
 void skip_to_next_routine() {
   assert(!Routines.empty());
-  assert(Current_routine_index < Routines.size());
-  for (index_t i = (Current_routine_index+1)%Routines.size();  i != Current_routine_index;  i = (i+1)%Routines.size()) {
+  assert(Current_routine_index < SIZE(Routines));
+  for (long long int i = (Current_routine_index+1)%SIZE(Routines);  i != Current_routine_index;  i = (i+1)%SIZE(Routines)) {
     if (Routines.at(i)->state == RUNNING) {
 //?       cout << "switching to " << i << '\n'; //? 1
       Current_routine_index = i;
@@ -105,7 +105,7 @@ string current_routine_label() {
 }
 
 :(before "End Teardown")
-for (index_t i = 0; i < Routines.size(); ++i)
+for (long long int i = 0; i < SIZE(Routines); ++i)
   delete Routines.at(i);
 Routines.clear();
 
@@ -114,9 +114,9 @@ Routines.clear();
 //: 'start-running' will return a unique id for the routine that was created.
 //: routine id is a number, but don't do any arithmetic on it
 :(before "End routine Fields")
-index_t id;
+long long int id;
 :(before "End Globals")
-index_t Next_routine_id = 1;
+long long int Next_routine_id = 1;
 :(before "End Setup")
 Next_routine_id = 1;
 :(before "End routine Constructor")
@@ -146,7 +146,7 @@ case START_RUNNING: {
 //?   cerr << new_routine->id << " -> " << Current_routine->id << '\n'; //? 1
   new_routine->parent_index = Current_routine_index;
   // populate ingredients
-  for (index_t i = 1; i < current_instruction().ingredients.size(); ++i)
+  for (long long int i = 1; i < SIZE(current_instruction().ingredients); ++i)
     new_routine->calls.front().ingredient_atoms.push_back(ingredients.at(i));
   Routines.push_back(new_routine);
   products.resize(1);
@@ -255,10 +255,10 @@ recipe f1 [
 
 :(before "End Scheduler Cleanup")
 //? trace("schedule") << "Before cleanup"; //? 1
-//? for (index_t i = 0; i < Routines.size(); ++i) { //? 1
+//? for (long long int i = 0; i < SIZE(Routines); ++i) { //? 1
 //?   trace("schedule") << i << ": " << Routines.at(i)->id << ' ' << Routines.at(i)->state << ' ' << Routines.at(i)->parent_index << ' ' << Routines.at(i)->state; //? 1
 //? } //? 1
-for (index_t i = 0; i < Routines.size(); ++i) {
+for (long long int i = 0; i < SIZE(Routines); ++i) {
   if (Routines.at(i)->state == COMPLETED) continue;
   if (Routines.at(i)->parent_index < 0) continue;  // root thread
 //?   trace("schedule") << "AAA " << i; //? 1
@@ -268,12 +268,12 @@ for (index_t i = 0; i < Routines.size(); ++i) {
   }
 }
 //? trace("schedule") << "After cleanup"; //? 1
-//? for (index_t i = 0; i < Routines.size(); ++i) { //? 1
+//? for (long long int i = 0; i < SIZE(Routines); ++i) { //? 1
 //?   trace("schedule") << i << ": " << Routines.at(i)->id << ' ' << Routines.at(i)->state << ' ' << Routines.at(i)->parent_index << ' ' << Routines.at(i)->state; //? 1
 //? } //? 1
 
 :(code)
-bool has_completed_parent(index_t routine_index) {
+bool has_completed_parent(long long int routine_index) {
 //?   trace("schedule") << "CCC " << routine_index << '\n'; //? 2
   for (long long int j = routine_index; j >= 0; j = Routines.at(j)->parent_index) {
 //?     trace("schedule") << "DDD " << j << '\n'; //? 2
@@ -306,10 +306,10 @@ ROUTINE_STATE,
 Recipe_number["routine-state"] = ROUTINE_STATE;
 :(before "End Primitive Recipe Implementations")
 case ROUTINE_STATE: {
-  assert(ingredients.at(0).size() == 1);  // routine id must be scalar
-  index_t id = ingredients.at(0).at(0);
+  assert(scalar(ingredients.at(0)));
+  long long int id = ingredients.at(0).at(0);
   long long int result = -1;
-  for (index_t i = 0; i < Routines.size(); ++i) {
+  for (long long int i = 0; i < SIZE(Routines); ++i) {
     if (Routines.at(i)->id == id) {
       result = Routines.at(i)->state;
       break;
@@ -328,9 +328,9 @@ RESTART,
 Recipe_number["restart"] = RESTART;
 :(before "End Primitive Recipe Implementations")
 case RESTART: {
-  assert(ingredients.at(0).size() == 1);  // routine id must be scalar
-  index_t id = ingredients.at(0).at(0);
-  for (index_t i = 0; i < Routines.size(); ++i) {
+  assert(scalar(ingredients.at(0)));
+  long long int id = ingredients.at(0).at(0);
+  for (long long int i = 0; i < SIZE(Routines); ++i) {
     if (Routines.at(i)->id == id) {
       Routines.at(i)->state = RUNNING;
       break;
@@ -345,9 +345,9 @@ STOP,
 Recipe_number["stop"] = STOP;
 :(before "End Primitive Recipe Implementations")
 case STOP: {
-  assert(ingredients.at(0).size() == 1);  // routine id must be scalar
-  index_t id = ingredients.at(0).at(0);
-  for (index_t i = 0; i < Routines.size(); ++i) {
+  assert(scalar(ingredients.at(0)));
+  long long int id = ingredients.at(0).at(0);
+  for (long long int i = 0; i < SIZE(Routines); ++i) {
     if (Routines.at(i)->id == id) {
       Routines.at(i)->state = COMPLETED;
       break;
@@ -362,7 +362,7 @@ _DUMP_ROUTINES,
 Recipe_number["$dump-routines"] = _DUMP_ROUTINES;
 :(before "End Primitive Recipe Implementations")
 case _DUMP_ROUTINES: {
-  for (index_t i = 0; i < Routines.size(); ++i) {
+  for (long long int i = 0; i < SIZE(Routines); ++i) {
     cerr << i << ": " << Routines.at(i)->id << ' ' << Routines.at(i)->state << ' ' << Routines.at(i)->parent_index << '\n';
   }
   break;
diff --git a/039wait.cc b/039wait.cc
index c7743785..14a9ee18 100644
--- a/039wait.cc
+++ b/039wait.cc
@@ -23,7 +23,7 @@ recipe f2 [
 WAITING,
 :(before "End routine Fields")
 // only if state == WAITING
-index_t waiting_on_location;
+long long int waiting_on_location;
 int old_value_of_waiting_location;
 :(before "End routine Constructor")
 waiting_on_location = old_value_of_waiting_location = 0;
@@ -48,7 +48,7 @@ case WAIT_FOR_LOCATION: {
 //: scheduler tweak to get routines out of that state
 
 :(before "End Scheduler State Transitions")
-for (index_t i = 0; i < Routines.size(); ++i) {
+for (long long int i = 0; i < SIZE(Routines); ++i) {
 //?   trace("schedule") << "wake up loop 1: routine " << Routines.at(i)->id << " has state " << Routines.at(i)->state; //? 1
   if (Routines.at(i)->state != WAITING) continue;
 //?   trace("schedule") << "waiting on location: " << Routines.at(i)->waiting_on_location; //? 1
@@ -86,7 +86,7 @@ recipe f2 [
 
 :(before "End routine Fields")
 // only if state == WAITING
-index_t waiting_on_routine;
+long long int waiting_on_routine;
 :(before "End routine Constructor")
 waiting_on_routine = 0;
 
@@ -97,7 +97,7 @@ Recipe_number["wait-for-routine"] = WAIT_FOR_ROUTINE;
 :(before "End Primitive Recipe Implementations")
 case WAIT_FOR_ROUTINE: {
   Current_routine->state = WAITING;
-  assert(ingredients.at(0).size() == 1);  // scalar
+  assert(scalar(ingredients.at(0)));
   Current_routine->waiting_on_routine = ingredients.at(0).at(0);
   trace("run") << "waiting for routine " << ingredients.at(0).at(0);
   break;
@@ -107,12 +107,12 @@ case WAIT_FOR_ROUTINE: {
 // Wake up any routines waiting for other routines to go to sleep.
 // Important: this must come after the scheduler loop above giving routines
 // waiting for locations to change a chance to wake up.
-for (index_t i = 0; i < Routines.size(); ++i) {
+for (long long int i = 0; i < SIZE(Routines); ++i) {
   if (Routines.at(i)->state != WAITING) continue;
   if (!Routines.at(i)->waiting_on_routine) continue;
-  index_t id = Routines.at(i)->waiting_on_routine;
+  long long int id = Routines.at(i)->waiting_on_routine;
   assert(id != Routines.at(i)->id);
-  for (index_t j = 0; j < Routines.size(); ++j) {
+  for (long long int j = 0; j < SIZE(Routines); ++j) {
     if (Routines.at(j)->id == id && Routines.at(j)->state != RUNNING) {
       trace("schedule") << "waking up routine " << Routines.at(i)->id;
       Routines.at(i)->state = RUNNING;
@@ -127,7 +127,7 @@ SWITCH,
 Recipe_number["switch"] = SWITCH;
 :(before "End Primitive Recipe Implementations")
 case SWITCH: {
-  index_t id = some_other_running_routine();
+  long long int id = some_other_running_routine();
   if (id) {
     assert(id != Current_routine->id);
 //?     cerr << "waiting on " << id << " from " << Current_routine->id << '\n'; //? 1
@@ -138,8 +138,8 @@ case SWITCH: {
 }
 
 :(code)
-index_t some_other_running_routine() {
-  for (index_t i = 0; i < Routines.size(); ++i) {
+long long int some_other_running_routine() {
+  for (long long int i = 0; i < SIZE(Routines); ++i) {
     if (i == Current_routine_index) continue;
     assert(Routines.at(i) != Current_routine);
     assert(Routines.at(i)->id != Current_routine->id);
diff --git a/040brace.cc b/040brace.cc
index ec9c6a4d..8a1b4512 100644
--- a/040brace.cc
+++ b/040brace.cc
@@ -42,7 +42,7 @@ void transform_braces(const recipe_number r) {
   const int OPEN = 0, CLOSE = 1;
   // use signed integer for step index because we'll be doing arithmetic on it
   list<pair<int/*OPEN/CLOSE*/, /*step*/long long int> > braces;
-  for (long long int index = 0; index < static_cast<long long int>(Recipe[r].steps.size()); ++index) {
+  for (long long int index = 0; index < SIZE(Recipe[r].steps); ++index) {
     const instruction& inst = Recipe[r].steps.at(index);
     if (inst.label == "{") {
       trace("brace") << r << ": push (open, " << index << ")";
@@ -55,7 +55,7 @@ void transform_braces(const recipe_number r) {
   }
   stack</*step*/long long int> open_braces;
   trace("after-brace") << "recipe " << Recipe[r].name;
-  for (long long int index = 0; index < static_cast<long long int>(Recipe[r].steps.size()); ++index) {
+  for (long long int index = 0; index < SIZE(Recipe[r].steps); ++index) {
 //?     cerr << index << '\n'; //? 1
     instruction& inst = Recipe[r].steps.at(index);
 //?     cout << "AAA " << inst.name << ": " << inst.operation << '\n'; //? 1
@@ -65,7 +65,7 @@ void transform_braces(const recipe_number r) {
       ;  // do nothing
     else if (inst.operation == Recipe_number["loop"]) {
       inst.operation = Recipe_number["jump"];
-      if (inst.ingredients.size() > 0 && isa_literal(inst.ingredients.at(0))) {
+      if (SIZE(inst.ingredients) > 0 && isa_literal(inst.ingredients.at(0))) {
         // explicit target; a later phase will handle it
         trace("after-brace") << "jump " << inst.ingredients.at(0).name << ":offset";
       }
@@ -81,7 +81,7 @@ void transform_braces(const recipe_number r) {
     }
     else if (inst.operation == Recipe_number["break"]) {
       inst.operation = Recipe_number["jump"];
-      if (inst.ingredients.size() > 0 && isa_literal(inst.ingredients.at(0))) {
+      if (SIZE(inst.ingredients) > 0 && isa_literal(inst.ingredients.at(0))) {
         // explicit target; a later phase will handle it
         trace("after-brace") << "jump " << inst.ingredients.at(0).name << ":offset";
       }
@@ -95,7 +95,7 @@ void transform_braces(const recipe_number r) {
     }
     else if (inst.operation == Recipe_number["loop-if"]) {
       inst.operation = Recipe_number["jump-if"];
-      if (inst.ingredients.size() > 1 && isa_literal(inst.ingredients.at(1))) {
+      if (SIZE(inst.ingredients) > 1 && isa_literal(inst.ingredients.at(1))) {
         // explicit target; a later phase will handle it
         trace("after-brace") << "jump " << inst.ingredients.at(1).name << ":offset";
       }
@@ -109,7 +109,7 @@ void transform_braces(const recipe_number r) {
     }
     else if (inst.operation == Recipe_number["break-if"]) {
       inst.operation = Recipe_number["jump-if"];
-      if (inst.ingredients.size() > 1 && isa_literal(inst.ingredients.at(1))) {
+      if (SIZE(inst.ingredients) > 1 && isa_literal(inst.ingredients.at(1))) {
         // explicit target; a later phase will handle it
         trace("after-brace") << "jump " << inst.ingredients.at(1).name << ":offset";
       }
@@ -123,7 +123,7 @@ void transform_braces(const recipe_number r) {
     }
     else if (inst.operation == Recipe_number["loop-unless"]) {
       inst.operation = Recipe_number["jump-unless"];
-      if (inst.ingredients.size() > 1 && isa_literal(inst.ingredients.at(1))) {
+      if (SIZE(inst.ingredients) > 1 && isa_literal(inst.ingredients.at(1))) {
         // explicit target; a later phase will handle it
         trace("after-brace") << "jump " << inst.ingredients.at(1).name << ":offset";
       }
@@ -138,7 +138,7 @@ void transform_braces(const recipe_number r) {
     else if (inst.operation == Recipe_number["break-unless"]) {
 //?       cout << "AAA break-unless\n"; //? 1
       inst.operation = Recipe_number["jump-unless"];
-      if (inst.ingredients.size() > 1 && isa_literal(inst.ingredients.at(1))) {
+      if (SIZE(inst.ingredients) > 1 && isa_literal(inst.ingredients.at(1))) {
         // explicit target; a later phase will handle it
         trace("after-brace") << "jump " << inst.ingredients.at(1).name << ":offset";
       }
diff --git a/041name.cc b/041name.cc
index 1f8a17bd..cf337ffc 100644
--- a/041name.cc
+++ b/041name.cc
@@ -21,9 +21,9 @@ recipe main [
   Transform.push_back(transform_names);
 
 :(before "End Globals")
-map<recipe_number, map<string, index_t> > Name;
+map<recipe_number, map<string, long long int> > Name;
 :(after "Clear Other State For recently_added_recipes")
-for (index_t i = 0; i < recently_added_recipes.size(); ++i) {
+for (long long int i = 0; i < SIZE(recently_added_recipes); ++i) {
   Name.erase(recently_added_recipes.at(i));
 }
 
@@ -31,15 +31,15 @@ for (index_t i = 0; i < recently_added_recipes.size(); ++i) {
 void transform_names(const recipe_number r) {
   bool names_used = false;
   bool numeric_locations_used = false;
-  map<string, index_t>& names = Name[r];
+  map<string, long long int>& names = Name[r];
   // store the indices 'used' so far in the map
-  index_t& curr_idx = names[""];
+  long long int& curr_idx = names[""];
   ++curr_idx;  // avoid using index 0, benign skip in some other cases
-  for (index_t i = 0; i < Recipe[r].steps.size(); ++i) {
+  for (long long int i = 0; i < SIZE(Recipe[r].steps); ++i) {
     instruction& inst = Recipe[r].steps.at(i);
     // Per-recipe Transforms
     // map names to addresses
-    for (index_t in = 0; in < inst.ingredients.size(); ++in) {
+    for (long long int in = 0; in < SIZE(inst.ingredients); ++in) {
       if (is_numeric_location(inst.ingredients.at(in))) numeric_locations_used = true;
       if (is_named_location(inst.ingredients.at(in))) names_used = true;
       if (disqualified(inst.ingredients.at(in))) continue;
@@ -48,7 +48,7 @@ void transform_names(const recipe_number r) {
       }
       inst.ingredients.at(in).set_value(lookup_name(inst.ingredients.at(in), r));
     }
-    for (index_t out = 0; out < inst.products.size(); ++out) {
+    for (long long int out = 0; out < SIZE(inst.products); ++out) {
       if (is_numeric_location(inst.products.at(out))) numeric_locations_used = true;
       if (is_named_location(inst.products.at(out))) names_used = true;
       if (disqualified(inst.products.at(out))) continue;
@@ -77,16 +77,16 @@ bool disqualified(/*mutable*/ reagent& x) {
   return false;
 }
 
-bool already_transformed(const reagent& r, const map<string, index_t>& names) {
+bool already_transformed(const reagent& r, const map<string, long long int>& names) {
   return names.find(r.name) != names.end();
 }
 
-index_t lookup_name(const reagent& r, const recipe_number default_recipe) {
+long long int lookup_name(const reagent& r, const recipe_number default_recipe) {
   return Name[default_recipe][r.name];
 }
 
 type_number skip_addresses(const vector<type_number>& types) {
-  for (index_t i = 0; i < types.size(); ++i) {
+  for (long long int i = 0; i < SIZE(types); ++i) {
     if (types.at(i) != Type_number["address"]) return types.at(i);
   }
   raise << "expected a container" << '\n' << die();
@@ -95,8 +95,8 @@ type_number skip_addresses(const vector<type_number>& types) {
 
 int find_element_name(const type_number t, const string& name) {
   const type_info& container = Type[t];
-//?   cout << "looking for element " << name << " in type " << container.name << " with " << container.element_names.size() << " elements\n"; //? 1
-  for (index_t i = 0; i < container.element_names.size(); ++i) {
+//?   cout << "looking for element " << name << " in type " << container.name << " with " << SIZE(container.element_names) << " elements\n"; //? 1
+  for (long long int i = 0; i < SIZE(container.element_names); ++i) {
     if (container.element_names.at(i) == name) return i;
   }
   raise << "unknown element " << name << " in container " << t << '\n' << die();
@@ -118,7 +118,7 @@ bool is_named_location(const reagent& x) {
 }
 
 bool is_raw(const reagent& r) {
-  for (index_t i = /*skip value+type*/1; i < r.properties.size(); ++i) {
+  for (long long int i = /*skip value+type*/1; i < SIZE(r.properties); ++i) {
     if (r.properties.at(i).first == "raw") return true;
   }
   return false;
@@ -214,10 +214,10 @@ recipe main [
 if (inst.operation == Recipe_number["get"]
     || inst.operation == Recipe_number["get-address"]) {
   // at least 2 args, and second arg is offset
-  assert(inst.ingredients.size() >= 2);
+  assert(SIZE(inst.ingredients) >= 2);
 //?   cout << inst.ingredients.at(1).to_string() << '\n'; //? 1
   assert(isa_literal(inst.ingredients.at(1)));
-  if (inst.ingredients.at(1).name.find_first_not_of("0123456789") == NOT_FOUND) continue;
+  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(find_element_name(base_type, inst.ingredients.at(1).name));
@@ -251,9 +251,9 @@ recipe main [
 // convert variant names of exclusive containers
 if (inst.operation == Recipe_number["maybe-convert"]) {
   // at least 2 args, and second arg is offset
-  assert(inst.ingredients.size() >= 2);
+  assert(SIZE(inst.ingredients) >= 2);
   assert(isa_literal(inst.ingredients.at(1)));
-  if (inst.ingredients.at(1).name.find_first_not_of("0123456789") == NOT_FOUND) continue;
+  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(find_element_name(base_type, inst.ingredients.at(1).name));
diff --git a/042new.cc b/042new.cc
index 8d90c3e7..7e173b36 100644
--- a/042new.cc
+++ b/042new.cc
@@ -11,14 +11,14 @@ recipe main [
 +mem: storing 0 in location 3
 
 :(before "End Globals")
-size_t Reserved_for_tests = 1000;
-index_t Memory_allocated_until = Reserved_for_tests;
-size_t Initial_memory_per_routine = 100000;
+long long int Reserved_for_tests = 1000;
+long long int Memory_allocated_until = Reserved_for_tests;
+long long int Initial_memory_per_routine = 100000;
 :(before "End Setup")
 Memory_allocated_until = Reserved_for_tests;
 Initial_memory_per_routine = 100000;
 :(before "End routine Fields")
-index_t alloc, alloc_max;
+long long int alloc, alloc_max;
 :(before "End routine Constructor")
 alloc = Memory_allocated_until;
 Memory_allocated_until += Initial_memory_per_routine;
@@ -33,7 +33,7 @@ Type_number["type"] = 0;
 // replace type names with type_numbers
 if (inst.operation == Recipe_number["new"]) {
   // first arg must be of type 'type'
-  assert(inst.ingredients.size() >= 1);
+  assert(SIZE(inst.ingredients) >= 1);
 //?   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") {
@@ -52,13 +52,13 @@ Recipe_number["new"] = NEW;
 :(before "End Primitive Recipe Implementations")
 case NEW: {
   // compute the space we need
-  size_t size = 0;
-  size_t array_length = 0;
+  long long int size = 0;
+  long long int array_length = 0;
   {
     vector<type_number> type;
     assert(isa_literal(current_instruction().ingredients.at(0)));
     type.push_back(current_instruction().ingredients.at(0).value);
-    if (current_instruction().ingredients.size() > 1) {
+    if (SIZE(current_instruction().ingredients) > 1) {
       // array
       array_length = ingredients.at(1).at(0);
       trace("mem") << "array size is " << array_length;
@@ -72,16 +72,16 @@ case NEW: {
   // compute the region of memory to return
   // really crappy at the moment
   ensure_space(size);
-  const index_t result = Current_routine->alloc;
+  const long long int result = Current_routine->alloc;
   trace("mem") << "new alloc: " << result;
   // save result
   products.resize(1);
   products.at(0).push_back(result);
   // initialize allocated space
-  for (index_t address = result; address < result+size; ++address) {
+  for (long long int address = result; address < result+size; ++address) {
     Memory[address] = 0;
   }
-  if (current_instruction().ingredients.size() > 1) {
+  if (SIZE(current_instruction().ingredients) > 1) {
     Memory[result] = array_length;
   }
   // bump
@@ -92,7 +92,7 @@ case NEW: {
 }
 
 :(code)
-void ensure_space(size_t size) {
+void ensure_space(long long int size) {
   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) {
@@ -169,7 +169,7 @@ recipe main [
 if (isa_literal(current_instruction().ingredients.at(0))
     && current_instruction().ingredients.at(0).properties.at(0).second.at(0) == "literal-string") {
   // allocate an array just large enough for it
-  size_t string_length = current_instruction().ingredients.at(0).name.size();
+  long long int string_length = SIZE(current_instruction().ingredients.at(0).name);
 //?   cout << "string_length is " << string_length << '\n'; //? 1
   ensure_space(string_length+1);  // don't forget the extra location for array size
   products.resize(1);
@@ -177,7 +177,7 @@ if (isa_literal(current_instruction().ingredients.at(0))
   // initialize string
 //?   cout << "new string literal: " << current_instruction().ingredients.at(0).name << '\n'; //? 1
   Memory[Current_routine->alloc++] = string_length;
-  for (index_t i = 0; i < string_length; ++i) {
+  for (long long int i = 0; i < string_length; ++i) {
     Memory[Current_routine->alloc++] = current_instruction().ingredients.at(0).name.at(i);
   }
   // mu strings are not null-terminated in memory
diff --git a/043space.cc b/043space.cc
index ec63e19a..494e8215 100644
--- a/043space.cc
+++ b/043space.cc
@@ -26,7 +26,7 @@ recipe main [
 +mem: storing 34 in location 8
 
 :(before "End call Fields")
-index_t default_space;
+long long int default_space;
 :(replace "call(recipe_number r) :running_recipe(r)")
 call(recipe_number r) :running_recipe(r), running_step_index(0), next_ingredient_to_process(0), default_space(0) {}
 
@@ -93,14 +93,14 @@ tmp.properties.push_back(pair<string, vector<string> >("raw", vector<string>()))
 //:: helpers
 
 :(code)
-index_t space_base(const reagent& x) {
+long long int space_base(const reagent& x) {
   return Current_routine->calls.front().default_space;
 }
 
-index_t address(index_t offset, index_t base) {
+long long int address(long long int offset, long long int base) {
   if (base == 0) return offset;  // raw
 //?   cout << base << '\n'; //? 2
-  if (offset >= static_cast<index_t>(Memory[base])) {
+  if (offset >= static_cast<long long int>(Memory[base])) {
     // todo: test
     raise << "location " << offset << " is out of bounds " << Memory[base] << '\n';
   }
@@ -109,7 +109,7 @@ index_t address(index_t offset, index_t base) {
 
 :(after "void write_memory(reagent x, vector<double> data)")
   if (x.name == "default-space") {
-    assert(data.size() == 1);
+    assert(scalar(data));
     Current_routine->calls.front().default_space = data.at(0);
 //?     cout << "AAA " << Current_routine->calls.front().default_space << '\n'; //? 1
     return;
diff --git a/044space_surround.cc b/044space_surround.cc
index 445be78c..5464c968 100644
--- a/044space_surround.cc
+++ b/044space_surround.cc
@@ -25,26 +25,26 @@ recipe main [
 //: lifetime, surrounding allows managing shorter lifetimes inside a longer
 //: one.
 
-:(replace{} "index_t space_base(const reagent& x)")
-index_t space_base(const reagent& x) {
+:(replace{} "long long int space_base(const reagent& x)")
+long long int space_base(const reagent& x) {
   return space_base(x, space_index(x), Current_routine->calls.front().default_space);
 }
 
-index_t space_base(const reagent& x, index_t space_index, index_t base) {
+long long int space_base(const reagent& x, long long int space_index, long long int base) {
 //?   trace("foo") << "base of space " << space_index << '\n'; //? 1
   if (space_index == 0) {
 //?     trace("foo") << "base of space " << space_index << " is " << base << '\n'; //? 1
     return base;
   }
 //?   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]);
+  long long int result = space_base(x, space_index-1, Memory[base+1]);
   return result;
 }
 
-index_t space_index(const reagent& x) {
-  for (index_t i = 0; i < x.properties.size(); ++i) {
+long long int space_index(const reagent& x) {
+  for (long long int i = 0; i < SIZE(x.properties); ++i) {
     if (x.properties.at(i).first == "space") {
-      assert(x.properties.at(i).second.size() == 1);
+      assert(SIZE(x.properties.at(i).second) == 1);
       return to_integer(x.properties.at(i).second.at(0));
     }
   }
diff --git a/045closure_name.cc b/045closure_name.cc
index 5af737d0..237eee3c 100644
--- a/045closure_name.cc
+++ b/045closure_name.cc
@@ -42,13 +42,13 @@ map<recipe_number, recipe_number> Surrounding_space;
 
 :(code)
 void collect_surrounding_spaces(const recipe_number r) {
-  for (index_t i = 0; i < Recipe[r].steps.size(); ++i) {
+  for (long long int i = 0; i < SIZE(Recipe[r].steps); ++i) {
     const instruction& inst = Recipe[r].steps.at(i);
     if (inst.is_label) continue;
-    for (index_t j = 0; j < inst.products.size(); ++j) {
+    for (long long int j = 0; j < SIZE(inst.products); ++j) {
       if (isa_literal(inst.products.at(j))) continue;
       if (inst.products.at(j).name != "0") continue;
-      if (inst.products.at(j).types.size() != 3
+      if (SIZE(inst.products.at(j).types) != 3
           || inst.products.at(j).types.at(0) != Type_number["address"]
           || inst.products.at(j).types.at(1) != Type_number["array"]
           || inst.products.at(j).types.at(2) != Type_number["location"]) {
@@ -58,7 +58,7 @@ void collect_surrounding_spaces(const recipe_number r) {
       vector<string> s = property(inst.products.at(j), "names");
       if (s.empty())
         raise << "slot 0 requires a /names property in recipe " << Recipe[r].name << die();
-      if (s.size() > 1) raise << "slot 0 should have a single value in /names, got " << inst.products.at(j).to_string() << '\n';
+      if (SIZE(s) > 1) raise << "slot 0 should have a single value in /names, got " << inst.products.at(j).to_string() << '\n';
       string surrounding_recipe_name = s.at(0);
       if (Surrounding_space.find(r) != Surrounding_space.end()
           && Surrounding_space[r] != Recipe_number[surrounding_recipe_name]) {
@@ -74,8 +74,8 @@ void collect_surrounding_spaces(const recipe_number r) {
 //: Once surrounding spaces are available, transform_names uses them to handle
 //: /space properties.
 
-:(replace{} "index_t lookup_name(const reagent& r, const recipe_number default_recipe)")
-index_t lookup_name(const reagent& x, const recipe_number default_recipe) {
+:(replace{} "long long int lookup_name(const reagent& r, const recipe_number default_recipe)")
+long long int lookup_name(const reagent& x, const recipe_number default_recipe) {
 //?   cout << "AAA " << default_recipe << " " << Recipe[default_recipe].name << '\n'; //? 2
 //?   cout << "AAA " << x.to_string() << '\n'; //? 1
   if (!has_property(x, "space")) {
@@ -83,7 +83,7 @@ index_t lookup_name(const reagent& x, const recipe_number default_recipe) {
     return Name[default_recipe][x.name];
   }
   vector<string> p = property(x, "space");
-  if (p.size() != 1) raise << "/space property should have exactly one (non-negative integer) value\n";
+  if (SIZE(p) != 1) raise << "/space property should have exactly one (non-negative integer) value\n";
   long long int n = to_integer(p.at(0));
   assert(n >= 0);
   recipe_number surrounding_recipe = lookup_surrounding_recipe(default_recipe, n);
@@ -94,14 +94,14 @@ index_t lookup_name(const reagent& x, const recipe_number default_recipe) {
 
 // If the recipe we need to lookup this name in doesn't have names done yet,
 // recursively call transform_names on it.
-index_t lookup_name(const reagent& x, const recipe_number r, set<recipe_number>& done, vector<recipe_number>& path) {
+long long int lookup_name(const reagent& x, const recipe_number r, set<recipe_number>& done, vector<recipe_number>& path) {
   if (!Name[r].empty()) return Name[r][x.name];
   if (done.find(r) != done.end()) {
     raise << "can't compute address of " << x.to_string() << " because ";
-    for (index_t i = 1; i < path.size(); ++i) {
+    for (long long int i = 1; i < SIZE(path); ++i) {
       raise << path.at(i-1) << " requires computing names of " << path.at(i) << '\n';
     }
-    raise << path.at(path.size()-1) << " requires computing names of " << r << "..ad infinitum\n" << die();
+    raise << path.at(SIZE(path)-1) << " requires computing names of " << r << "..ad infinitum\n" << die();
     return 0;
   }
   done.insert(r);
@@ -111,7 +111,7 @@ index_t lookup_name(const reagent& x, const recipe_number r, set<recipe_number>&
   return Name[r][x.name];
 }
 
-recipe_number lookup_surrounding_recipe(const recipe_number r, index_t n) {
+recipe_number lookup_surrounding_recipe(const recipe_number r, long long int n) {
   if (n == 0) return r;
   if (Surrounding_space.find(r) == Surrounding_space.end()) {
     raise << "don't know surrounding recipe of " << Recipe[r].name << '\n';
@@ -122,11 +122,11 @@ recipe_number lookup_surrounding_recipe(const recipe_number r, index_t n) {
 }
 
 //: weaken use-before-set warnings just a tad
-:(replace{} "bool already_transformed(const reagent& r, const map<string, index_t>& names)")
-bool already_transformed(const reagent& r, const map<string, index_t>& names) {
+:(replace{} "bool already_transformed(const reagent& r, const map<string, long long int>& names)")
+bool already_transformed(const reagent& r, const map<string, long long int>& names) {
   if (has_property(r, "space")) {
     vector<string> p = property(r, "space");
-    assert(p.size() == 1);
+    assert(SIZE(p) == 1);
     if (p.at(0) != "0") return true;
   }
   return names.find(r.name) != names.end();
diff --git a/046tangle.cc b/046tangle.cc
index d77eecf1..2b650e3d 100644
--- a/046tangle.cc
+++ b/046tangle.cc
@@ -48,7 +48,7 @@ void insert_fragments(const recipe_number r) {
   // Copy into a new vector because insertions invalidate iterators.
   // But this way we can't insert into labels created inside before/after.
   vector<instruction> result;
-  for (index_t i = 0; i < Recipe[r].steps.size(); ++i) {
+  for (long long int i = 0; i < SIZE(Recipe[r].steps); ++i) {
     const instruction inst = Recipe[r].steps.at(i);
     if (!inst.is_label) {
       result.push_back(inst);
@@ -62,7 +62,7 @@ void insert_fragments(const recipe_number r) {
       result.insert(result.end(), After_fragments[inst.label].steps.begin(), After_fragments[inst.label].steps.end());
     }
   }
-//?   for (index_t i = 0; i < result.size(); ++i) { //? 1
+//?   for (long long int i = 0; i < SIZE(result); ++i) { //? 1
 //?     cout << result.at(i).to_string() << '\n'; //? 1
 //?   } //? 1
   Recipe[r].steps.swap(result);
diff --git a/047jump_label.cc b/047jump_label.cc
index 81a9d123..4ec31341 100644
--- a/047jump_label.cc
+++ b/047jump_label.cc
@@ -18,12 +18,12 @@ Type_number["label"] = 0;
 
 :(code)
 void transform_labels(const recipe_number r) {
-  map<string, index_t> offset;
-  for (index_t i = 0; i < Recipe[r].steps.size(); ++i) {
+  map<string, long long int> offset;
+  for (long long int i = 0; i < SIZE(Recipe[r].steps); ++i) {
     const instruction& inst = Recipe[r].steps.at(i);
     if (!inst.label.empty()) offset[inst.label] = i;
   }
-  for (index_t i = 0; i < Recipe[r].steps.size(); ++i) {
+  for (long long int i = 0; i < SIZE(Recipe[r].steps); ++i) {
     instruction& inst = Recipe[r].steps.at(i);
     if (inst.operation == Recipe_number["jump"]) {
 //?       cerr << inst.to_string() << '\n'; //? 1
@@ -33,19 +33,19 @@ void transform_labels(const recipe_number r) {
       replace_offset(inst.ingredients.at(1), offset, i, r);
     }
     if ((inst.operation == Recipe_number["loop"] || inst.operation == Recipe_number["break"])
-        && inst.ingredients.size() == 1) {
+        && SIZE(inst.ingredients) == 1) {
       replace_offset(inst.ingredients.at(0), offset, i, r);
     }
     if ((inst.operation == Recipe_number["loop-if"] || inst.operation == Recipe_number["loop-unless"]
             || inst.operation == Recipe_number["break-if"] || inst.operation == Recipe_number["break-unless"])
-        && inst.ingredients.size() == 2) {
+        && SIZE(inst.ingredients) == 2) {
       replace_offset(inst.ingredients.at(1), offset, i, r);
     }
   }
 }
 
 :(code)
-void replace_offset(reagent& x, /*const*/ map<string, index_t>& offset, const index_t current_offset, const recipe_number r) {
+void replace_offset(reagent& x, /*const*/ map<string, long long int>& offset, const long long int current_offset, const recipe_number r) {
 //?   cerr << "AAA " << x.to_string() << '\n'; //? 1
   assert(isa_literal(x));
 //?   cerr << "BBB " << x.to_string() << '\n'; //? 1
diff --git a/048continuation.cc b/048continuation.cc
index 80c9293d..87cf12e3 100644
--- a/048continuation.cc
+++ b/048continuation.cc
@@ -7,8 +7,8 @@
 
 //: todo: implement continuations in mu's memory
 :(before "End Globals")
-map<index_t, call_stack> Continuation;
-index_t Next_continuation_id = 0;
+map<long long int, call_stack> Continuation;
+long long int Next_continuation_id = 0;
 :(before "End Setup")
 Continuation.clear();
 Next_continuation_id = 0;
@@ -36,8 +36,8 @@ CONTINUE_FROM,
 Recipe_number["continue-from"] = CONTINUE_FROM;
 :(before "End Primitive Recipe Implementations")
 case CONTINUE_FROM: {
-  assert(ingredients.at(0).size() == 1);  // scalar
-  index_t c = ingredients.at(0).at(0);
+  assert(scalar(ingredients.at(0)));
+  long long int c = ingredients.at(0).at(0);
   Current_routine->calls = Continuation[c];  // deep copy because calls have no pointers
   // refresh instruction_counter to next instruction after current-continuation
   instruction_counter = current_step_index()+1;
diff --git a/050scenario.cc b/050scenario.cc
index b43aea57..ee6485a9 100644
--- a/050scenario.cc
+++ b/050scenario.cc
@@ -86,7 +86,7 @@ scenario parse_scenario(istream& in) {
 :(before "End Tests")
 time_t mu_time; time(&mu_time);
 cerr << "\nMu tests: " << ctime(&mu_time);
-for (index_t i = 0; i < Scenarios.size(); ++i) {
+for (long long int i = 0; i < SIZE(Scenarios); ++i) {
 //?   cerr << Passed << '\n'; //? 1
 //?   cerr << i << ": " << Scenarios.at(i).name << '\n'; //? 3
   run_mu_scenario(Scenarios.at(i));
@@ -96,7 +96,7 @@ for (index_t i = 0; i < Scenarios.size(); ++i) {
 //: Convenience: run a single named scenario.
 :(before "Loading Commandline Files")
 if (argc == 2 && Run_tests) {
-  for (index_t i = 0; i < Scenarios.size(); ++i) {
+  for (long long int i = 0; i < SIZE(Scenarios); ++i) {
     if (Scenarios.at(i).name == argv[1]) {
       run_mu_scenario(Scenarios.at(i));
       return 0;
@@ -202,7 +202,7 @@ case MEMORY_SHOULD_CONTAIN: {
 void check_memory(const string& s) {
   istringstream in(s);
   in >> std::noskipws;
-  set<index_t> locations_checked;
+  set<long long int> locations_checked;
   while (true) {
     skip_whitespace_and_comments(in);
     if (in.eof()) break;
@@ -240,7 +240,7 @@ void check_type(const string& lhs, istream& in) {
     assert(_assign == "<-");
     skip_whitespace_and_comments(in);
     string literal = next_word(in);
-    index_t address = x.value;
+    long long int address = x.value;
     // exclude quoting brackets
     assert(*literal.begin() == '[');  literal.erase(literal.begin());
     assert(*--literal.end() == ']');  literal.erase(--literal.end());
@@ -250,12 +250,12 @@ void check_type(const string& lhs, istream& in) {
   raise << "don't know how to check memory for " << lhs << '\n';
 }
 
-void check_string(index_t address, const string& literal) {
+void check_string(long long int address, const string& literal) {
   trace("run") << "checking string length at " << address;
-  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';
+  if (Memory[address] != SIZE(literal))
+    raise << "expected location " << address << " to contain length " << SIZE(literal) << " of string [" << literal << "] but saw " << Memory[address] << '\n';
   ++address;  // now skip length
-  for (index_t i = 0; i < literal.size(); ++i) {
+  for (long long int i = 0; i < SIZE(literal); ++i) {
     trace("run") << "checking location " << address+i;
     if (Memory[address+i] != literal.at(i))
       raise << "expected location " << (address+i) << " to contain " << literal.at(i) << " but saw " << Memory[address+i] << '\n';
@@ -337,15 +337,15 @@ bool check_trace(const string& expected) {
 //?   cerr << "AAA " << expected << '\n'; //? 1
   Trace_stream->newline();
   vector<pair<string, string> > expected_lines = parse_trace(expected);
-//?   cerr << "BBB " << expected_lines.size() << '\n'; //? 1
+//?   cerr << "BBB " << SIZE(expected_lines) << '\n'; //? 1
   if (expected_lines.empty()) return true;
-  index_t curr_expected_line = 0;
+  long long int curr_expected_line = 0;
   for (vector<pair<string, pair<int, string> > >::iterator p = Trace_stream->past_lines.begin(); p != Trace_stream->past_lines.end(); ++p) {
     if (expected_lines.at(curr_expected_line).first != p->first) continue;
     if (expected_lines.at(curr_expected_line).second != p->second.second) continue;
     // match
     ++curr_expected_line;
-    if (curr_expected_line == expected_lines.size()) {
+    if (curr_expected_line == SIZE(expected_lines)) {
 //?       cerr << "ZZZ\n"; //? 1
       return true;
     }
@@ -360,10 +360,10 @@ bool check_trace(const string& expected) {
 vector<pair<string, string> > parse_trace(const string& expected) {
   vector<string> buf = split(expected, "\n");
   vector<pair<string, string> > result;
-  for (index_t i = 0; i < buf.size(); ++i) {
+  for (long long int i = 0; i < SIZE(buf); ++i) {
     buf.at(i) = trim(buf.at(i));
     if (buf.at(i).empty()) continue;
-    index_t delim = buf.at(i).find(": ");
+    long long int delim = buf.at(i).find(": ");
     result.push_back(pair<string, string>(buf.at(i).substr(0, delim), buf.at(i).substr(delim+2)));
   }
   return result;
@@ -426,7 +426,7 @@ case TRACE_SHOULD_NOT_CONTAIN: {
 bool check_trace_missing(const string& in) {
   Trace_stream->newline();
   vector<pair<string, string> > lines = parse_trace(in);
-  for (index_t i = 0; i < lines.size(); ++i) {
+  for (long long int i = 0; i < SIZE(lines); ++i) {
     if (trace_count(lines.at(i).first, lines.at(i).second) != 0) {
       raise << "unexpected [" << lines.at(i).second << "] in trace layer " << lines.at(i).first << '\n';
       Passed = false;
diff --git a/070display.cc b/070display.cc
index b93731ab..2a2c51a7 100644
--- a/070display.cc
+++ b/070display.cc
@@ -7,7 +7,7 @@
 //:: Display management
 
 :(before "End Globals")
-index_t Display_row = 0, Display_column = 0;
+long long int Display_row = 0, Display_column = 0;
 
 :(before "End Primitive Recipe Declarations")
 SWITCH_TO_DISPLAY,
@@ -51,8 +51,8 @@ CLEAR_LINE_ON_DISPLAY,
 Recipe_number["clear-line-on-display"] = CLEAR_LINE_ON_DISPLAY;
 :(before "End Primitive Recipe Implementations")
 case CLEAR_LINE_ON_DISPLAY: {
-  size_t width = tb_width();
-  for (index_t x = Display_column; x < width; ++x) {
+  long long int width = tb_width();
+  for (long long int x = Display_column; x < width; ++x) {
     tb_change_cell(x, Display_row, ' ', TB_WHITE, TB_DEFAULT);
   }
   tb_set_cursor(Display_column, Display_row);
@@ -67,9 +67,9 @@ Recipe_number["print-character-to-display"] = PRINT_CHARACTER_TO_DISPLAY;
 :(before "End Primitive Recipe Implementations")
 case PRINT_CHARACTER_TO_DISPLAY: {
   int h=tb_height(), w=tb_width();
-  size_t height = (h >= 0) ? h : 0;
-  size_t width = (w >= 0) ? w : 0;
-  assert(ingredients.at(0).size() == 1);  // scalar
+  long long int height = (h >= 0) ? h : 0;
+  long long int width = (w >= 0) ? w : 0;
+  assert(scalar(ingredients.at(0)));
   long long int c = ingredients.at(0).at(0);
   if (c == '\n' || c == '\r') {
     if (Display_row < height-1) {
@@ -116,9 +116,9 @@ MOVE_CURSOR_ON_DISPLAY,
 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
+  assert(scalar(ingredients.at(0)));
   Display_row = ingredients.at(0).at(0);
-  assert(ingredients.at(1).size() == 1);  // scalar
+  assert(scalar(ingredients.at(1)));
   Display_column = ingredients.at(1).at(0);
   tb_set_cursor(Display_column, Display_row);
   tb_present();
@@ -132,7 +132,7 @@ Recipe_number["move-cursor-down-on-display"] = MOVE_CURSOR_DOWN_ON_DISPLAY;
 :(before "End Primitive Recipe Implementations")
 case MOVE_CURSOR_DOWN_ON_DISPLAY: {
   int h=tb_height();
-  size_t height = (h >= 0) ? h : 0;
+  long long int height = (h >= 0) ? h : 0;
   if (Display_row < height-1) {
     Display_row++;
     tb_set_cursor(Display_column, Display_row);
@@ -162,7 +162,7 @@ Recipe_number["move-cursor-right-on-display"] = MOVE_CURSOR_RIGHT_ON_DISPLAY;
 :(before "End Primitive Recipe Implementations")
 case MOVE_CURSOR_RIGHT_ON_DISPLAY: {
   int w=tb_width();
-  size_t width = (w >= 0) ? w : 0;
+  long long int width = (w >= 0) ? w : 0;
   if (Display_column < width-1) {
     Display_column++;
     tb_set_cursor(Display_column, Display_row);
diff --git a/072scenario_screen.cc b/072scenario_screen.cc
index 4f2cfd0a..72b9bad3 100644
--- a/072scenario_screen.cc
+++ b/072scenario_screen.cc
@@ -41,8 +41,8 @@ scenario screen-in-scenario-error [
 // Scenarios may not define default-space, so they should fit within the
 // initial area of memory reserved for tests. We'll put the predefined
 // variables available to them at the end of that region.
-const size_t Max_variables_in_scenarios = Reserved_for_tests-100;
-size_t Next_predefined_global_for_scenarios = Max_variables_in_scenarios;
+const long long int Max_variables_in_scenarios = Reserved_for_tests-100;
+long long int Next_predefined_global_for_scenarios = Max_variables_in_scenarios;
 :(before "End Setup")
 assert(Next_predefined_global_for_scenarios < Reserved_for_tests);
 :(after "transform_all()" following "case RUN:")
@@ -53,7 +53,7 @@ assert(Name[tmp_recipe.at(0)][""] < Max_variables_in_scenarios);
 
 :(before "End Globals")
 // Scenario Globals.
-const size_t SCREEN = Next_predefined_global_for_scenarios++;
+const long long int SCREEN = Next_predefined_global_for_scenarios++;
 // End Scenario Globals.
 :(before "End Predefined Scenario Locals In Run")
 Name[tmp_recipe.at(0)]["screen"] = SCREEN;
@@ -87,23 +87,23 @@ case SCREEN_SHOULD_CONTAIN: {
 void check_screen(const string& contents) {
 //?   cerr << "Checking screen\n"; //? 1
   assert(!Current_routine->calls.front().default_space);  // not supported
-  index_t screen_location = Memory[SCREEN];
+  long long int 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 = Memory[screen_data_location];  // type: array:character
+  long long int screen_data_location = screen_location+data_offset;  // type: address:array:character
+  long long int 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 = Memory[screen_location+width_offset];
+  long long int screen_width = Memory[screen_location+width_offset];
   int height_offset = find_element_name(Type_number["screen"], "num-rows");
-  size_t screen_height = Memory[screen_location+height_offset];
+  long long int screen_height = Memory[screen_location+height_offset];
   string expected_contents;
   istringstream in(contents);
   in >> std::noskipws;
-  for (index_t row = 0; row < screen_height; ++row) {
+  for (long long int row = 0; row < screen_height; ++row) {
     skip_whitespace_and_comments(in);
     assert(!in.eof());
     assert(in.get() == '.');
-    for (index_t column = 0; column < screen_width; ++column) {
+    for (long long int column = 0; column < screen_width; ++column) {
       assert(!in.eof());
       expected_contents += in.get();
     }
@@ -112,11 +112,11 @@ void check_screen(const string& contents) {
   skip_whitespace_and_comments(in);
 //?   assert(in.get() == ']');
   trace("run") << "checking screen size at " << screen_data_start;
-//?   cout << expected_contents.size() << '\n'; //? 1
-  if (Memory[screen_data_start] > static_cast<signed>(expected_contents.size()))
+//?   cout << SIZE(expected_contents) << '\n'; //? 1
+  if (Memory[screen_data_start] > SIZE(expected_contents))
     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) {
+  for (long long int i = 0; i < SIZE(expected_contents); ++i) {
     trace("run") << "checking location " << screen_data_start+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
@@ -153,21 +153,21 @@ case _DUMP_SCREEN: {
 :(code)
 void dump_screen() {
   assert(!Current_routine->calls.front().default_space);  // not supported
-  index_t screen_location = Memory[SCREEN];
+  long long int screen_location = Memory[SCREEN];
   int width_offset = find_element_name(Type_number["screen"], "num-columns");
-  size_t screen_width = Memory[screen_location+width_offset];
+  long long int screen_width = Memory[screen_location+width_offset];
   int height_offset = find_element_name(Type_number["screen"], "num-rows");
-  size_t screen_height = Memory[screen_location+height_offset];
+  long long int screen_height = Memory[screen_location+height_offset];
   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 = Memory[screen_data_location];  // type: array:character
+  long long int screen_data_location = screen_location+data_offset;  // type: address:array:character
+  long long int screen_data_start = Memory[screen_data_location];  // type: array:character
 //?   cerr << "data start: " << screen_data_start << '\n'; //? 1
   assert(Memory[screen_data_start] == screen_width*screen_height);
-  index_t curr = screen_data_start+1;  // skip length
-  for (index_t row = 0; row < screen_height; ++row) {
+  long long int curr = screen_data_start+1;  // skip length
+  for (long long int row = 0; row < screen_height; ++row) {
 //?     cerr << curr << ":\n"; //? 1
-    for (index_t col = 0; col < screen_width; ++col) {
+    for (long long int col = 0; col < screen_width; ++col) {
       cerr << static_cast<char>(Memory[curr]);
       ++curr;
     }
diff --git a/075scenario_keyboard.cc b/075scenario_keyboard.cc
index 039f10c8..ceea12c9 100644
--- a/075scenario_keyboard.cc
+++ b/075scenario_keyboard.cc
@@ -26,7 +26,7 @@ scenario keyboard-in-scenario [
 ]
 
 :(before "End Scenario Globals")
-const size_t KEYBOARD = Next_predefined_global_for_scenarios++;
+const long long int KEYBOARD = Next_predefined_global_for_scenarios++;
 :(before "End Predefined Scenario Locals In Run")
 Name[tmp_recipe.at(0)]["keyboard"] = KEYBOARD;