about summary refs log tree commit diff stats
Commit message (Collapse)AuthorAgeFilesLines
* drop an unnecessary level of indentKartik K. Agaram2022-07-201-23/+21
|
* clean up some printsKartik K. Agaram2022-07-201-17/+10
| | | | | (Looking at prints in Text.draw, Text.compute_fragments and Text.nearest_pos_less_than)
* move a var closer to its useKartik K. Agaram2022-07-201-2/+2
|
* more clearly skip prints before screen topKartik K. Agaram2022-07-201-21/+19
|
* unify two similar functionsKartik K. Agaram2022-07-192-24/+16
| | | | | | The cost is just having to tweak a few more brittle tests. I can't actually perceive any difference in how the cursor moves when I click on text.
* keep text from overflowing right marginKartik K. Agaram2022-07-192-41/+48
| | | | | | | | | | I've been sloppy about this so far, and outside of tests I can't find any examples where it matters, but it matters in a potential fork where I'm rendering multiple columns of text. It's unfortunate that my tests have this level of brittleness. What I'd really like to assert in many of these changed lines is that the text stays inside the margins and that more text would overflow margins.
* delete some duplicate initializationKartik K. Agaram2022-07-191-4/+0
|
* clean up a cross-test leakageKartik K. Agaram2022-07-191-9/+9
|
* bugfix: couple of margin-relative computationsKartik K. Agaram2022-07-172-3/+63
|
* separate data structure for each line's cache dataKartik K. Agaram2022-07-177-70/+211
| | | | I have no idea what the performance implications of this are..
* keep all text cache writes inside text.luaKartik K. Agaram2022-07-172-9/+8
|
* switch to line index in a functionKartik K. Agaram2022-07-171-2/+3
| | | | - Text.screen_line_width
* switch to line index in a functionKartik K. Agaram2022-07-171-16/+17
| | | | - Text.compute_fragments
* make a function oblivious to line data structureKartik K. Agaram2022-07-171-5/+5
| | | | - Text.screen_line_index
* switch to line index in a functionKartik K. Agaram2022-07-173-6/+6
| | | | - Text.to_pos_on_line
* switch to line index in a functionKartik K. Agaram2022-07-171-15/+16
| | | | - Text.populate_screen_line_starting_pos
* switch to line index in a functionKartik K. Agaram2022-07-173-4/+5
| | | | - Text.in_line
* drop some extra argsKartik K. Agaram2022-07-171-4/+4
|
* drop some redundant args when clearing the cacheKartik K. Agaram2022-07-172-11/+11
|
* fold together two largely similar casesKartik K. Agaram2022-07-171-28/+23
|
* drop some redundant args from Text.drawKartik K. Agaram2022-07-172-5/+6
|
* formattingKartik K. Agaram2022-07-162-3/+3
|
* bring back a set of constantsKartik K. Agaram2022-07-164-90/+89
| | | | | It's starting to sink in that I don't want hard-coded constants inside objects.
* more decoupling editor tests from AppKartik K. Agaram2022-07-161-1/+1
|
* more decoupling editor tests from AppKartik K. Agaram2022-07-161-3/+3
|
* more decoupling editor tests from AppKartik K. Agaram2022-07-161-13/+13
|
* more precise nameKartik K. Agaram2022-07-152-10/+10
|
* make test initializations a little more obviousKartik K. Agaram2022-07-155-156/+162
|
* bugfix: zoom in/out hotkeysKartik K. Agaram2022-07-131-0/+7
| | | | Broken since commit 3b36093553 5 hours ago.
* bugfix: resizeKartik K. Agaram2022-07-132-2/+9
|
* a more radical attempt at ignoring nil y'sKartik K. Agaram2022-07-132-7/+5
|
* no, bring back that defenseKartik K. Agaram2022-07-131-0/+4
| | | | | | | | | Scenario where I ran into it: start a stroke inside a drawing press 'o' to switch to circle mode (but any mode switch will do) The problem is that Text.textinput unconditionally blows away all .y values. Sometimes we have to wait for a draw() to fill them back in.
* a bug I've never run intoKartik K. Agaram2022-07-133-5/+10
| | | | | | The previous commit was failing inside a test that I can't reproduce manually. Perhaps it's something about how often draw/update run in practice. Anyways, it's definitely uncovered a real issue.
* hoist couple of variables outKartik K. Agaram2022-07-131-3/+6
| | | | This seems to uncover a corner case I'd never run into until now.
* use available variablesKartik K. Agaram2022-07-131-1/+1
|
* more idiomatic variable namesKartik K. Agaram2022-07-131-5/+5
|
* chunking by simple local variableKartik K. Agaram2022-07-131-4/+6
|
* make local functions look differentKartik K. Agaram2022-07-131-6/+6
|
* more chunks, same approachKartik K. Agaram2022-07-131-3/+6
|
* chunk up some long linesKartik K. Agaram2022-07-131-32/+32
| | | | | Hopefully this is more approachable. Though now I'm creating two new temporary functions on every draw. Whether I need them or not.
* .Kartik K. Agaram2022-07-121-0/+2
|
* drop final mention of state global beyond main.luaKartik K. Agaram2022-07-121-29/+28
| | | | | | | | | | This is all unfortunate in several ways - lots of functions have extra args - table lookups where we used to have a simple variable - program initialization is a lot more delicate Let's see if it was worthwhile. Can we now actually build around the editor component in forks?
* replace globals with args in a few functionsKartik K. Agaram2022-07-124-78/+81
| | | | | | | | | - Drawing.draw_shape - Drawing.draw_pending_shape - Drawing.in_drawing - Drawing.find_or_insert_point - Drawing.near - Drawing.pixels
* correct a mis-named thresholdKartik K. Agaram2022-07-122-2/+4
|
* drop heavyweight near check on file load/storeKartik K. Agaram2022-07-121-19/+25
|
* deduce left/right from state where possibleKartik K. Agaram2022-07-123-78/+78
|
* left/right margin -> left/right coordinatesKartik K. Agaram2022-07-129-369/+486
| | | | | Editor state initialization now depends on window dimensions, so we have to more carefully orchestrate startup.
* add state arg to a few functionsKartik K. Agaram2022-07-122-26/+26
| | | | | | | - Drawing.current_drawing - Drawing.select_shape_at_mouse - Drawing.select_point_at_mouse - Drawing.select_drawing_at_mouse
* add state arg to a few functionsKartik K. Agaram2022-07-124-121/+107
| | | | | | | | | | | | | - Text.cursor_at_final_screen_line - Text.move_cursor_down_to_next_text_line_while_scrolling_again_if_necessary - Text.snap_cursor_to_bottom_of_screen - Text.in_line - Text.to_pos_on_line - Text.to2 - Text.to1 - Text.previous_screen_line - Text.tweak_screen_top_and_cursor - Text.redraw_all
* add state arg to a few functionsKartik K. Agaram2022-07-123-20/+20
| | | | | - Text.pos_at_start_of_cursor_screen_line - Text.cursor_past_screen_bottom
amp;id=90560d7194f3e451ddab9d4033c98d2e6aec977b'>90560d71 ^
76755b28 ^


