about summary refs log tree commit diff stats
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/.traces/set_default_space15
-rw-r--r--cpp/010vm1
-rw-r--r--cpp/012transform2
-rw-r--r--cpp/013run4
-rw-r--r--cpp/018record2
-rw-r--r--cpp/019address7
-rw-r--r--cpp/020array4
-rw-r--r--cpp/024brace18
-rw-r--r--cpp/025name13
-rw-r--r--cpp/026space42
10 files changed, 84 insertions, 24 deletions
diff --git a/cpp/.traces/set_default_space b/cpp/.traces/set_default_space
new file mode 100644
index 00000000..e4a963a5
--- /dev/null
+++ b/cpp/.traces/set_default_space
@@ -0,0 +1,15 @@
+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: "12", value: 0, type: 0, properties: [12: literal]}
+parse/0:   product: {name: "1", value: 0, type: 1, properties: [1: integer]}
+name/0: assign default-space 1
+after-brace/0: recipe main
+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 12
+mem/0: storing in location 11
diff --git a/cpp/010vm b/cpp/010vm
index d37dd83a..c7de25b0 100644
--- a/cpp/010vm
+++ b/cpp/010vm
@@ -45,6 +45,7 @@ struct reagent {
   vector<type_number> types;
   reagent(string s);
   reagent(type_number t);
+  void set_value(int v) { value = v; initialized = true; }
   string to_string();
 };
 
diff --git a/cpp/012transform b/cpp/012transform
index 21bcf60f..e9b74776 100644
--- a/cpp/012transform
+++ b/cpp/012transform
@@ -51,5 +51,5 @@ void populate_value(reagent& r) {
   int result = strtol(r.name.c_str(), &end, /*any base*/0);
   if (*end != '\0') return;
 //?   cout << "setting value\n"; //? 1
-  r.value = result;
+  r.set_value(result);
 }
diff --git a/cpp/013run b/cpp/013run
index 22239667..26436392 100644
--- a/cpp/013run
+++ b/cpp/013run
@@ -26,12 +26,16 @@ struct routine {
   routine(recipe_number r) :running_recipe(r), running_at(0) {}
 };
 
