about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-07-13 17:20:56 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-07-13 17:20:56 -0700
commit385d3080066bc22d264b1ae30ee2505cab6cc202 (patch)
tree7bcba1addf558d70cc4b4605a253d7b12abd31fb
parentf59ccc4652bfdb7faf7d77a1685e795342e28fa2 (diff)
downloadmu-385d3080066bc22d264b1ae30ee2505cab6cc202.tar.gz
1769 - routines can now have global variables
-rw-r--r--044space.cc6
-rw-r--r--045space_surround.cc6
-rw-r--r--047global.cc54
3 files changed, 54 insertions, 12 deletions
diff --git a/044space.cc b/044space.cc
index e32fbceb..9a975147 100644
--- a/044space.cc
+++ b/044space.cc
@@ -49,17 +49,12 @@ default_space = 0;
 reagent r = absolutize(x);
 :(code)
 reagent absolutize(reagent x) {
-//?   if (Recipe_ordinal.find("increment-counter") != Recipe_ordinal.end()) //? 1
-//?     cout << "AAA " << "increment-counter/2: " << Recipe[Recipe_ordinal["increment-counter"]].steps.at(2).products.at(0).to_string() << '\n'; //? 1
 //?   cout << "absolutize " << x.to_string() << '\n'; //? 4
-//?   cout << is_raw(x) << '\n'; //? 1
   if (is_raw(x) || is_dummy(x)) return x;
-//?   cout << "not raw: " << x.to_string() << '\n'; //? 1
   if (!x.initialized)
     raise << current_instruction().to_string() << ": reagent not initialized: " << x.to_string() << die();
   reagent r = x;
   r.set_value(address(r.value, space_base(r)));
-//?   cout << "after absolutize: " << r.value << '\n'; //? 1
   r.properties.push_back(pair<string, vector<string> >("raw", vector<string>()));
   assert(is_raw(r));
   return r;
@@ -127,7 +122,6 @@ long long int address(long long int offset, long long int base) {
   if (x.name == "default-space") {
     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/045space_surround.cc b/045space_surround.cc
index 61521013..b90d464f 100644
--- a/045space_surround.cc
+++ b/045space_surround.cc
@@ -27,24 +27,18 @@ recipe main [
 
 :(replace{} "long long int space_base(const reagent& x)")
 long long int space_base(const reagent& x) {
-//?   cerr << "space_base: " << x.to_string() << '\n'; //? 1
   return space_base(x, space_index(x), Current_routine->calls.front().default_space);
 }
 
 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
-//?   cerr << "space_base sub: " << x.to_string() << '\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
   long long int result = space_base(x, space_index-1, Memory[base+1]);
   return result;
 }
 
 long long int space_index(const reagent& x) {
-//?   cerr << "space_index: " << x.to_string() << '\n'; //? 1
   for (long long int i = /*skip name:type*/1; i < SIZE(x.properties); ++i) {
     if (x.properties.at(i).first == "space") {
       assert(SIZE(x.properties.at(i).second) == 1);
diff --git a/047global.cc b/047global.cc
new file mode 100644
index 00000000..1ab77eec
--- /dev/null
+++ b/047global.cc
@@ -0,0 +1,54 @@
+// So far we have local variables, and we can nest local variables of short
+// lifetimes inside longer ones. Now let's support 'global' variables that
+// last for the life of a routine. If we create multiple routines they won't
+// have access to each other's globals.
+
+:(scenario global_space)
+recipe main [
+  # pretend arrays; in practice we'll use new
+  10:number <- copy 5:literal
+  20:number <- copy 5:literal
+  # actual start of this recipe
+  default-space:address:array:location <- copy 10:literal
+  1:number <- copy 23:literal
+  global-space:address:array:location <- copy 20:literal
+  1:number/space:global <- copy 24:literal
+]
++mem: storing 23 in location 12
++mem: storing 24 in location 22
+
+//: to support it, create another special variable called global space
+:(before "End Disqualified Reagents")
+if (x.name == "global-space")
+  x.initialized = true;
+:(before "End is_special_name Cases")
+if (s == "global-space") return true;
+
+//: writes to this variable go to a field in the current routine
+:(before "End routine Fields")
+long long int global_space;
+:(before "End routine Constructor")
+global_space = 0;
+:(after "void write_memory(reagent x, vector<double> data)")
+  if (x.name == "global-space") {
+    assert(scalar(data));
+    Current_routine->global_space = data.at(0);
+    return;
+  }
+
+//: now marking variables as /space:global looks them up inside this field
+:(after "long long int space_base(const reagent& x)")
+  if (is_global(x)) {
+    if (!Current_routine->global_space)
+      raise << "routine has no global space\n" << die();
+    return Current_routine->global_space;
+  }
+
+:(code)
+bool is_global(const reagent& x) {
+  for (long long int i = /*skip name:type*/1; i < SIZE(x.properties); ++i) {
+    if (x.properties.at(i).first == "space")
+      return x.properties.at(i).second.at(0) == "global";
+  }
+  return false;
+}