9542bb11 ^

76755b28 ^
672e3e50 ^
76755b28 ^
672e3e50 ^




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183



                                                                                          
                                      






                                                                                         

                                                                                                 
                        

                                  
                             
                             

                              
                            
                                  

















                                                                                                         



                                                                                                                                                                          

 




                                                                                                                                                            


                          



                                                                                                                                                                                                                                                
                                                      

 
                                                                                                                         


                                                                                                  
                                                                  

                                                                
                                                                                                                          
 

                                                                                                                                                                                         

                                      
                                                                                                                                                      



                                                                                                                                                                                                                                                                                                                                                                                                                                                                    



                                                                                                                                                                                                                                                                                                                                                     













                                                                                                                                                                                                                                                                                                                                                                                                                                    

                                                                                




                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              

                                                                                



                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 

                                                                                
                                                                                                                                                                       






                                                                                                           
                                                                                                                                            
                                                                                                                                                                                                                  
                                                                                                                                                                                                                                     
                                                                                                                                                                                                                                                                                                                                                            

                                                                                                                                      


                                                                                                                                                                                                                                                                                                                                                                      
                                                                                                                


                                                                                                                                                                                




                                                                                                                                                                                                                                                   

                                                                                                                                                                                                                                                                                                                                                

                                                                                                                                                                                                                                                                                             
                                                                                                                                                                                                                                                                               
                                                                                                                                                                                                                                                                                                                                                                                                                                                               
                                    
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  








                                                                                                                                                                                           

                                                                                                                                                                                                               

                                                                                                                                                                                                                                                                                                                         





                                                                                                                                                                                                                         
                                                                           
                                                                                                                                                         

                                                                                                                                                                                                                                                              


                                                                                                                                                                                                                                                                                                  

                                                                                                                
                                                                                                                                                                                                                                                                          
                                  
                                                                                                                                                                                                 




                                     
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Mu - 046closure_name.cc</title>
<meta name="Generator" content="Vim/7.4">
<meta name="plugin-version" content="vim7.4_v1">
<meta name="syntax" content="cpp">
<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
<meta name="colorscheme" content="minimal">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
.traceContains { color: #008000; }
.Identifier { color: #804000; }
.cSpecial { color: #008000; }
.Constant { color: #00a0a0; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
.CommentedCode { color: #6c6c6c; }
-->
</style>

<script type='text/javascript'>
<!--

-->
</script>
</head>
<body>
<pre id='vimCodeElement'>
<span class="Comment">//: Writing to a literal (not computed) address of 0 in a recipe chains two</span>
<span class="Comment">//: spaces together. When a variable has a property of /space:1, it looks up</span>
<span class="Comment">//: the variable in the chained/surrounding space. /space:2 looks up the</span>
<span class="Comment">//: surrounding space of the surrounding space, etc.</span>

<span class="Delimiter">:(scenario closure)</span>
recipe main [
  default-space:address:array:location<span class="Special"> &lt;- </span>new location:type<span class="Delimiter">,</span> <span class="Constant">30</span>
  <span class="Constant">1</span>:address:array:location/names:new-counter<span class="Special"> &lt;- </span>new-counter
  <span class="Constant">2</span>:number/<span class="Special">raw &lt;- </span>increment-counter <span class="Constant">1</span>:address:array:location/names:new-counter
  <span class="Constant">3</span>:number/<span class="Special">raw &lt;- </span>increment-counter <span class="Constant">1</span>:address:array:location/names:new-counter
]

recipe new-counter [
  default-space:address:array:location<span class="Special"> &lt;- </span>new location:type<span class="Delimiter">,</span> <span class="Constant">30</span>
  x:number<span class="Special"> &lt;- </span>copy <span class="Constant">23</span>
  y:number<span class="Special"> &lt;- </span>copy <span class="Constant">3</span>  <span class="Comment"># variable that will be incremented</span>
  reply default-space:address:array:location
]

recipe increment-counter [
  default-space:address:array:location<span class="Special"> &lt;- </span>new location:type<span class="Delimiter">,</span> <span class="Constant">30</span>
  <span class="Constant">0</span>:address:array:location/names:new-counter<span class="Special"> &lt;- </span>next-ingredient  <span class="Comment"># outer space must be created by 'new-counter' above</span>
  y:number/space:<span class="Constant">1</span><span class="Special"> &lt;- </span>add y:number/space:<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">1</span>  <span class="Comment"># increment</span>
  y:number<span class="Special"> &lt;- </span>copy <span class="Constant">234</span>  <span class="Comment"># dummy</span>
  reply y:number/space:<span class="Constant">1</span>
]

<span class="traceContains">+name: lexically surrounding space for recipe increment-counter comes from new-counter</span>
<span class="traceContains">+mem: storing 5 in location 3</span>

<span class="Comment">//: To make this work, compute the recipe that provides names for the</span>
<span class="Comment">//: surrounding space of each recipe.</span>

<span class="Delimiter">:(before &quot;End Globals&quot;)</span>
map&lt;recipe_ordinal<span class="Delimiter">,</span> recipe_ordinal&gt; Surrounding_space<span class="Delimiter">;</span>

<span class="Delimiter">:(before &quot;Transform.push_back(transform_names)&quot;)</span>
Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>collect_surrounding_spaces<span class="Delimiter">);</span>  <span class="Comment">// idempotent</span>

<span class="Delimiter">:(code)</span>
void collect_surrounding_spaces<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;--- collect surrounding spaces for recipe &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name &lt;&lt; end<span class="Delimiter">();</span>
<span class="CommentedCode">//?   cerr &lt;&lt; &quot;--- collect surrounding spaces for recipe &quot; &lt;&lt; get(Recipe, r).name &lt;&lt; '\n';</span>
  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
    const instruction&amp; inst = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
    if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>is_label<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
    for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span>
      if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
      if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>name != <span class="Constant">&quot;0&quot;</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
      type_tree* type = inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>type<span class="Delimiter">;</span>
      if <span class="Delimiter">(</span>!type
          || type<span class="Delimiter">-&gt;</span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;address&quot;</span><span class="Delimiter">)</span>
          || !type<span class="Delimiter">-&gt;</span>right
          || type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">-&gt;</span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;array&quot;</span><span class="Delimiter">)</span>
          || !type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">-&gt;</span>right
          || type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">-&gt;</span>right<span class="Delimiter">-&gt;</span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;location&quot;</span><span class="Delimiter">)</span>
          || type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">-&gt;</span>right<span class="Delimiter">-&gt;</span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span>
        raise_error &lt;&lt; <span class="Constant">&quot;slot 0 should always have type address:array:location, but is &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
        <span class="Identifier">continue</span><span class="Delimiter">;</span>
      <span class="Delimiter">}</span>
      string_tree* s = property<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">),</span> <span class="Constant">&quot;names&quot;</span><span class="Delimiter">);</span>
      if <span class="Delimiter">(</span>!s<span class="Delimiter">)</span> <span class="Delimiter">{</span>
        raise_error &lt;&lt; <span class="Constant">&quot;slot 0 requires a /names property in recipe &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name &lt;&lt; end<span class="Delimiter">();</span>
        <span class="Identifier">continue</span><span class="Delimiter">;</span>
      <span class="Delimiter">}</span>
      if <span class="Delimiter">(</span>s<span class="Delimiter">-&gt;</span>right<span class="Delimiter">)</span> raise_error &lt;&lt; <span class="Constant">&quot;slot 0 should have a single value in /names, but got &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
      const string&amp; surrounding_recipe_name = s<span class="Delimiter">-&gt;</span>value<span class="Delimiter">;</span>
      if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Surrounding_space<span class="Delimiter">,</span> r<span class="Delimiter">)</span>
          &amp;&amp; Surrounding_space[r] != get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> surrounding_recipe_name<span class="Delimiter">))</span> <span class="Delimiter">{</span>
        raise_error &lt;&lt; <span class="Constant">&quot;recipe &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; can have only one 'surrounding' recipe but has &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> Surrounding_space[r]<span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; and &quot;</span> &lt;&lt; surrounding_recipe_name &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
        <span class="Identifier">continue</span><span class="Delimiter">;</span>
      <span class="Delimiter">}</span>
      trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;name&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;lexically surrounding space for recipe &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; comes from &quot;</span> &lt;&lt; surrounding_recipe_name &lt;&lt; end<span class="Delimiter">();</span>
