about summary refs log tree commit diff stats
path: root/cpp
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-03-28 20:57:21 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-03-28 20:57:21 -0700
commit8f1db754005616054192b3f75e54af9929df26cc (patch)
tree9cef43e2279326f28c028c126349d929e345b8f5 /cpp
parent75845d2b1276214ce6c3cbc3504e49cb946d29f0 (diff)
downloadmu-8f1db754005616054192b3f75e54af9929df26cc.tar.gz
992 - c++ chain spaces for lexical scope
Diffstat (limited to 'cpp')
-rw-r--r--cpp/.traces/surrounding_space29
-rw-r--r--cpp/027space6
-rw-r--r--cpp/028space_surround42
3 files changed, 76 insertions, 1 deletions
diff --git a/cpp/.traces/surrounding_space b/cpp/.traces/surrounding_space
new file mode 100644
index 00000000..5297428b
--- /dev/null
+++ b/cpp/.traces/surrounding_space
@@ -0,0 +1,29 @@
+parse/0: instruction: 1
+parse/0:   ingredient: {name: "10", value: 0, type: 0, properties: [10: literal]}
+parse/0:   product: {name: "default-space", value: 0, type: 2-0, properties: [default-space: address:space]}
+parse/0: instruction: 1
+parse/0:   ingredient: {name: "20", value: 0, type: 0, properties: [20: literal]}
+parse/0:   product: {name: "0", value: 0, type: 2-0, properties: [0: address:space]}
+parse/0: instruction: 1
+parse/0:   ingredient: {name: "32", value: 0, type: 0, properties: [32: literal]}
+parse/0:   product: {name: "1", value: 0, type: 1, properties: [1: integer]}
+parse/0: instruction: 1
+parse/0:   ingredient: {name: "33", value: 0, type: 0, properties: [33: literal]}
+parse/0:   product: {name: "1", value: 0, type: 1, properties: [1: integer, space: 1]}
+name/0: assign default-space 1
+after-brace/0: recipe main
+after-brace/0: copy ...
+after-brace/0: copy ...
+after-brace/0: copy ...
+after-brace/0: copy ...
+run/0: instruction main/0
+run/0: ingredient 0 is 10
+run/0: instruction main/1
+run/0: ingredient 0 is 20
+mem/0: storing 20 in location 11
+run/0: instruction main/2
+run/0: ingredient 0 is 32
+mem/0: storing 32 in location 12
+run/0: instruction main/3
+run/0: ingredient 0 is 33
+mem/0: storing 33 in location 22
diff --git a/cpp/027space b/cpp/027space
index 2fa6f36d..0e1686f0 100644
--- a/cpp/027space
+++ b/cpp/027space
@@ -26,7 +26,7 @@ reagent absolutize(reagent x) {
 //?   cout << "not raw: " << x.to_string() << '\n'; //? 1
   assert(x.initialized);
   reagent r = x;
-  r.set_value(address(r.value, Current_routine.calls.top().default_space));
+  r.set_value(address(r.value, space(r)));
 //?   cout << "after absolutize: " << r.value << '\n'; //? 1
   if (r.properties.empty())
     r.properties.push_back(pair<string, vector<string> >("", vector<string>()));
@@ -35,6 +35,10 @@ reagent absolutize(reagent x) {
   return r;
 }
 
+int space(const reagent& x) {
+  return Current_routine.calls.top().default_space;
+}
+
 int address(int offset, int base) {
   if (base == 0) return offset;  // raw
   return base+offset+1;
diff --git a/cpp/028space_surround b/cpp/028space_surround
new file mode 100644
index 00000000..9899ed89
--- /dev/null
+++ b/cpp/028space_surround
@@ -0,0 +1,42 @@
+//: So far you can have global variables by not setting default-space, and
+//: local variables by setting default-space. You can isolate variables
+//: between those extremes by creating 'surrounding' spaces.
+//:
+//: (Surrounding spaces are like lexical scopes in other languages.)
+
+:(scenario "surrounding_space")
+# location 1 in space 1 refers to the space surrounding the default space, here 20.
+recipe main [
+  default-space:address:space <- copy 10:literal
+  0:address:space <- copy 20:literal
+  1:integer <- copy 32:literal
+  1:integer/space:1 <- copy 33:literal
+]
++run: instruction main/1
++mem: storing 20 in location 11
++run: instruction main/2
++mem: storing 32 in location 12
++run: instruction main/3
++mem: storing 33 in location 22
+
+//: If you think of a space as a collection of variables with a common
+//: lifetime, surrounding allows managing shorter lifetimes inside a longer
+//: one.
+
+:(replace{} "int space(const reagent& x)")
+int space(const reagent& x) {
+  return space(x, space_index(x), Current_routine.calls.top().default_space);
+}
+
+int space(const reagent& x, int space_index, int base) {
+  if (space_index == 0) return base;
+  return space(x, space_index-1, Memory[base+1]);
+}
+
+int space_index(const reagent& x) {
+  for (size_t i = 0; i < x.properties.size(); ++i) {
+    if (x.properties[i].first == "space")
+      return to_int(x.properties[i].second[0]);
+  }
+  return 0;
+}