+:(before "End Globals")
+routine Current_routine(0);
+
 :(code)
 void run(recipe_number r) {
   run(routine(r));
 }
 
 void run(routine rr) {
+  Current_routine = rr;
   while (!done(rr)) {
     vector<instruction>& instructions = steps(rr);
     size_t& pc = running_at(rr);
diff --git a/cpp/018record b/cpp/018record
index 062f35cf..c19718cb 100644
--- a/cpp/018record
+++ b/cpp/018record
@@ -51,7 +51,7 @@ case GET: {
   int src_type = Type[base_type].elements[offset][0];
   trace("run") << "its type is " << src_type;
   reagent tmp(src_type);
-  tmp.value = src;
+  tmp.set_value(src);
   vector<int> result(read_memory(tmp));
   trace("run") << "product 0 is " << result[0];
   write_memory(instructions[pc].products[0], result);
diff --git a/cpp/019address b/cpp/019address
index 623d5aaa..9e9e1164 100644
--- a/cpp/019address
+++ b/cpp/019address
@@ -21,6 +21,7 @@ vector<int> read_memory(reagent x) {
   }
   x = canonize(x);
   int base = x.value;
+//?   cout << "base: " << base << '\n'; //? 1
   size_t size = size_of(x);
   for (size_t offset = 0; offset < size; ++offset) {
     int val = Memory[base+offset];
@@ -45,6 +46,7 @@ recipe main [
 void write_memory(reagent x, vector<int> data) {
   if (x.name == "_") return;  // dummy results are never stored
   x = canonize(x);
+//?   cout << x.to_string() << '\n'; //? 1
   int base = x.value;
   if (!Type[x.types[0]].is_array && size_of(x) != data.size())
     raise << "size mismatch in storing to " << x.to_string();
@@ -58,6 +60,7 @@ void write_memory(reagent x, vector<int> data) {
 reagent canonize(reagent x) {
 //?   cout << "canonize\n"; //? 1
   reagent r = x;
+//?   cout << x.to_string() << " => " << r.to_string() << '\n'; //? 1
   while (has_property(r, "deref"))
     r = deref(r);
   return r;
@@ -76,7 +79,7 @@ reagent deref(reagent x) {
   assert(x.types[0] == 2);  // address
 
   // compute value
-  result.value = Memory[x.value];
+  result.set_value(Memory[x.value]);
   trace("mem") << "location " << x.value << " is " << result.value;
 
   // populate types
@@ -142,7 +145,7 @@ case GET: {
   int src_type = Type[base_type].elements[offset][0];
   trace("run") << "its type is " << src_type;
   reagent tmp(src_type);
-  tmp.value = src;
+  tmp.set_value(src);
   tmp.types.push_back(src_type);
   vector<int> result(read_memory(tmp));
   trace("run") << "product 0 is " << result[0];
diff --git a/cpp/020array b/cpp/020array
index 457ed366..d5e0204c 100644
--- a/cpp/020array
+++ b/cpp/020array
@@ -33,7 +33,7 @@ if (t.is_array) {
   int base = r.value;
   if (Memory[base] == 0) return 0;
   reagent x(t.element[0]);
-  x.value = base+1;
+  x.set_value(base+1);
   return 1 + Memory[base]*size_of(x);
 }
 
@@ -58,7 +58,7 @@ case INDEX: {
   int src_type = Type[base_type].element[0];
   trace("run") << "its type is " << src_type;
   reagent tmp(src_type);
-  tmp.value = src;
+  tmp.set_value(src);
   vector<int> result(read_memory(tmp));
   trace("run") << "product 0 is " << result[0];
   write_memory(instructions[pc].products[0], result);
diff --git a/cpp/024brace b/cpp/024brace
index aa8c7a4c..f61fb6ac 100644
--- a/cpp/024brace
+++ b/cpp/024brace
@@ -66,8 +66,7 @@ void transform_braces(const recipe_number r) {
       }
       else {
         reagent ing(0);  // literal
-        ing.value = open_braces.top()-index;
-        ing.initialized = true;
+        ing.set_value(open_braces.top()-index);
         inst.ingredients.push_back(ing);
         trace("after-brace") << "jump " << ing.value << ":offset";
         trace("after-brace") << index << ": " << ing.to_string();
@@ -82,8 +81,7 @@ void transform_braces(const recipe_number r) {
       }
       else {
         reagent ing(0);  // literal
-        ing.value = matching_brace(open_braces.top(), braces) - index - 1;
-        ing.initialized = true;
+        ing.set_value(matching_brace(open_braces.top(), braces) - index - 1);
         inst.ingredients.push_back(ing);
         trace("after-brace") << "jump " << ing.value << ":offset";
       }
@@ -96,8 +94,7 @@ void transform_braces(const recipe_number r) {
       }
       else {
         reagent ing(0);  // literal
-        ing.value = open_braces.top()-index;
-        ing.initialized = true;
+        ing.set_value(open_braces.top()-index);
         inst.ingredients.push_back(ing);
         trace("after-brace") << "jump-if " << inst.ingredients[0].name << ", " << ing.value << ":offset";
       }
@@ -110,8 +107,7 @@ void transform_braces(const recipe_number r) {
       }
       else {
         reagent ing(0);  // literal
-        ing.value = matching_brace(open_braces.top(), braces) - index - 1;
-        ing.initialized = true;
+        ing.set_value(matching_brace(open_braces.top(), braces) - index - 1);
         inst.ingredients.push_back(ing);
         trace("after-brace") << "jump-if " << inst.ingredients[0].name << ", " << ing.value << ":offset";
       }
@@ -124,8 +120,7 @@ void transform_braces(const recipe_number r) {
       }
       else {
         reagent ing(0);  // literal
-        ing.value = open_braces.top()-index;
-        ing.initialized = true;
+        ing.set_value(open_braces.top()-index);
         inst.ingredients.push_back(ing);
         trace("after-brace") << "jump-unless " << inst.ingredients[0].name << ", " << ing.value << ":offset";
       }
@@ -138,8 +133,7 @@ void transform_braces(const recipe_number r) {
       }
       else {
         reagent ing(0);  // literal
-        ing.value = matching_brace(open_braces.top(), braces) - index - 1;
-        ing.initialized = true;
+        ing.set_value(matching_brace(open_braces.top(), braces) - index - 1);
         inst.ingredients.push_back(ing);
         trace("after-brace") << "jump-unless " << inst.ingredients[0].name << ", " << ing.value << ":offset";
       }
diff --git a/cpp/025name b/cpp/025name
index 7654907a..e943ddf3 100644
--- a/cpp/025name
+++ b/cpp/025name
@@ -38,14 +38,15 @@ void transform_names(const recipe_number r) {
       if (inst.ingredients[1].name.find_first_not_of("0123456789") == string::npos) continue;
       // since first non-address in base type must be a record, we don't have to canonize
       type_number record = skip_addresses(inst.ingredients[0].types);
-      inst.ingredients[1].value = find_element_name(record, inst.ingredients[1].name);
-      inst.ingredients[1].initialized = true;
+      inst.ingredients[1].set_value(find_element_name(record, inst.ingredients[1].name));
       trace("name") << "field " << inst.ingredients[1].name << " of type " << Type[record].name << " is at offset " << inst.ingredients[1].value;
     }
     // 2: map names to addresses if necessary
     for (size_t in = 0; in < inst.ingredients.size(); ++in) {
       if (is_raw(inst.ingredients[in])) continue;
 //?       cout << "ingredient " << inst.ingredients[in].name << '\n'; //? 1
+      if (inst.ingredients[in].name == "default_space")
+        inst.ingredients[in].initialized = true;
       if (inst.ingredients[in].name != "default_space"
           && inst.ingredients[in].types[0]
           && inst.ingredients[in].name.find_first_not_of("0123456789-.") != string::npos) {
@@ -53,14 +54,15 @@ void transform_names(const recipe_number r) {
           // todo: test
           cerr << "user before set: " << inst.ingredients[in].name << " in " << Recipe[r].name << '\n';
         }
-        inst.ingredients[in].value = names[inst.ingredients[in].name];
-        inst.ingredients[in].initialized = true;
+        inst.ingredients[in].set_value(names[inst.ingredients[in].name]);
       }
     }
     for (size_t out = 0; out < inst.products.size(); ++out) {
       if (is_raw(inst.products[out])) continue;
 //?       cout << "product " << out << '/' << inst.products.size() << " " << inst.products[out].name << '\n'; //? 3
 //?       cout << inst.products[out].types[0] << '\n'; //? 1
+      if (inst.products[out].name == "default_space")
+        inst.products[out].initialized = true;
       if (inst.products[out].name != "_"
           && inst.products[out].name != "default_space"
           && inst.products[out].types[0]
@@ -70,8 +72,7 @@ void transform_names(const recipe_number r) {
           names[inst.products[out].name] = curr_idx;
           curr_idx += size_of(inst.products[out]);
         }
-        inst.products[out].value = names[inst.products[out].name];
-        inst.products[out].initialized = true;
+        inst.products[out].set_value(names[inst.products[out].name]);
       }
     }
   }
diff --git a/cpp/026space b/cpp/026space
new file mode 100644
index 00000000..b3b2f001
--- /dev/null
+++ b/cpp/026space
@@ -0,0 +1,42 @@
+//: Spaces help isolate functions from each other. You can create them at will,
+//: and all addresses in arguments are implicitly based on the 'default-space'
+//: (unless they have the /raw property)
+
+:(scenarios run)
+:(scenario "set_default_space")
+recipe main [
+  default-space:address:space <- copy 10:literal
+  1:integer <- copy 12:literal
+]
++mem: storing in location 11
+
+:(before "End Call Fields")
+size_t default_space;
+:(replace "call(recipe_number r) :running_recipe(r)")
+call(recipe_number r) :running_recipe(r), pc(0), next_ingredient_to_process(0), default_space(0) {}
+
+:(replace "reagent r = x" following "reagent canonize(reagent x)")
+reagent r = absolutize(x);
+:(code)
+reagent absolutize(reagent x) {
+//?   cout << "absolutize " << x.to_string() << '\n'; //? 1
+  if (is_raw(x) || is_dummy(x)) return x;
+//?   cout << "not raw: " << x.to_string() << '\n'; //? 1
+  assert(x.initialized);
+  reagent r = x;
+  r.set_value(r.value + Current_routine.calls.top().default_space);
+//?   cout << "after absolutize: " << r.value << '\n'; //? 1
+  if (r.properties.empty())
+    r.properties.push_back(pair<string, vector<string> >("", vector<string>()));
+  r.properties.push_back(pair<string, vector<string> >("raw", vector<string>()));
+  assert(is_raw(r));
+  return r;
+}
+
+:(after "void write_memory(reagent x, vector<int> data)")
+  if (x.name == "default-space") {
+    assert(data.size() == 1);
+    Current_routine.calls.top().default_space = data[0];
+//?     cout << "AAA " << Current_routine.calls.top().default_space << '\n'; //? 1
+    return;
+  }