<span class="CommentedCode">//?       cerr &lt;&lt; &quot;lexically surrounding space for recipe &quot; &lt;&lt; get(Recipe, r).name &lt;&lt; &quot; comes from &quot; &lt;&lt; surrounding_recipe_name &lt;&lt; '\n';</span>
      if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> surrounding_recipe_name<span class="Delimiter">))</span> <span class="Delimiter">{</span>
        raise &lt;&lt; <span class="Constant">&quot;can't find recipe providing surrounding space for &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot;: &quot;</span> &lt;&lt; surrounding_recipe_name &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
        <span class="Identifier">continue</span><span class="Delimiter">;</span>
      <span class="Delimiter">}</span>
      Surrounding_space[r] = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> surrounding_recipe_name<span class="Delimiter">);</span>
    <span class="Delimiter">}</span>
  <span class="Delimiter">}</span>
<span class="Delimiter">}</span>

<span class="Comment">//: Once surrounding spaces are available, transform_names uses them to handle</span>
<span class="Comment">//: /space properties.</span>

<span class="Delimiter">:(replace{} &quot;long long int lookup_name(const reagent&amp; r, const recipe_ordinal default_recipe)&quot;)</span>
long long int lookup_name<span class="Delimiter">(</span>const reagent&amp; x<span class="Delimiter">,</span> const recipe_ordinal default_recipe<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  if <span class="Delimiter">(</span>!has_property<span class="Delimiter">(</span>x<span class="Delimiter">,</span> <span class="Constant">&quot;space&quot;</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
    if <span class="Delimiter">(</span>Name[default_recipe]<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> raise_error &lt;&lt; <span class="Constant">&quot;name not found: &quot;</span> &lt;&lt; x<span class="Delimiter">.</span>name &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
    <span class="Identifier">return</span> Name[default_recipe][x<span class="Delimiter">.</span>name]<span class="Delimiter">;</span>
  <span class="Delimiter">}</span>
  string_tree* p = property<span class="Delimiter">(</span>x<span class="Delimiter">,</span> <span class="Constant">&quot;space&quot;</span><span class="Delimiter">);</span>
  if <span class="Delimiter">(</span>!p || p<span class="Delimiter">-&gt;</span>right<span class="Delimiter">)</span> raise_error &lt;&lt; <span class="Constant">&quot;/space property should have exactly one (non-negative integer) value</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
  long long int n = to_integer<span class="Delimiter">(</span>p<span class="Delimiter">-&gt;</span>value<span class="Delimiter">);</span>
  assert<span class="Delimiter">(</span>n &gt;= <span class="Constant">0</span><span class="Delimiter">);</span>
  recipe_ordinal surrounding_recipe = lookup_surrounding_recipe<span class="Delimiter">(</span>default_recipe<span class="Delimiter">,</span> n<span class="Delimiter">);</span>
  set&lt;recipe_ordinal&gt; done<span class="Delimiter">;</span>
  vector&lt;recipe_ordinal&gt; path<span class="Delimiter">;</span>
  <span class="Identifier">return</span> lookup_name<span class="Delimiter">(</span>x<span class="Delimiter">,</span> surrounding_recipe<span class="Delimiter">,</span> done<span class="Delimiter">,</span> path<span class="Delimiter">);</span>
<span class="Delimiter">}</span>

<span class="Comment">// If the recipe we need to lookup this name in doesn't have names done yet,</span>
<span class="Comment">// recursively call transform_names on it.</span>
long long int lookup_name<span class="Delimiter">(</span>const reagent&amp; x<span class="Delimiter">,</span> const recipe_ordinal r<span class="Delimiter">,</span> set&lt;recipe_ordinal&gt;&amp; done<span class="Delimiter">,</span> vector&lt;recipe_ordinal&gt;&amp; path<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  if <span class="Delimiter">(</span>!Name[r]<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> Name[r][x<span class="Delimiter">.</span>name]<span class="Delimiter">;</span>
  if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>done<span class="Delimiter">,</span> r<span class="Delimiter">))</span> <span class="Delimiter">{</span>
    raise_error &lt;&lt; <span class="Constant">&quot;can't compute address of &quot;</span> &lt;&lt; x<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot; because &quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
    for <span class="Delimiter">(</span>long long int i = <span class="Constant">1</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>path<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
      raise_error &lt;&lt; path<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i-<span class="Constant">1</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; requires computing names of &quot;</span> &lt;&lt; path<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
    <span class="Delimiter">}</span>
    raise_error &lt;&lt; path<span class="Delimiter">.</span>at<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>path<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; requires computing names of &quot;</span> &lt;&lt; r &lt;&lt; <span class="Constant">&quot;..ad infinitum</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
    <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
  <span class="Delimiter">}</span>
  done<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>r<span class="Delimiter">);</span>
  path<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>r<span class="Delimiter">);</span>
  transform_names<span class="Delimiter">(</span>r<span class="Delimiter">);</span>  <span class="Comment">// Not passing 'done' through. Might this somehow cause an infinite loop?</span>
  assert<span class="Delimiter">(</span>!Name[r]<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
  <span class="Identifier">return</span> Name[r][x<span class="Delimiter">.</span>name]<span class="Delimiter">;</span>
<span class="Delimiter">}</span>

