From 204dae921abff0c70e017215bb3c91fa6ca11aff Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Mon, 26 Dec 2016 11:44:14 -0800 Subject: 3710 Turns out we don't need to explicitly add anchors for each line. Vim's TOhtml has magic for that out of the box. --- html/045closure_name.cc.html | 334 +++++++++++++++++++++---------------------- 1 file changed, 167 insertions(+), 167 deletions(-) (limited to 'html/045closure_name.cc.html') diff --git a/html/045closure_name.cc.html b/html/045closure_name.cc.html index 8613f1da..c2a4cac8 100644 --- a/html/045closure_name.cc.html +++ b/html/045closure_name.cc.html @@ -57,173 +57,173 @@ if ('onhashchange' in window) {
-  1 //: Writing to a literal (not computed) address of 0 in a recipe chains two
-  2 //: spaces together. When a variable has a property of /space:1, it looks up
-  3 //: the variable in the chained/surrounding space. /space:2 looks up the
-  4 //: surrounding space of the surrounding space, etc.
-  5 
-  6 :(scenario closure)
-  7 def main [
-  8   default-space:space <- new location:type, 30
-  9   1:space/names:new-counter <- new-counter
- 10   2:num/raw <- increment-counter 1:space/names:new-counter
- 11   3:num/raw <- increment-counter 1:space/names:new-counter
- 12 ]
- 13 def new-counter [
- 14   default-space:space <- new location:type, 30
- 15   x:num <- copy 23
- 16   y:num <- copy 3  # variable that will be incremented
- 17   return default-space:space
- 18 ]
- 19 def increment-counter [
- 20   default-space:space <- new location:type, 30
- 21   0:space/names:new-counter <- next-ingredient  # outer space must be created by 'new-counter' above
- 22   y:num/space:1 <- add y:num/space:1, 1  # increment
- 23   y:num <- copy 234  # dummy
- 24   return y:num/space:1
- 25 ]
- 26 +name: lexically surrounding space for recipe increment-counter comes from new-counter
- 27 +mem: storing 5 in location 3
- 28 
- 29 //: To make this work, compute the recipe that provides names for the
- 30 //: surrounding space of each recipe.
- 31 
- 32 :(before "End Globals")
- 33 map<recipe_ordinal, recipe_ordinal> Surrounding_space;
- 34 
- 35 :(before "Transform.push_back(transform_names)")
- 36 Transform.push_back(collect_surrounding_spaces);  // idempotent
- 37 
- 38 :(code)
- 39 void collect_surrounding_spaces(const recipe_ordinal r) {
- 40   trace(9991, "transform") << "--- collect surrounding spaces for recipe " << get(Recipe, r).name << end();
- 41   for (int i = 0;  i < SIZE(get(Recipe, r).steps);  ++i) {
- 42     const instruction& inst = get(Recipe, r).steps.at(i);
- 43     if (inst.is_label) continue;
- 44     for (int j = 0;  j < SIZE(inst.products);  ++j) {
- 45       if (is_literal(inst.products.at(j))) continue;
- 46       if (inst.products.at(j).name != "0") continue;
- 47       if (!is_space(inst.products.at(j))) {
- 48         raise << "slot 0 should always have type address:array:location, but is '" << to_string(inst.products.at(j)) << "'\n" << end();
- 49         continue;
- 50       }
- 51       string_tree* s = property(inst.products.at(j), "names");
- 52       if (!s) {
- 53         raise << "slot 0 requires a /names property in recipe '" << get(Recipe, r).name << "'\n" << end();
- 54         continue;
- 55       }
- 56       if (!s->atom) raise << "slot 0 should have a single value in /names, but got '" << to_string(inst.products.at(j)) << "'\n" << end();
- 57       const string& surrounding_recipe_name = s->value;
- 58       if (surrounding_recipe_name.empty()) {
- 59         raise << "slot 0 doesn't initialize its /names property in recipe '" << get(Recipe, r).name << "'\n" << end();
- 60         continue;
- 61       }
- 62       if (contains_key(Surrounding_space, r)
- 63           && get(Surrounding_space, r) != get(Recipe_ordinal, surrounding_recipe_name)) {
- 64         raise << "recipe '" << get(Recipe, r).name << "' can have only one 'surrounding' recipe but has '" << get(Recipe, get(Surrounding_space, r)).name << "' and '" << surrounding_recipe_name << "'\n" << end();
- 65         continue;
- 66       }
- 67       trace(9993, "name") << "lexically surrounding space for recipe " << get(Recipe, r).name << " comes from " << surrounding_recipe_name << end();
- 68       if (!contains_key(Recipe_ordinal, surrounding_recipe_name)) {
- 69         raise << "can't find recipe providing surrounding space for '" << get(Recipe, r).name << "'; looking for '" << surrounding_recipe_name << "'\n" << end();
- 70         continue;
- 71       }
- 72       put(Surrounding_space, r, get(Recipe_ordinal, surrounding_recipe_name));
- 73     }
- 74   }
- 75 }
- 76 
- 77 //: Once surrounding spaces are available, transform_names uses them to handle
- 78 //: /space properties.
- 79 
- 80 :(replace{} "int lookup_name(const reagent& r, const recipe_ordinal default_recipe)")
- 81 int lookup_name(const reagent& x, const recipe_ordinal default_recipe) {
- 82   if (!has_property(x, "space")) {
- 83     if (Name[default_recipe].empty()) raise << "name not found: " << x.name << '\n' << end();
- 84     return Name[default_recipe][x.name];
- 85   }
- 86   string_tree* p = property(x, "space");
- 87   if (!p || !p->atom) raise << "/space property should have exactly one (non-negative integer) value\n" << end();
- 88   int n = to_integer(p->value);
- 89   assert(n >= 0);
- 90   recipe_ordinal surrounding_recipe = lookup_surrounding_recipe(default_recipe, n);
- 91   if (surrounding_recipe == -1) return -1;
- 92   set<recipe_ordinal> done;
- 93   vector<recipe_ordinal> path;
- 94   return lookup_name(x, surrounding_recipe, done, path);
- 95 }
- 96 
- 97 // If the recipe we need to lookup this name in doesn't have names done yet,
- 98 // recursively call transform_names on it.
- 99 int lookup_name(const reagent& x, const recipe_ordinal r, set<recipe_ordinal>& done, vector<recipe_ordinal>& path) {
-100   if (!Name[r].empty()) return Name[r][x.name];
-101   if (contains_key(done, r)) {
-102     raise << "can't compute address of '" << to_string(x) << "' because\n" << end();
-103     for (int i = 1;  i < SIZE(path);  ++i) {
-104       raise << path.at(i-1) << " requires computing names of " << path.at(i) << '\n' << end();
-105     }
-106     raise << path.at(SIZE(path)-1) << " requires computing names of " << r << "..ad infinitum\n" << end();
-107     return -1;
-108   }
-109   done.insert(r);
-110   path.push_back(r);
-111   transform_names(r);  // Not passing 'done' through. Might this somehow cause an infinite loop?
-112   assert(!Name[r].empty());
-113   return Name[r][x.name];
-114 }
-115 
-116 recipe_ordinal lookup_surrounding_recipe(const recipe_ordinal r, int n) {
-117   if (n == 0) return r;
-118   if (!contains_key(Surrounding_space, r)) {
-119     raise << "don't know surrounding recipe of '" << get(Recipe, r).name << "'\n" << end();
-120     return -1;
-121   }
-122   assert(contains_key(Surrounding_space, r));
-123   return lookup_surrounding_recipe(get(Surrounding_space, r), n-1);
-124 }
-125 
-126 //: weaken use-before-set detection just a tad
-127 :(replace{} "bool already_transformed(const reagent& r, const map<string, int>& names)")
-128 bool already_transformed(const reagent& r, const map<string, int>& names) {
-129   if (has_property(r, "space")) {
-130     string_tree* p = property(r, "space");
-131     if (!p || !p->atom) {
-132       raise << "/space property should have exactly one (non-negative integer) value in '" << r.original_string << "'\n" << end();
-133       return false;
-134     }
-135     if (p->value != "0") return true;
-136   }
-137   return contains_key(names, r.name);
-138 }
-139 
-140 :(scenario missing_surrounding_space)
-141 % Hide_errors = true;
-142 def f [
-143   local-scope
-144   x:num/space:1 <- copy 34
-145 ]
-146 +error: don't know surrounding recipe of 'f'
-147 +error: f: can't find a place to store 'x'
-148 
-149 //: extra test for try_reclaim_locals() from previous layers
-150 :(scenario local_scope_ignores_nonlocal_spaces)
-151 def new-scope [
-152   new-default-space
-153   x:&:num <- new number:type
-154   *x:&:num <- copy 34
-155   return default-space:space
-156 ]
-157 def use-scope [
-158   local-scope
-159   outer:space <- next-ingredient
-160   0:space/names:new-scope <- copy outer:space
-161   return *x:&:num/space:1
-162 ]
-163 def main [
-164   1:space/raw <- new-scope
-165   2:num/raw <- use-scope 1:space/raw
-166 ]
-167 +mem: storing 34 in location 2
+  1 //: Writing to a literal (not computed) address of 0 in a recipe chains two
+  2 //: spaces together. When a variable has a property of /space:1, it looks up
+  3 //: the variable in the chained/surrounding space. /space:2 looks up the
+  4 //: surrounding space of the surrounding space, etc.
+  5 
+  6 :(scenario closure)
+  7 def main [
+  8   default-space:space <- new location:type, 30
+  9   1:space/names:new-counter <- new-counter
+ 10   2:num/raw <- increment-counter 1:space/names:new-counter
+ 11   3:num/raw <- increment-counter 1:space/names:new-counter
+ 12 ]
+ 13 def new-counter [
+ 14   default-space:space <- new location:type, 30
+ 15   x:num <- copy 23
+ 16   y:num <- copy 3  # variable that will be incremented
+ 17   return default-space:space
+ 18 ]
+ 19 def increment-counter [
+ 20   default-space:space <- new location:type, 30
+ 21   0:space/names:new-counter <- next-ingredient  # outer space must be created by 'new-counter' above
+ 22   y:num/space:1 <- add y:num/space:1, 1  # increment
+ 23   y:num <- copy 234  # dummy
+ 24   return y:num/space:1
+ 25 ]
+ 26 +name: lexically surrounding space for recipe increment-counter comes from new-counter
+ 27 +mem: storing 5 in location 3
+ 28 
+ 29 //: To make this work, compute the recipe that provides names for the
+ 30 //: surrounding space of each recipe.
+ 31 
+ 32 :(before "End Globals")
+ 33 map<recipe_ordinal, recipe_ordinal> Surrounding_space;
+ 34 
+ 35 :(before "Transform.push_back(transform_names)")
+ 36 Transform.push_back(collect_surrounding_spaces);  // idempotent
+ 37 
+ 38 :(code)
+ 39 void collect_surrounding_spaces(const recipe_ordinal r) {
+ 40   trace(9991, "transform") << "--- collect surrounding spaces for recipe " << get(Recipe, r).name << end();
+ 41   for (int i = 0;  i < SIZE(get(Recipe, r).steps);  ++i) {
+ 42     const instruction& inst = get(Recipe, r).steps.at(i);
+ 43     if (inst.is_label) continue;
+ 44     for (int j = 0;  j < SIZE(inst.products);  ++j) {
+ 45       if (is_literal(inst.products.at(j))) continue;
+ 46       if (inst.products.at(j).name != "0") continue;
+ 47       if (!is_space(inst.products.at(j))) {
+ 48         raise << "slot 0 should always have type address:array:location, but is '" << to_string(inst.products.at(j)) << "'\n" << end();
+ 49         continue;
+ 50       }
+ 51       string_tree* s = property(inst.products.at(j), "names");
+ 52       if (!s) {
+ 53         raise << "slot 0 requires a /names property in recipe '" << get(Recipe, r).name << "'\n" << end();
+ 54         continue;
+ 55       }
+ 56       if (!s->atom) raise << "slot 0 should have a single value in /names, but got '" << to_string(inst.products.at(j)) << "'\n" << end();
+ 57       const string& surrounding_recipe_name = s->value;
+ 58       if (surrounding_recipe_name.empty()) {
+ 59         raise << "slot 0 doesn't initialize its /names property in recipe '" << get(Recipe, r).name << "'\n" << end();
+ 60         continue;
+ 61       }
+ 62       if (contains_key(Surrounding_space, r)
+ 63           && get(Surrounding_space, r) != get(Recipe_ordinal, surrounding_recipe_name)) {
+ 64         raise << "recipe '" << get(Recipe, r).name << "' can have only one 'surrounding' recipe but has '" << get(Recipe, get(Surrounding_space, r)).name << "' and '" << surrounding_recipe_name << "'\n" << end();
+ 65         continue;
+ 66       }
+ 67       trace(9993, "name") << "lexically surrounding space for recipe " << get(Recipe, r).name << " comes from " << surrounding_recipe_name << end();
+ 68       if (!contains_key(Recipe_ordinal, surrounding_recipe_name)) {
+ 69         raise << "can't find recipe providing surrounding space for '" << get(Recipe, r).name << "'; looking for '" << surrounding_recipe_name << "'\n" << end();
+ 70         continue;
+ 71       }
+ 72       put(Surrounding_space, r, get(Recipe_ordinal, surrounding_recipe_name));
+ 73     }
+ 74   }
+ 75 }
+ 76 
+ 77 //: Once surrounding spaces are available, transform_names uses them to handle
+ 78 //: /space properties.
+ 79 
+ 80 :(replace{} "int lookup_name(const reagent& r, const recipe_ordinal default_recipe)")
+ 81 int lookup_name(const reagent& x, const recipe_ordinal default_recipe) {
+ 82   if (!has_property(x, "space")) {
+ 83     if (Name[default_recipe].empty()) raise << "name not found: " << x.name << '\n' << end();
+ 84     return Name[default_recipe][x.name];
+ 85   }
+ 86   string_tree* p = property(x, "space");
+ 87   if (!p || !p->atom) raise << "/space property should have exactly one (non-negative integer) value\n" << end();
+ 88   int n = to_integer(p->value);
+ 89   assert(n >= 0);
+ 90   recipe_ordinal surrounding_recipe = lookup_surrounding_recipe(default_recipe, n);
+ 91   if (surrounding_recipe == -1) return -1;
+ 92   set<recipe_ordinal> done;
+ 93   vector<recipe_ordinal> path;
+ 94   return lookup_name(x, surrounding_recipe, done, path);
+ 95 }
+ 96 
+ 97 // If the recipe we need to lookup this name in doesn't have names done yet,
+ 98 // recursively call transform_names on it.
+ 99 int lookup_name(const reagent& x, const recipe_ordinal r, set<recipe_ordinal>& done, vector<recipe_ordinal>& path) {
+100   if (!Name[r].empty()) return Name[r][x.name];
+101   if (contains_key(done, r)) {
+102     raise << "can't compute address of '" << to_string(x) << "' because\n" << end();
+103     for (int i = 1;  i < SIZE(path);  ++i) {
+104       raise << path.at(i-1) << " requires computing names of " << path.at(i) << '\n' << end();
+105     }
+106     raise << path.at(SIZE(path)-1) << " requires computing names of " << r << "..ad infinitum\n" << end();
+107     return -1;
+108   }
+109   done.insert(r);
+110   path.push_back(r);
+111   transform_names(r);  // Not passing 'done' through. Might this somehow cause an infinite loop?
+112   assert(!Name[r].empty());
+113   return Name[r][x.name];
+114 }
+115 
+116 recipe_ordinal lookup_surrounding_recipe(const recipe_ordinal r, int n) {
+117   if (n == 0) return r;
+118   if (!contains_key(Surrounding_space, r)) {
+119     raise << "don't know surrounding recipe of '" << get(Recipe, r).name << "'\n" << end();
+120     return -1;
+121   }
+122   assert(contains_key(Surrounding_space, r));
+123   return lookup_surrounding_recipe(get(Surrounding_space, r), n-1);
+124 }
+125 
+126 //: weaken use-before-set detection just a tad
+127 :(replace{} "bool already_transformed(const reagent& r, const map<string, int>& names)")
+128 bool already_transformed(const reagent& r, const map<string, int>& names) {
+129   if (has_property(r, "space")) {
+130     string_tree* p = property(r, "space");
+131     if (!p || !p->atom) {
+132       raise << "/space property should have exactly one (non-negative integer) value in '" << r.original_string << "'\n" << end();
+133       return false;
+134     }
+135     if (p->value != "0") return true;
+136   }
+137   return contains_key(names, r.name);
+138 }
+139 
+140 :(scenario missing_surrounding_space)
+141 % Hide_errors = true;
+142 def f [
+143   local-scope
+144   x:num/space:1 <- copy 34
+145 ]
+146 +error: don't know surrounding recipe of 'f'
+147 +error: f: can't find a place to store 'x'
+148 
+149 //: extra test for try_reclaim_locals() from previous layers
+150 :(scenario local_scope_ignores_nonlocal_spaces)
+151 def new-scope [
+152   new-default-space
+153   x:&:num <- new number:type
+154   *x:&:num <- copy 34
+155   return default-space:space
+156 ]
+157 def use-scope [
+158   local-scope
+159   outer:space <- next-ingredient
+160   0:space/names:new-scope <- copy outer:space
+161   return *x:&:num/space:1
+162 ]
+163 def main [
+164   1:space/raw <- new-scope
+165   2:num/raw <- use-scope 1:space/raw
+166 ]
+167 +mem: storing 34 in location 2
 
-- cgit 1.4.1-2-gfad0