recipe_ordinal lookup_surrounding_recipe<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">,</span> long long int n<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  if <span class="Delimiter">(</span>n == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> r<span class="Delimiter">;</span>
  if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Surrounding_space<span class="Delimiter">,</span> r<span class="Delimiter">))</span> <span class="Delimiter">{</span>
    raise_error &lt;&lt; <span class="Constant">&quot;don't know surrounding recipe of &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
    <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
  <span class="Delimiter">}</span>
  assert<span class="Delimiter">(</span>Surrounding_space[r]<span class="Delimiter">);</span>
  <span class="Identifier">return</span> lookup_surrounding_recipe<span class="Delimiter">(</span>Surrounding_space[r]<span class="Delimiter">,</span> n-<span class="Constant">1</span><span class="Delimiter">);</span>
<span class="Delimiter">}</span>

<span class="Comment">//: weaken use-before-set detection just a tad</span>
<span class="Delimiter">:(replace{} &quot;bool already_transformed(const reagent&amp; r, const map&lt;string, long long int&gt;&amp; names)&quot;)</span>
bool already_transformed<span class="Delimiter">(</span>const reagent&amp; r<span class="Delimiter">,</span> const map&lt;string<span class="Delimiter">,</span> long long int&gt;&amp; names<span class="Delimiter">)</span> <span class="Delimiter">{</span>
  if <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">&quot;space&quot;</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
    string_tree* p = property<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">&quot;space&quot;</span><span class="Delimiter">);</span>
    if <span class="Delimiter">(</span>!p || p<span class="Delimiter">-&gt;</span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span>
      raise_error &lt;&lt; <span class="Constant">&quot;/space property should have exactly one (non-negative integer) value in &quot;</span> &lt;&lt; r<span class="Delimiter">.</span>original_string &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
      <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
    <span class="Delimiter">}</span>
    if <span class="Delimiter">(</span>p<span class="Delimiter">-&gt;</span>value != <span class="Constant">&quot;0&quot;</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
  <span class="Delimiter">}</span>
  <span class="Identifier">return</span> contains_key<span class="Delimiter">(</span>names<span class="Delimiter">,</span> r<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->