diff options
-rw-r--r-- | html/003trace.cc.html | 7 | ||||
-rw-r--r-- | html/010vm.cc.html | 6 | ||||
-rw-r--r-- | html/020run.cc.html | 4 | ||||
-rw-r--r-- | html/029debug.cc.html | 36 | ||||
-rw-r--r-- | html/030container.cc.html | 55 | ||||
-rw-r--r-- | html/032array.cc.html | 88 | ||||
-rw-r--r-- | html/036call_reply.cc.html | 1 | ||||
-rw-r--r-- | html/043new.cc.html | 104 | ||||
-rw-r--r-- | html/044space.cc.html | 62 | ||||
-rw-r--r-- | html/050scenario.cc.html | 2 | ||||
-rw-r--r-- | html/060string.mu.html | 77 | ||||
-rw-r--r-- | html/061channel.mu.html | 30 | ||||
-rw-r--r-- | html/062array.mu.html | 2 | ||||
-rw-r--r-- | html/063list.mu.html | 6 | ||||
-rw-r--r-- | html/065duplex_list.mu.html | 12 | ||||
-rw-r--r-- | html/066stream.mu.html | 8 | ||||
-rw-r--r-- | html/071print.mu.html | 112 | ||||
-rw-r--r-- | html/074console.mu.html | 12 | ||||
-rw-r--r-- | html/081run_interactive.cc.html | 112 | ||||
-rw-r--r-- | html/082persist.cc.html | 109 | ||||
-rw-r--r-- | html/999spaces.cc.html | 6 | ||||
-rw-r--r-- | html/channel.mu.html | 6 | ||||
-rw-r--r-- | html/chessboard.mu.html | 102 | ||||
-rw-r--r-- | html/counters.mu.html | 4 | ||||
-rw-r--r-- | html/edit.mu.html | 1180 | ||||
-rw-r--r-- | html/factorial.mu.html | 4 | ||||
-rw-r--r-- | html/tangle.mu.html | 2 | ||||
-rw-r--r-- | index.html | 18 |
28 files changed, 1785 insertions, 382 deletions
diff --git a/html/003trace.cc.html b/html/003trace.cc.html index a94ed6b1..0143551b 100644 --- a/html/003trace.cc.html +++ b/html/003trace.cc.html @@ -136,14 +136,17 @@ struct trace_stream <span class="Delimiter">{</span> string curr_layer<span class="Delimiter">;</span> int curr_depth<span class="Delimiter">;</span> string dump_layer<span class="Delimiter">;</span> + string collect_layer<span class="Delimiter">;</span> <span class="Comment">// if set, ignore all other layers</span> + ofstream null_stream<span class="Delimiter">;</span> <span class="Comment">// never opens a file, so writes silently fail</span> trace_stream<span class="Delimiter">()</span> :curr_stream<span class="Delimiter">(</span><span class="Constant">NULL</span><span class="Delimiter">),</span> curr_depth<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{}</span> ~trace_stream<span class="Delimiter">()</span> <span class="Delimiter">{</span> if <span class="Delimiter">(</span>curr_stream<span class="Delimiter">)</span> delete curr_stream<span class="Delimiter">;</span> <span class="Delimiter">}</span> - ostringstream& stream<span class="Delimiter">(</span>string layer<span class="Delimiter">)</span> <span class="Delimiter">{</span> + ostream& stream<span class="Delimiter">(</span>string layer<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> stream<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">,</span> layer<span class="Delimiter">);</span> <span class="Delimiter">}</span> - ostringstream& stream<span class="Delimiter">(</span>int depth<span class="Delimiter">,</span> string layer<span class="Delimiter">)</span> <span class="Delimiter">{</span> + ostream& stream<span class="Delimiter">(</span>int depth<span class="Delimiter">,</span> string layer<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!collect_layer<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && layer != collect_layer<span class="Delimiter">)</span> <span class="Identifier">return</span> null_stream<span class="Delimiter">;</span> newline<span class="Delimiter">();</span> curr_stream = new ostringstream<span class="Delimiter">;</span> curr_layer = layer<span class="Delimiter">;</span> diff --git a/html/010vm.cc.html b/html/010vm.cc.html index 6e76f36f..95a36dcf 100644 --- a/html/010vm.cc.html +++ b/html/010vm.cc.html @@ -192,8 +192,8 @@ void setup_recipes<span class="Delimiter">()</span> <span class="Delimiter">{</s <span class="Comment">//: itself.</span> <span class="Delimiter">:(before "End One-time Setup")</span> setup_recipes<span class="Delimiter">();</span> -assert<span class="Delimiter">(</span>MAX_PRIMITIVE_RECIPES < <span class="Constant">100</span><span class="Delimiter">);</span> <span class="Comment">// level 0 is primitives; until 99</span> -Next_recipe_ordinal = <span class="Constant">100</span><span class="Delimiter">;</span> +assert<span class="Delimiter">(</span>MAX_PRIMITIVE_RECIPES < <span class="Constant">200</span><span class="Delimiter">);</span> <span class="Comment">// level 0 is primitives; until 199</span> +Next_recipe_ordinal = <span class="Constant">200</span><span class="Delimiter">;</span> <span class="Comment">// End Load Recipes</span> <span class="Delimiter">:(before "End Test Run Initialization")</span> assert<span class="Delimiter">(</span>Next_recipe_ordinal < <span class="Constant">1000</span><span class="Delimiter">);</span> <span class="Comment">// recipes being tested didn't overflow into test space</span> @@ -304,8 +304,6 @@ void dump_memory<span class="Delimiter">()</span> <span class="Delimiter">{</spa <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Includes")</span> -<span class="PreProc">#include </span><span class="Constant"><map></span> -using std::map<span class="Delimiter">;</span> <span class="PreProc">#include</span><span class="Constant"><utility></span> using std::pair<span class="Delimiter">;</span> </pre> diff --git a/html/020run.cc.html b/html/020run.cc.html index fc5fd15f..792703a1 100644 --- a/html/020run.cc.html +++ b/html/020run.cc.html @@ -122,7 +122,7 @@ void run_current_routine<span class="Delimiter">()</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>products<span class="Delimiter">)</span> < SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">))</span> - raise << <span class="Constant">"failed to write to all products! "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">();</span> + raise << SIZE<span class="Delimiter">(</span>products<span class="Delimiter">)</span> << <span class="Constant">" vs "</span> << SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">)</span> << <span class="Constant">": failed to write to all products! "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">();</span> for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> write_memory<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> <span class="Delimiter">}</span> @@ -165,7 +165,7 @@ if <span class="Delimiter">(</span>argc > <span class="Constant">1</span><spa if <span class="Delimiter">(</span>!Run_tests<span class="Delimiter">)</span> <span class="Delimiter">{</span> setup<span class="Delimiter">();</span> <span class="CommentedCode">//? Trace_file = "interactive"; //? 1</span> - START_TRACING_UNTIL_END_OF_SCOPE<span class="Delimiter">;</span> +<span class="CommentedCode">//? START_TRACING_UNTIL_END_OF_SCOPE;</span> <span class="CommentedCode">//? Trace_stream->dump_layer = "all"; //? 2</span> transform_all<span class="Delimiter">();</span> recipe_ordinal r = Recipe_ordinal[string<span class="Delimiter">(</span><span class="Constant">"main"</span><span class="Delimiter">)</span>]<span class="Delimiter">;</span> diff --git a/html/029debug.cc.html b/html/029debug.cc.html index 85f82582..58adec43 100644 --- a/html/029debug.cc.html +++ b/html/029debug.cc.html @@ -13,6 +13,7 @@ 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; } +.cSpecial { color: #008000; } .Constant { color: #00a0a0; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } @@ -40,7 +41,10 @@ case _PRINT: <span class="Delimiter">{</span> for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"$print: "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">;</span> - cout << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> <span class="Constant">"newline"</span><span class="Delimiter">))</span> + cout << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + else + cout << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">;</span> <span class="Delimiter">}</span> else <span class="Delimiter">{</span> for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -134,6 +138,36 @@ case _DUMP_MEMORY: <span class="Delimiter">{</span> dump_memory<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> + +<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> +_DUMP<span class="Delimiter">,</span> +<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> +Recipe_ordinal[<span class="Constant">"$dump"</span>] = _DUMP<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> +case _DUMP: <span class="Delimiter">{</span> + reagent after_canonize = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> + cerr << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name << <span class="Constant">' '</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>value << <span class="Constant">" => "</span> << after_canonize<span class="Delimiter">.</span>value << <span class="Constant">" => "</span> << Memory[after_canonize<span class="Delimiter">.</span>value] << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +<span class="Comment">//: Helper for debugging: grab an address and then dump its value.</span> +<span class="Delimiter">:(before "End Globals")</span> +long long int foo = -<span class="Constant">1</span><span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> +_FOO<span class="Delimiter">,</span> +<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> +Recipe_ordinal[<span class="Constant">"$foo"</span>] = _FOO<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> +case _FOO: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>foo != -<span class="Constant">1</span><span class="Delimiter">)</span> cerr << foo << <span class="Constant">": "</span> << Memory[foo] << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + else cerr << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + else <span class="Delimiter">{</span> + foo = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)).</span>value<span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> </pre> </body> </html> diff --git a/html/030container.cc.html b/html/030container.cc.html index fb0e1cdc..d7666e33 100644 --- a/html/030container.cc.html +++ b/html/030container.cc.html @@ -148,15 +148,17 @@ case GET: <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span> assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span> long long int offset = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> - assert<span class="Delimiter">(</span>offset >= <span class="Constant">0</span><span class="Delimiter">);</span> - assert<span class="Delimiter">(</span>offset < size_of<span class="Delimiter">(</span>base<span class="Delimiter">));</span> long long int src = base_address<span class="Delimiter">;</span> for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < offset<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> src += size_of<span class="Delimiter">(</span>Type[base_type]<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> <span class="Delimiter">}</span> trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"address to copy is "</span> << src<span class="Delimiter">;</span> assert<span class="Delimiter">(</span>Type[base_type]<span class="Delimiter">.</span>kind == container<span class="Delimiter">);</span> - assert<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Type[base_type]<span class="Delimiter">.</span>elements<span class="Delimiter">)</span> > offset<span class="Delimiter">);</span> + if <span class="Delimiter">(</span>offset < <span class="Constant">0</span> || offset >= SIZE<span class="Delimiter">(</span>Type[base_type]<span class="Delimiter">.</span>elements<span class="Delimiter">))</span> <span class="Delimiter">{</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": invalid offset "</span> << offset << <span class="Constant">" for "</span> << Type[base_type]<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> type_ordinal src_type = Type[base_type]<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>offset<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"its type is "</span> << Type[src_type]<span class="Delimiter">.</span>name<span class="Delimiter">;</span> reagent tmp<span class="Delimiter">;</span> @@ -185,6 +187,26 @@ recipe main [ ] <span class="traceContains">+mem: storing 13 in location 15</span> +<span class="Delimiter">:(scenario get_out_of_bounds)</span> +<span class="Special">% Hide_warnings = true;</span> +recipe main [ + <span class="Constant">12</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>:literal + <span class="Constant">13</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span>:literal + <span class="Constant">14</span>:number<span class="Special"> <- </span>copy <span class="Constant">36</span>:literal + get <span class="Constant">12</span>:point-number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">2</span>:offset <span class="Comment"># point-number occupies 3 locations but has only 2 fields; out of bounds</span> +] +<span class="traceContains">+warn: main: invalid offset 2 for point-number</span> + +<span class="Delimiter">:(scenario get_out_of_bounds2)</span> +<span class="Special">% Hide_warnings = true;</span> +recipe main [ + <span class="Constant">12</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>:literal + <span class="Constant">13</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span>:literal + <span class="Constant">14</span>:number<span class="Special"> <- </span>copy <span class="Constant">36</span>:literal + get <span class="Constant">12</span>:point-number/<span class="Special">raw</span><span class="Delimiter">,</span> -<span class="Constant">1</span>:offset +] +<span class="traceContains">+warn: main: invalid offset -1 for point-number</span> + <span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> GET_ADDRESS<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> @@ -199,8 +221,11 @@ case GET_ADDRESS: <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span> assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span> long long int offset = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> - assert<span class="Delimiter">(</span>offset >= <span class="Constant">0</span><span class="Delimiter">);</span> - assert<span class="Delimiter">(</span>offset < size_of<span class="Delimiter">(</span>base<span class="Delimiter">));</span> + if <span class="Delimiter">(</span>offset < <span class="Constant">0</span> || offset >= SIZE<span class="Delimiter">(</span>Type[base_type]<span class="Delimiter">.</span>elements<span class="Delimiter">))</span> <span class="Delimiter">{</span> + raise << <span class="Constant">"invalid offset "</span> << offset << <span class="Constant">" for "</span> << Type[base_type]<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> long long int result = base_address<span class="Delimiter">;</span> for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < offset<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> result += size_of<span class="Delimiter">(</span>Type[base_type]<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> @@ -211,6 +236,26 @@ case GET_ADDRESS: <span class="Delimiter">{</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> +<span class="Delimiter">:(scenario get_address_out_of_bounds)</span> +<span class="Special">% Hide_warnings = true;</span> +recipe main [ + <span class="Constant">12</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>:literal + <span class="Constant">13</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span>:literal + <span class="Constant">14</span>:number<span class="Special"> <- </span>copy <span class="Constant">36</span>:literal + get-address <span class="Constant">12</span>:point-number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">2</span>:offset <span class="Comment"># point-number occupies 3 locations but has only 2 fields; out of bounds</span> +] +<span class="traceContains">+warn: invalid offset 2 for point-number</span> + +<span class="Delimiter">:(scenario get_address_out_of_bounds2)</span> +<span class="Special">% Hide_warnings = true;</span> +recipe main [ + <span class="Constant">12</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>:literal + <span class="Constant">13</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span>:literal + <span class="Constant">14</span>:number<span class="Special"> <- </span>copy <span class="Constant">36</span>:literal + get-address <span class="Constant">12</span>:point-number/<span class="Special">raw</span><span class="Delimiter">,</span> -<span class="Constant">1</span>:offset +] +<span class="traceContains">+warn: invalid offset -1 for point-number</span> + <span class="SalientComment">//:: Allow containers to be defined in mu code.</span> <span class="Delimiter">:(scenarios load)</span> diff --git a/html/032array.cc.html b/html/032array.cc.html index 101bd958..fddb6a17 100644 --- a/html/032array.cc.html +++ b/html/032array.cc.html @@ -122,8 +122,11 @@ case INDEX: <span class="Delimiter">{</span> vector<type_ordinal> element_type = array_element<span class="Delimiter">(</span>base<span class="Delimiter">.</span>types<span class="Delimiter">);</span> <span class="CommentedCode">//? trace(Primitive_recipe_depth, "run") << "offset: " << offset_val.at(0); //? 1</span> <span class="CommentedCode">//? trace(Primitive_recipe_depth, "run") << "size of elements: " << size_of(element_type); //? 1</span> - assert<span class="Delimiter">(</span>offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> >= <span class="Constant">0</span><span class="Delimiter">);</span> - assert<span class="Delimiter">(</span>offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> < Memory[base_address]*size_of<span class="Delimiter">(</span>element_type<span class="Delimiter">)</span> + <span class="Constant">1</span><span class="Delimiter">);</span> + if <span class="Delimiter">(</span>offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> < <span class="Constant">0</span> || offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> >= Memory[base_address]<span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": invalid index "</span> << offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> long long int src = base_address + <span class="Constant">1</span> + offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>*size_of<span class="Delimiter">(</span>element_type<span class="Delimiter">);</span> trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"address to copy is "</span> << src<span class="Delimiter">;</span> trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"its type is "</span> << Type[element_type<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>]<span class="Delimiter">.</span>name<span class="Delimiter">;</span> @@ -139,28 +142,58 @@ vector<type_ordinal> array_element<span class="Delimiter">(</span>const ve <span class="Identifier">return</span> vector<type_ordinal><span class="Delimiter">(</span>++types<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> types<span class="Delimiter">.</span>end<span class="Delimiter">());</span> <span class="Delimiter">}</span> -<span class="Delimiter">:(scenario index_address)</span> +<span class="Delimiter">:(scenario index_indirect)</span> recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">3</span>:literal <span class="Comment"># length</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>:literal <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span>:literal <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span>:literal - <span class="Constant">5</span>:number<span class="Special"> <- </span>index-address <span class="Constant">1</span>:array:number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">0</span>:literal <span class="Comment"># unsafe</span> + <span class="Constant">5</span>:address:array:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:literal + <span class="Constant">6</span>:number<span class="Special"> <- </span>index <span class="Constant">5</span>:address:array:number/deref<span class="Delimiter">,</span> <span class="Constant">1</span>:literal ] -<span class="traceContains">+mem: storing 2 in location 5</span> +<span class="traceContains">+mem: storing 15 in location 6</span> + +<span class="Delimiter">:(scenario index_out_of_bounds)</span> +<span class="Special">% Hide_warnings = true;</span> +recipe main [ + <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">3</span>:literal <span class="Comment"># 3 points</span> + <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>:literal + <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span>:literal + <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span>:literal + <span class="Constant">5</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>:literal + <span class="Constant">6</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span>:literal + <span class="Constant">7</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span>:literal + <span class="Constant">8</span>:address:array:point<span class="Special"> <- </span>copy <span class="Constant">1</span>:literal + index <span class="Constant">8</span>:address:array:point/deref<span class="Delimiter">,</span> <span class="Constant">4</span>:literal <span class="Comment"># less than size of array in locations, but larger than its length in elements</span> +] +<span class="traceContains">+warn: main: invalid index 4</span> + +<span class="Delimiter">:(scenario index_out_of_bounds2)</span> +<span class="Special">% Hide_warnings = true;</span> +recipe main [ + <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">3</span>:literal <span class="Comment"># 3 points</span> + <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>:literal + <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span>:literal + <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span>:literal + <span class="Constant">5</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>:literal + <span class="Constant">6</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span>:literal + <span class="Constant">7</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span>:literal + <span class="Constant">8</span>:address:array:point<span class="Special"> <- </span>copy <span class="Constant">1</span>:literal + index <span class="Constant">8</span>:address:array:point/deref<span class="Delimiter">,</span> -<span class="Constant">1</span>:literal +] +<span class="traceContains">+warn: main: invalid index -1</span> <span class="SalientComment">//:: To write to elements of containers, you need their address.</span> -<span class="Delimiter">:(scenario index_indirect)</span> +<span class="Delimiter">:(scenario index_address)</span> recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">3</span>:literal <span class="Comment"># length</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>:literal <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span>:literal <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span>:literal - <span class="Constant">5</span>:address:array:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:literal - <span class="Constant">6</span>:number<span class="Special"> <- </span>index <span class="Constant">5</span>:address:array:number/deref<span class="Delimiter">,</span> <span class="Constant">1</span>:literal + <span class="Constant">5</span>:number<span class="Special"> <- </span>index-address <span class="Constant">1</span>:array:number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">0</span>:literal <span class="Comment"># unsafe</span> ] -<span class="traceContains">+mem: storing 15 in location 6</span> +<span class="traceContains">+mem: storing 2 in location 5</span> <span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> INDEX_ADDRESS<span class="Delimiter">,</span> @@ -174,14 +207,47 @@ case INDEX_ADDRESS: <span class="Delimiter">{</span> reagent offset = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">));</span> vector<double> offset_val<span class="Delimiter">(</span>read_memory<span class="Delimiter">(</span>offset<span class="Delimiter">));</span> vector<type_ordinal> element_type = array_element<span class="Delimiter">(</span>base<span class="Delimiter">.</span>types<span class="Delimiter">);</span> - assert<span class="Delimiter">(</span>offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> >= <span class="Constant">0</span><span class="Delimiter">);</span> - assert<span class="Delimiter">(</span>offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> < Memory[base_address]*size_of<span class="Delimiter">(</span>element_type<span class="Delimiter">)</span> + <span class="Constant">1</span><span class="Delimiter">);</span> + if <span class="Delimiter">(</span>offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> < <span class="Constant">0</span> || offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> >= Memory[base_address]<span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": invalid index "</span> << offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> long long int result = base_address + <span class="Constant">1</span> + offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>*size_of<span class="Delimiter">(</span>element_type<span class="Delimiter">);</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> +<span class="Delimiter">:(scenario index_address_out_of_bounds)</span> +<span class="Special">% Hide_warnings = true;</span> +recipe main [ + <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">3</span>:literal <span class="Comment"># 3 points</span> + <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>:literal + <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span>:literal + <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span>:literal + <span class="Constant">5</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>:literal + <span class="Constant">6</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span>:literal + <span class="Constant">7</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span>:literal + <span class="Constant">8</span>:address:array:point<span class="Special"> <- </span>copy <span class="Constant">1</span>:literal + index-address <span class="Constant">8</span>:address:array:point/deref<span class="Delimiter">,</span> <span class="Constant">4</span>:literal <span class="Comment"># less than size of array in locations, but larger than its length in elements</span> +] +<span class="traceContains">+warn: main: invalid index 4</span> + +<span class="Delimiter">:(scenario index_address_out_of_bounds2)</span> +<span class="Special">% Hide_warnings = true;</span> +recipe main [ + <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">3</span>:literal <span class="Comment"># 3 points</span> + <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>:literal + <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span>:literal + <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span>:literal + <span class="Constant">5</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>:literal + <span class="Constant">6</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span>:literal + <span class="Constant">7</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span>:literal + <span class="Constant">8</span>:address:array:point<span class="Special"> <- </span>copy <span class="Constant">1</span>:literal + index-address <span class="Constant">8</span>:address:array:point/deref<span class="Delimiter">,</span> -<span class="Constant">1</span>:literal +] +<span class="traceContains">+warn: main: invalid index -1</span> + <span class="SalientComment">//:: compute the length of an array</span> <span class="Delimiter">:(scenario array_length)</span> diff --git a/html/036call_reply.cc.html b/html/036call_reply.cc.html index ab73fdb7..c32b06ae 100644 --- a/html/036call_reply.cc.html +++ b/html/036call_reply.cc.html @@ -85,6 +85,7 @@ case REPLY: <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'same-as-ingredient' result "</span> << caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>value << <span class="Constant">" from call to "</span> << callee << <span class="Constant">" must be location "</span> << caller_instruction<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>ingredient_index<span class="Delimiter">).</span>value << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> + <span class="Comment">// End Reply</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Comment">// continue to process rest of *caller* instruction</span> <span class="Delimiter">}</span> diff --git a/html/043new.cc.html b/html/043new.cc.html index a34f46fc..60ebb332 100644 --- a/html/043new.cc.html +++ b/html/043new.cc.html @@ -110,6 +110,8 @@ case NEW: <span class="Delimiter">{</span> size = size_of<span class="Delimiter">(</span>type<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> +<span class="CommentedCode">//? Total_alloc += size; //? 1</span> +<span class="CommentedCode">//? Num_alloc++; //? 1</span> <span class="Comment">// compute the region of memory to return</span> <span class="Comment">// really crappy at the moment</span> ensure_space<span class="Delimiter">(</span>size<span class="Delimiter">);</span> @@ -133,6 +135,18 @@ case NEW: <span class="Delimiter">{</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> +<span class="CommentedCode">//? :(before "End Globals") //? 1</span> +<span class="CommentedCode">//? long long int Total_alloc = 0; //? 1</span> +<span class="CommentedCode">//? long long int Num_alloc = 0; //? 1</span> +<span class="CommentedCode">//? long long int Total_free = 0; //? 1</span> +<span class="CommentedCode">//? long long int Num_free = 0; //? 1</span> +<span class="CommentedCode">//? :(before "End Setup") //? 1</span> +<span class="CommentedCode">//? Total_alloc = Num_alloc = Total_free = Num_free = 0; //? 1</span> +<span class="CommentedCode">//? :(before "End Teardown") //? 1</span> +<span class="CommentedCode">//? cerr << Total_alloc << "/" << Num_alloc //? 1</span> +<span class="CommentedCode">//? << " vs " << Total_free << "/" << Num_free << '\n'; //? 1</span> +<span class="CommentedCode">//? cerr << Memory.size() << '\n'; //? 1</span> + <span class="Delimiter">:(code)</span> void ensure_space<span class="Delimiter">(</span>long long int size<span class="Delimiter">)</span> <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>size <= Initial_memory_per_routine<span class="Delimiter">);</span> @@ -205,6 +219,94 @@ recipe main [ <span class="traceContains">+new: routine allocated memory from 1000 to 1002</span> <span class="traceContains">+new: routine allocated memory from 1002 to 1004</span> +<span class="Comment">//: We also provide a way to return memory, and to reuse reclaimed memory.</span> +<span class="Comment">//: todo: custodians, etc. Following malloc/free is a temporary hack.</span> + +<span class="Delimiter">:(scenario new_reclaim)</span> +recipe main [ + <span class="Constant">1</span>:address:number<span class="Special"> <- </span>new number:type + abandon <span class="Constant">1</span>:address:number + <span class="Constant">2</span>:address:number<span class="Special"> <- </span>new number:type <span class="Comment"># must be same size as abandoned memory to reuse</span> + <span class="Constant">3</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">1</span>:address:number<span class="Delimiter">,</span> <span class="Constant">2</span>:address:number +] +<span class="Comment"># both allocations should have returned the same address</span> +<span class="traceContains">+mem: storing 1 in location 3</span> + +<span class="Delimiter">:(before "End Globals")</span> +map<long long int<span class="Delimiter">,</span> long long int> Free_list<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Setup")</span> +Free_list<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> + +<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> +ABANDON<span class="Delimiter">,</span> +<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> +Recipe_ordinal[<span class="Constant">"abandon"</span>] = ABANDON<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> +case ABANDON: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> + raise << <span class="Constant">"abandon's ingredient should be scalar</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + long long int address = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> + reagent types = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> + if <span class="Delimiter">(</span>types<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> != Type_ordinal[<span class="Constant">"address"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << <span class="Constant">"abandon's ingredient should be an address</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + reagent target_type = deref<span class="Delimiter">(</span>types<span class="Delimiter">);</span> + abandon<span class="Delimiter">(</span>address<span class="Delimiter">,</span> size_of<span class="Delimiter">(</span>target_type<span class="Delimiter">));</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +<span class="Delimiter">:(code)</span> +void abandon<span class="Delimiter">(</span>long long int address<span class="Delimiter">,</span> long long int size<span class="Delimiter">)</span> <span class="Delimiter">{</span> +<span class="CommentedCode">//? Total_free += size; //? 1</span> +<span class="CommentedCode">//? Num_free++; //? 1</span> +<span class="CommentedCode">//? cerr << "abandon: " << size << '\n'; //? 2</span> + <span class="Comment">// clear memory</span> + for <span class="Delimiter">(</span>long long int curr = address<span class="Delimiter">;</span> curr < address+size<span class="Delimiter">;</span> ++curr<span class="Delimiter">)</span> + Memory[curr] = <span class="Constant">0</span><span class="Delimiter">;</span> + <span class="Comment">// append existing free list to address</span> + Memory[address] = Free_list[size]<span class="Delimiter">;</span> + Free_list[size] = address<span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +<span class="Delimiter">:(before "ensure_space(size)" following "case NEW")</span> +if <span class="Delimiter">(</span>Free_list[size]<span class="Delimiter">)</span> <span class="Delimiter">{</span> + long long int result = Free_list[size]<span class="Delimiter">;</span> + Free_list[size] = Memory[result]<span class="Delimiter">;</span> + for <span class="Delimiter">(</span>long long int curr = result+<span class="Constant">1</span><span class="Delimiter">;</span> curr < result+size<span class="Delimiter">;</span> ++curr<span class="Delimiter">)</span> + if <span class="Delimiter">(</span>Memory[curr] != <span class="Constant">0</span><span class="Delimiter">)</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": memory in free list was not zeroed out: "</span> << curr << <span class="Constant">'/'</span> << result << <span class="Constant">"; somebody wrote to us after free!!!</span><span class="cSpecial">\n</span><span class="Constant">"</span> << die<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span> + Memory[result] = array_length<span class="Delimiter">;</span> + else + Memory[result] = <span class="Constant">0</span><span class="Delimiter">;</span> + products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> + products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +<span class="Delimiter">:(scenario new_differing_size_no_reclaim)</span> +recipe main [ + <span class="Constant">1</span>:address:number<span class="Special"> <- </span>new number:type + abandon <span class="Constant">1</span>:address:number + <span class="Constant">2</span>:address:number<span class="Special"> <- </span>new number:type<span class="Delimiter">,</span> <span class="Constant">2</span>:literal <span class="Comment"># different size</span> + <span class="Constant">3</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">1</span>:address:number<span class="Delimiter">,</span> <span class="Constant">2</span>:address:number +] +<span class="Comment"># no reuse</span> +<span class="traceContains">+mem: storing 0 in location 3</span> + +<span class="Delimiter">:(scenario new_reclaim_array)</span> +recipe main [ + <span class="Constant">1</span>:address:array:number<span class="Special"> <- </span>new number:type<span class="Delimiter">,</span> <span class="Constant">2</span>:literal + abandon <span class="Constant">1</span>:address:array:number + <span class="Constant">2</span>:address:array:number<span class="Special"> <- </span>new number:type<span class="Delimiter">,</span> <span class="Constant">2</span>:literal + <span class="Constant">3</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">1</span>:address:array:number<span class="Delimiter">,</span> <span class="Constant">2</span>:address:array:number +] +<span class="Comment"># reuse</span> +<span class="traceContains">+mem: storing 1 in location 3</span> + <span class="SalientComment">//:: Next, extend 'new' to handle a unicode string literal argument.</span> <span class="Delimiter">:(scenario new_string)</span> @@ -248,6 +350,8 @@ long long int new_string<span class="Delimiter">(</span>const string& conten <span class="Comment">// allocate an array just large enough for it</span> long long int string_length = unicode_length<span class="Delimiter">(</span>contents<span class="Delimiter">);</span> <span class="CommentedCode">//? cout << "string_length is " << string_length << '\n'; //? 1</span> +<span class="CommentedCode">//? Total_alloc += string_length+1; //? 1</span> +<span class="CommentedCode">//? Num_alloc++; //? 1</span> ensure_space<span class="Delimiter">(</span>string_length+<span class="Constant">1</span><span class="Delimiter">);</span> <span class="Comment">// don't forget the extra location for array size</span> <span class="Comment">// initialize string</span> <span class="CommentedCode">//? cout << "new string literal: " << current_instruction().ingredients.at(0).name << '\n'; //? 1</span> diff --git a/html/044space.cc.html b/html/044space.cc.html index ca3a7bec..b0e25bf2 100644 --- a/html/044space.cc.html +++ b/html/044space.cc.html @@ -160,14 +160,7 @@ if <span class="Delimiter">(</span>s == <span class="Constant">"number-of-l <span class="Comment">// `default-space:address:array:location <- new location:type, number-of-locals:literal`</span> <span class="Comment">// where N is Name[recipe][""]</span> if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"new-default-space"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - curr<span class="Delimiter">.</span>operation = Recipe_ordinal[<span class="Constant">"new"</span>]<span class="Delimiter">;</span> - if <span class="Delimiter">(</span>!curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> - raise << <span class="Constant">"new-default-space can't take any ingredients</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span> - curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span><span class="Constant">"location:type"</span><span class="Delimiter">));</span> - curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span><span class="Constant">"number-of-locals:literal"</span><span class="Delimiter">));</span> - if <span class="Delimiter">(</span>!curr<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> - raise << <span class="Constant">"new-default-space can't take any results</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span> - curr<span class="Delimiter">.</span>products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span><span class="Constant">"default-space:address:array:location"</span><span class="Delimiter">));</span> + rewrite_default_space_instruction<span class="Delimiter">(</span>curr<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">:(after "vector<double> read_memory(reagent x)")</span> if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"number-of-locals"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -184,6 +177,59 @@ if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == < <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> +<span class="SalientComment">//:: a little hook to automatically reclaim the default-space when returning</span> +<span class="SalientComment">//:: from a recipe</span> + +<span class="Delimiter">:(scenario local_scope)</span> +recipe main [ + <span class="Constant">1</span>:address<span class="Special"> <- </span>foo + <span class="Constant">2</span>:address<span class="Special"> <- </span>foo + <span class="Constant">3</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">1</span>:address<span class="Delimiter">,</span> <span class="Constant">2</span>:address +] +recipe foo [ + local-scope + x:number<span class="Special"> <- </span>copy <span class="Constant">34</span>:literal + reply default-space:address:array:location +] +<span class="Comment"># both calls to foo should have received the same default-space</span> +<span class="traceContains">+mem: storing 1 in location 3</span> + +<span class="Delimiter">:(after "Falling Through End Of Recipe")</span> +try_reclaim_locals<span class="Delimiter">();</span> +<span class="Delimiter">:(after "Starting Reply")</span> +try_reclaim_locals<span class="Delimiter">();</span> + +<span class="Comment">//: now 'local-scope' is identical to 'new-default-space' except that we'll</span> +<span class="Comment">//: reclaim the default-space when the routine exits</span> +<span class="Delimiter">:(before "End Rewrite Instruction(curr)")</span> +if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"local-scope"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + rewrite_default_space_instruction<span class="Delimiter">(</span>curr<span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Delimiter">:(code)</span> +void try_reclaim_locals<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Comment">// only reclaim routines starting with 'local-scope'</span> + const recipe_ordinal r = Recipe_ordinal[current_recipe_name<span class="Delimiter">()</span>]<span class="Delimiter">;</span> + const instruction& inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> + if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name != <span class="Constant">"local-scope"</span><span class="Delimiter">)</span> + <span class="Identifier">return</span><span class="Delimiter">;</span> +<span class="CommentedCode">//? cerr << inst.to_string() << '\n'; //? 1</span> +<span class="CommentedCode">//? cerr << current_recipe_name() << ": abandon " << Current_routine->calls.front().default_space << '\n'; //? 1</span> + abandon<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>default_space<span class="Delimiter">,</span> + <span class="Comment">/*</span><span class="Comment">array length</span><span class="Comment">*/</span><span class="Constant">1</span>+<span class="Comment">/*</span><span class="Comment">number-of-locals</span><span class="Comment">*/</span>Name[r][<span class="Constant">""</span>]<span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +void rewrite_default_space_instruction<span class="Delimiter">(</span>instruction& curr<span class="Delimiter">)</span> <span class="Delimiter">{</span> + curr<span class="Delimiter">.</span>operation = Recipe_ordinal[<span class="Constant">"new"</span>]<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> + raise << <span class="Constant">"new-default-space can't take any ingredients</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span> + curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span><span class="Constant">"location:type"</span><span class="Delimiter">));</span> + curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span><span class="Constant">"number-of-locals:literal"</span><span class="Delimiter">));</span> + if <span class="Delimiter">(</span>!curr<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> + raise << <span class="Constant">"new-default-space can't take any results</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span> + curr<span class="Delimiter">.</span>products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span><span class="Constant">"default-space:address:array:location"</span><span class="Delimiter">));</span> +<span class="Delimiter">}</span> + <span class="SalientComment">//:: helpers</span> <span class="Delimiter">:(code)</span> diff --git a/html/050scenario.cc.html b/html/050scenario.cc.html index ca947e34..ae2d52b2 100644 --- a/html/050scenario.cc.html +++ b/html/050scenario.cc.html @@ -167,7 +167,7 @@ const scenario* Current_scenario = <span class="Constant">NULL</span><span class void run_mu_scenario<span class="Delimiter">(</span>const scenario& s<span class="Delimiter">)</span> <span class="Delimiter">{</span> Current_scenario = &s<span class="Delimiter">;</span> bool not_already_inside_test = !Trace_stream<span class="Delimiter">;</span> -<span class="CommentedCode">//? cerr << s.name << '\n'; //? 11</span> +<span class="CommentedCode">//? cerr << s.name << '\n'; //? 12</span> if <span class="Delimiter">(</span>not_already_inside_test<span class="Delimiter">)</span> <span class="Delimiter">{</span> Trace_file = s<span class="Delimiter">.</span>name<span class="Delimiter">;</span> Trace_stream = new trace_stream<span class="Delimiter">;</span> diff --git a/html/060string.mu.html b/html/060string.mu.html index eb98cd88..a78e7413 100644 --- a/html/060string.mu.html +++ b/html/060string.mu.html @@ -35,7 +35,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment"># Some useful helpers for dealing with strings.</span> <span class="muRecipe">recipe</span> string-equal [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> a:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> a-len:number<span class="Special"> <- </span>length a:address:array:character/deref b:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -138,9 +138,8 @@ container buffer [ ] <span class="muRecipe">recipe</span> new-buffer [ - <span class="Constant">new-default-space</span> -<span class="CommentedCode">#? $print default-space:address:array:location, [</span> -<span class="CommentedCode">#? ]</span> + <span class="Constant">local-scope</span> +<span class="CommentedCode">#? $print default-space:address:array:location, 10:literal/newline</span> result:address:buffer<span class="Special"> <- </span>new buffer:type len:address:number<span class="Special"> <- </span>get-address result:address:buffer/deref, length:offset len:address:number/deref<span class="Special"> <- </span>copy <span class="Constant">0:literal</span> @@ -148,13 +147,12 @@ container buffer [ capacity:number, found?:boolean<span class="Special"> <- </span><span class="Constant">next-ingredient</span> assert found?:boolean, <span class="Constant">[new-buffer must get a capacity argument]</span> s:address:address:array:character/deref<span class="Special"> <- </span>new character:type, capacity:number -<span class="CommentedCode">#? $print s:address:address:array:character/deref, [</span> -<span class="CommentedCode">#? ]</span> +<span class="CommentedCode">#? $print s:address:address:array:character/deref, 10:literal/newline</span> <span class="muControl">reply</span> result:address:buffer ] <span class="muRecipe">recipe</span> grow-buffer [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> in:address:buffer<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># double buffer size</span> x:address:address:array:character<span class="Special"> <- </span>get-address in:address:buffer/deref, data:offset @@ -177,7 +175,7 @@ container buffer [ ] <span class="muRecipe">recipe</span> buffer-full? [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> in:address:buffer<span class="Special"> <- </span><span class="Constant">next-ingredient</span> len:number<span class="Special"> <- </span>get in:address:buffer/deref, length:offset s:address:array:character<span class="Special"> <- </span>get in:address:buffer/deref, data:offset @@ -188,7 +186,7 @@ container buffer [ <span class="Comment"># in:address:buffer <- buffer-append in:address:buffer, c:character</span> <span class="muRecipe">recipe</span> buffer-append [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> in:address:buffer<span class="Special"> <- </span><span class="Constant">next-ingredient</span> c:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> len:address:number<span class="Special"> <- </span>get-address in:address:buffer/deref, length:offset @@ -208,13 +206,10 @@ container buffer [ in:address:buffer<span class="Special"> <- </span>grow-buffer in:address:buffer <span class="Delimiter">}</span> s:address:array:character<span class="Special"> <- </span>get in:address:buffer/deref, data:offset -<span class="CommentedCode">#? $print [array underlying buf: ], s:address:array:character, [ </span> -<span class="CommentedCode">#? ] #? 1</span> -<span class="CommentedCode">#? $print [index: ], len:address:number/deref, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [array underlying buf: ], s:address:array:character, 10:literal/newline</span> +<span class="CommentedCode">#? $print [index: ], len:address:number/deref, 10:literal/newline</span> dest:address:character<span class="Special"> <- </span>index-address s:address:array:character/deref, len:address:number/deref -<span class="CommentedCode">#? $print [storing ], c:character, [ in ], dest:address:character, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [storing ], c:character, [ in ], dest:address:character, 10:literal/newline</span> dest:address:character/deref<span class="Special"> <- </span>copy c:character len:address:number/deref<span class="Special"> <- </span>add len:address:number/deref, <span class="Constant">1:literal</span> <span class="muControl">reply</span> in:address:buffer/same-as-ingredient:0 @@ -222,7 +217,7 @@ container buffer [ <span class="muScenario">scenario</span> buffer-append-works [ run [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:buffer<span class="Special"> <- </span>new-buffer <span class="Constant">3:literal</span> s1:address:array:character<span class="Special"> <- </span>get x:address:buffer/deref, data:offset x:address:buffer<span class="Special"> <- </span>buffer-append x:address:buffer, <span class="Constant">97:literal</span> <span class="Comment"># 'a'</span> @@ -230,20 +225,6 @@ container buffer [ x:address:buffer<span class="Special"> <- </span>buffer-append x:address:buffer, <span class="Constant">99:literal</span> <span class="Comment"># 'c'</span> s2:address:array:character<span class="Special"> <- </span>get x:address:buffer/deref, data:offset 1:boolean/<span class="Special">raw <- </span>equal s1:address:array:character, s2:address:array:character -<span class="CommentedCode">#? $print s2:address:array:character, [</span> -<span class="CommentedCode">#? ]</span> -<span class="CommentedCode">#? $print 1060:number/raw, [</span> -<span class="CommentedCode">#? ]</span> -<span class="CommentedCode">#? $print 1061:number/raw, [</span> -<span class="CommentedCode">#? ]</span> -<span class="CommentedCode">#? $print 1062:number/raw, [</span> -<span class="CommentedCode">#? ]</span> -<span class="CommentedCode">#? $print 1063:number/raw, [</span> -<span class="CommentedCode">#? ]</span> -<span class="CommentedCode">#? $print 1064:number/raw, [</span> -<span class="CommentedCode">#? ]</span> -<span class="CommentedCode">#? $print 1065:number/raw, [</span> -<span class="CommentedCode">#? ]</span> 2:array:character/<span class="Special">raw <- </span>copy s2:address:array:character/deref <span class="Constant"> +buffer-filled</span> x:address:buffer<span class="Special"> <- </span>buffer-append x:address:buffer, <span class="Constant">100:literal</span> <span class="Comment"># 'd'</span> @@ -274,7 +255,7 @@ container buffer [ <span class="muScenario">scenario</span> buffer-append-handles-backspace [ run [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:buffer<span class="Special"> <- </span>new-buffer <span class="Constant">3:literal</span> x:address:buffer<span class="Special"> <- </span>buffer-append x:address:buffer, <span class="Constant">97:literal</span> <span class="Comment"># 'a'</span> x:address:buffer<span class="Special"> <- </span>buffer-append x:address:buffer, <span class="Constant">98:literal</span> <span class="Comment"># 'b'</span> @@ -291,7 +272,7 @@ container buffer [ <span class="Comment"># result:address:array:character <- integer-to-decimal-string n:number</span> <span class="muRecipe">recipe</span> integer-to-decimal-string [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> n:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># is it zero?</span> <span class="Delimiter">{</span> @@ -347,7 +328,7 @@ container buffer [ ] <span class="muRecipe">recipe</span> buffer-to-array [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> in:address:buffer<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Delimiter">{</span> <span class="Comment"># propagate null buffer</span> @@ -355,8 +336,7 @@ container buffer [ <span class="muControl">reply</span> <span class="Constant">0:literal</span> <span class="Delimiter">}</span> len:number<span class="Special"> <- </span>get in:address:buffer/deref, length:offset -<span class="CommentedCode">#? $print [size ], len:number, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [size ], len:number, 10:literal/newline</span> s:address:array:character<span class="Special"> <- </span>get in:address:buffer/deref, data:offset <span class="Comment"># we can't just return s because it is usually the wrong length</span> result:address:array:character<span class="Special"> <- </span>new character:type, len:number @@ -408,7 +388,7 @@ container buffer [ <span class="Comment"># result:address:array:character <- string-append a:address:array:character, b:address:array:character</span> <span class="muRecipe">recipe</span> string-append [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> <span class="Comment"># result = new character[a.length + b.length]</span> a:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> a-len:number<span class="Special"> <- </span>length a:address:array:character/deref @@ -467,7 +447,7 @@ container buffer [ <span class="Comment"># replace underscores in first with remaining args</span> <span class="Comment"># result:address:array:character <- interpolate template:address:array:character, ...</span> <span class="muRecipe">recipe</span> interpolate [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> template:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># compute result-len, space to allocate for result</span> tem-len:number<span class="Special"> <- </span>length template:address:array:character/deref @@ -482,8 +462,7 @@ container buffer [ result-len:number<span class="Special"> <- </span>subtract result-len:number, <span class="Constant">1:literal</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> -<span class="CommentedCode">#? $print tem-len:number, [ ], $result-len:number, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print tem-len:number, [ ], $result-len:number, 10:literal/newline</span> rewind-ingredients _<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># skip template</span> <span class="Comment"># result = new array:character[result-len]</span> @@ -592,7 +571,7 @@ container buffer [ <span class="Comment"># result:boolean <- space? c:character</span> <span class="muRecipe">recipe</span> space? [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> c:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># most common case first</span> result:boolean<span class="Special"> <- </span>equal c:character, <span class="Constant">32:literal/space</span> @@ -657,7 +636,7 @@ container buffer [ <span class="Comment"># result:address:array:character <- trim s:address:array:character</span> <span class="muRecipe">recipe</span> trim [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> s:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> len:number<span class="Special"> <- </span>length s:address:array:character/deref <span class="Comment"># left trim: compute start</span> @@ -766,7 +745,7 @@ container buffer [ <span class="Comment"># next-index:number <- find-next text:address:array:character, pattern:character</span> <span class="muRecipe">recipe</span> find-next [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> text:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> pattern:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> idx:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -866,7 +845,7 @@ container buffer [ <span class="Comment"># like find-next, but searches for multiple characters</span> <span class="Comment"># fairly dumb algorithm</span> <span class="muRecipe">recipe</span> find-substring [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> text:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> pattern:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> idx:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -945,7 +924,7 @@ container buffer [ <span class="Comment"># result:boolean <- match-at text:address:array:character, pattern:address:array:character, idx:number</span> <span class="Comment"># checks if substring matches at index 'idx'</span> <span class="muRecipe">recipe</span> match-at [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> text:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> pattern:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> idx:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -1076,7 +1055,7 @@ container buffer [ <span class="Comment"># result:address:array:address:array:character <- split s:address:array:character, delim:character</span> <span class="muRecipe">recipe</span> split [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> s:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> delim:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># empty string? return empty array</span> @@ -1206,7 +1185,7 @@ container buffer [ <span class="Comment"># x:address:array:character, y:address:array:character <- split-first text:address:array:character, delim:character</span> <span class="muRecipe">recipe</span> split-first [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> text:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> delim:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># empty string? return empty strings</span> @@ -1241,7 +1220,7 @@ container buffer [ <span class="Comment"># result:address:array:character <- string-copy buf:address:array:character, start:number, end:number</span> <span class="Comment"># todo: make this generic</span> <span class="muRecipe">recipe</span> string-copy [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> buf:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> start:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> end:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -1301,7 +1280,7 @@ container buffer [ ] <span class="muRecipe">recipe</span> min [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> y:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Delimiter">{</span> @@ -1313,7 +1292,7 @@ container buffer [ ] <span class="muRecipe">recipe</span> max [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> y:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Delimiter">{</span> diff --git a/html/061channel.mu.html b/html/061channel.mu.html index d1fc9b9b..73a39542 100644 --- a/html/061channel.mu.html +++ b/html/061channel.mu.html @@ -68,7 +68,7 @@ container channel [ <span class="Comment"># result:address:channel <- new-channel capacity:number</span> <span class="muRecipe">recipe</span> new-channel [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> <span class="Comment"># result = new channel</span> result:address:channel<span class="Special"> <- </span>new channel:type <span class="Comment"># result.first-full = 0</span> @@ -87,7 +87,7 @@ container channel [ <span class="Comment"># chan:address:channel <- write chan:address:channel, val:location</span> <span class="muRecipe">recipe</span> write [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> val:location<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Delimiter">{</span> @@ -116,7 +116,7 @@ container channel [ <span class="Comment"># result:location, chan:address:channel <- read chan:address:channel</span> <span class="muRecipe">recipe</span> read [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Delimiter">{</span> <span class="Comment"># block if chan is empty</span> @@ -142,7 +142,7 @@ container channel [ ] <span class="muRecipe">recipe</span> clear-channel [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Delimiter">{</span> empty?:boolean<span class="Special"> <- </span>channel-empty? chan:address:channel @@ -220,7 +220,7 @@ container channel [ <span class="Comment"># An empty channel has first-empty and first-full both at the same value.</span> <span class="muRecipe">recipe</span> channel-empty? [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># return chan.first-full == chan.first-free</span> full:number<span class="Special"> <- </span>get chan:address:channel/deref, first-full:offset @@ -232,7 +232,7 @@ container channel [ <span class="Comment"># A full channel has first-empty just before first-full, wasting one slot.</span> <span class="Comment"># (Other alternatives: <a href="https://en.wikipedia.org/wiki/Circular_buffer#Full_.2F_Empty_Buffer_Distinction)">https://en.wikipedia.org/wiki/Circular_buffer#Full_.2F_Empty_Buffer_Distinction)</a></span> <span class="muRecipe">recipe</span> channel-full? [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># tmp = chan.first-free + 1</span> tmp:number<span class="Special"> <- </span>get chan:address:channel/deref, first-free:offset @@ -252,7 +252,7 @@ container channel [ <span class="Comment"># result:number <- channel-capacity chan:address:channel</span> <span class="muRecipe">recipe</span> channel-capacity [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> q:address:array:location<span class="Special"> <- </span>get chan:address:channel/deref, data:offset result:number<span class="Special"> <- </span>length q:address:array:location/deref @@ -314,7 +314,7 @@ container channel [ <span class="Comment"># helper for channels of characters in particular</span> <span class="Comment"># out:address:channel <- buffer-lines in:address:channel, out:address:channel</span> <span class="muRecipe">recipe</span> buffer-lines [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> <span class="CommentedCode">#? $print [buffer-lines: aaa</span> <span class="CommentedCode">#? ]</span> in:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -333,25 +333,22 @@ container channel [ <span class="muControl">break-unless</span> backspace?:boolean <span class="Comment"># drop previous character</span> <span class="CommentedCode">#? close-console #? 2</span> -<span class="CommentedCode">#? $print [backspace! #? 1</span> +<span class="CommentedCode">#? $print [backspace!</span> <span class="CommentedCode">#? ] #? 1</span> <span class="Delimiter">{</span> buffer-length:address:number<span class="Special"> <- </span>get-address line:address:buffer/deref, length:offset buffer-empty?:boolean<span class="Special"> <- </span>equal buffer-length:address:number/deref, <span class="Constant">0:literal</span> <span class="muControl">break-if</span> buffer-empty?:boolean -<span class="CommentedCode">#? $print [before: ], buffer-length:address:number/deref, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [before: ], buffer-length:address:number/deref, 10:literal/newline</span> buffer-length:address:number/deref<span class="Special"> <- </span>subtract buffer-length:address:number/deref, <span class="Constant">1:literal</span> -<span class="CommentedCode">#? $print [after: ], buffer-length:address:number/deref, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [after: ], buffer-length:address:number/deref, 10:literal/newline</span> <span class="Delimiter">}</span> <span class="CommentedCode">#? $exit #? 2</span> <span class="Comment"># and don't append this one</span> <span class="muControl">loop</span> <span class="Constant">+next-character:label</span> <span class="Delimiter">}</span> <span class="Comment"># append anything else</span> -<span class="CommentedCode">#? $print [buffer-lines: appending ], c:character, [ </span> -<span class="CommentedCode">#? ]</span> +<span class="CommentedCode">#? $print [buffer-lines: appending ], c:character, 10:literal/newline</span> line:address:buffer<span class="Special"> <- </span>buffer-append line:address:buffer, c:character line-done?:boolean<span class="Special"> <- </span>equal c:character, <span class="Constant">10:literal/newline</span> <span class="muControl">break-if</span> line-done?:boolean @@ -372,8 +369,7 @@ container channel [ <span class="muControl">break-if</span> done?:boolean c:character<span class="Special"> <- </span>index line-contents:address:array:character/deref, i:number out:address:channel<span class="Special"> <- </span>write out:address:channel, c:character -<span class="CommentedCode">#? $print [writing ], i:number, [: ], c:character, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [writing ], i:number, [: ], c:character, 10:literal/newline</span> i:number<span class="Special"> <- </span>add i:number, <span class="Constant">1:literal</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> diff --git a/html/062array.mu.html b/html/062array.mu.html index 0388b603..52c24343 100644 --- a/html/062array.mu.html +++ b/html/062array.mu.html @@ -46,7 +46,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment"># create an array out of a list of scalar args</span> <span class="muRecipe">recipe</span> new-array [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> capacity:number<span class="Special"> <- </span>copy <span class="Constant">0:literal</span> <span class="Delimiter">{</span> <span class="Comment"># while read curr-value</span> diff --git a/html/063list.mu.html b/html/063list.mu.html index d805f6ed..0926bd94 100644 --- a/html/063list.mu.html +++ b/html/063list.mu.html @@ -43,7 +43,7 @@ container list [ <span class="Comment"># result:address:list <- push x:location, in:address:list</span> <span class="muRecipe">recipe</span> push [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:location<span class="Special"> <- </span><span class="Constant">next-ingredient</span> in:address:list<span class="Special"> <- </span><span class="Constant">next-ingredient</span> result:address:list<span class="Special"> <- </span>new list:type @@ -56,7 +56,7 @@ container list [ <span class="Comment"># result:location <- first in:address:list</span> <span class="muRecipe">recipe</span> first [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> in:address:list<span class="Special"> <- </span><span class="Constant">next-ingredient</span> result:location<span class="Special"> <- </span>get in:address:list/deref, value:offset <span class="muControl">reply</span> result:location @@ -64,7 +64,7 @@ container list [ <span class="Comment"># result:address:list <- rest in:address:list</span> <span class="muRecipe">recipe</span> rest [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> in:address:list<span class="Special"> <- </span><span class="Constant">next-ingredient</span> result:address:list<span class="Special"> <- </span>get in:address:list/deref, next:offset <span class="muControl">reply</span> result:address:list diff --git a/html/065duplex_list.mu.html b/html/065duplex_list.mu.html index 4f892745..cbf6492e 100644 --- a/html/065duplex_list.mu.html +++ b/html/065duplex_list.mu.html @@ -42,7 +42,7 @@ container duplex-list [ <span class="Comment"># result:address:duplex-list <- push-duplex x:location, in:address:duplex-list</span> <span class="muRecipe">recipe</span> push-duplex [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:location<span class="Special"> <- </span><span class="Constant">next-ingredient</span> in:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span> result:address:duplex-list<span class="Special"> <- </span>new duplex-list:type @@ -58,7 +58,7 @@ container duplex-list [ <span class="Comment"># result:location <- first-duplex in:address:duplex-list</span> <span class="muRecipe">recipe</span> first-duplex [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> in:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="muControl">reply-unless</span> in:address:duplex-list, <span class="Constant">0:literal</span> result:location<span class="Special"> <- </span>get in:address:duplex-list/deref, value:offset @@ -67,7 +67,7 @@ container duplex-list [ <span class="Comment"># result:address:duplex-list <- next-duplex in:address:duplex-list</span> <span class="muRecipe">recipe</span> next-duplex [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> in:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="muControl">reply-unless</span> in:address:duplex-list, <span class="Constant">0:literal</span> result:address:duplex-list<span class="Special"> <- </span>get in:address:duplex-list/deref, next:offset @@ -76,7 +76,7 @@ container duplex-list [ <span class="Comment"># result:address:duplex-list <- prev-duplex in:address:duplex-list</span> <span class="muRecipe">recipe</span> prev-duplex [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> in:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="muControl">reply-unless</span> in:address:duplex-list, <span class="Constant">0:literal</span> result:address:duplex-list<span class="Special"> <- </span>get in:address:duplex-list/deref, prev:offset @@ -129,7 +129,7 @@ container duplex-list [ <span class="Comment"># l:address:duplex-list <- insert-duplex x:location, in:address:duplex-list</span> <span class="Comment"># Inserts 'x' after 'in'. Returns some pointer into the list.</span> <span class="muRecipe">recipe</span> insert-duplex [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:location<span class="Special"> <- </span><span class="Constant">next-ingredient</span> in:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span> new-node:address:duplex-list<span class="Special"> <- </span>new duplex-list:type @@ -271,7 +271,7 @@ container duplex-list [ <span class="Comment"># Returns null if and only if list is empty. Beware: in that case any pointers</span> <span class="Comment"># to the head are now invalid.</span> <span class="muRecipe">recipe</span> remove-duplex [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> in:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># if 'in' is null, return</span> <span class="muControl">reply-unless</span> in:address:duplex-list, in:address:duplex-list diff --git a/html/066stream.mu.html b/html/066stream.mu.html index 2e899c6c..44a3b3ac 100644 --- a/html/066stream.mu.html +++ b/html/066stream.mu.html @@ -36,7 +36,7 @@ container stream [ ] <span class="muRecipe">recipe</span> new-stream [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> result:address:stream<span class="Special"> <- </span>new stream:type i:address:number<span class="Special"> <- </span>get-address result:address:stream/deref, index:offset i:address:number/deref<span class="Special"> <- </span>copy <span class="Constant">0:literal</span> @@ -46,7 +46,7 @@ container stream [ ] <span class="muRecipe">recipe</span> rewind-stream [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> in:address:stream<span class="Special"> <- </span><span class="Constant">next-ingredient</span> x:address:number<span class="Special"> <- </span>get-address in:address:stream/deref, index:offset x:address:number/deref<span class="Special"> <- </span>copy <span class="Constant">0:literal</span> @@ -54,7 +54,7 @@ container stream [ ] <span class="muRecipe">recipe</span> read-line [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> in:address:stream<span class="Special"> <- </span><span class="Constant">next-ingredient</span> idx:address:number<span class="Special"> <- </span>get-address in:address:stream/deref, index:offset s:address:array:character<span class="Special"> <- </span>get in:address:stream/deref, data:offset @@ -65,7 +65,7 @@ container stream [ ] <span class="muRecipe">recipe</span> end-of-stream? [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> in:address:stream<span class="Special"> <- </span><span class="Constant">next-ingredient</span> idx:number<span class="Special"> <- </span>get in:address:stream/deref, index:offset s:address:array:character<span class="Special"> <- </span>get in:address:stream/deref, data:offset diff --git a/html/071print.mu.html b/html/071print.mu.html index 43461cc5..b70e75c9 100644 --- a/html/071print.mu.html +++ b/html/071print.mu.html @@ -49,14 +49,13 @@ container screen-cell [ ] <span class="muRecipe">recipe</span> new-fake-screen [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> result:address:screen<span class="Special"> <- </span>new screen:type width:address:number<span class="Special"> <- </span>get-address result:address:screen/deref, num-columns:offset width:address:number/deref<span class="Special"> <- </span><span class="Constant">next-ingredient</span> height:address:number<span class="Special"> <- </span>get-address result:address:screen/deref, num-rows:offset height:address:number/deref<span class="Special"> <- </span><span class="Constant">next-ingredient</span> -<span class="CommentedCode">#? $print height:address:number/deref, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print height:address:number/deref, 10:literal/newline</span> row:address:number<span class="Special"> <- </span>get-address result:address:screen/deref, cursor-row:offset row:address:number/deref<span class="Special"> <- </span>copy <span class="Constant">0:literal</span> column:address:number<span class="Special"> <- </span>get-address result:address:screen/deref, cursor-column:offset @@ -69,7 +68,7 @@ container screen-cell [ ] <span class="muRecipe">recipe</span> clear-screen [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="CommentedCode">#? $print [clearing screen</span> <span class="CommentedCode">#? ] #? 1</span> @@ -103,8 +102,28 @@ container screen-cell [ <span class="muControl">reply</span> x:address:screen/same-as-ingredient:0 ] +<span class="muRecipe">recipe</span> fake-screen-is-clear? [ + <span class="Constant">local-scope</span> + screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="muControl">reply-unless</span> screen:address:screen, <span class="Constant">1:literal/true</span> + buf:address:array:screen-cell<span class="Special"> <- </span>get screen:address:screen/deref, data:offset + i:number<span class="Special"> <- </span>copy <span class="Constant">0:literal</span> + len:number<span class="Special"> <- </span>length buf:address:array:screen-cell/deref + <span class="Delimiter">{</span> + done?:boolean<span class="Special"> <- </span>greater-or-equal i:number, len:number + <span class="muControl">break-if</span> done?:boolean + curr:screen-cell<span class="Special"> <- </span>index buf:address:array:screen-cell/deref, i:number + curr-contents:character<span class="Special"> <- </span>get curr:screen-cell, contents:offset + i:number<span class="Special"> <- </span>add i:number, <span class="Constant">1:literal</span> + <span class="muControl">loop-unless</span> curr-contents:character + <span class="Comment"># not 0</span> + <span class="muControl">reply</span> <span class="Constant">0:literal/false</span> + <span class="Delimiter">}</span> + <span class="muControl">reply</span> <span class="Constant">1:literal/true</span> +] + <span class="muRecipe">recipe</span> print-character [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> c:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> color:number, color-found?:boolean<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -124,15 +143,23 @@ container screen-cell [ <span class="Comment"># if x exists</span> <span class="Comment"># (handle special cases exactly like in the real screen)</span> <span class="muControl">break-unless</span> x:address:screen - row:address:number<span class="Special"> <- </span>get-address x:address:screen/deref, cursor-row:offset - column:address:number<span class="Special"> <- </span>get-address x:address:screen/deref, cursor-column:offset width:number<span class="Special"> <- </span>get x:address:screen/deref, num-columns:offset height:number<span class="Special"> <- </span>get x:address:screen/deref, num-rows:offset + <span class="Comment"># if cursor is out of bounds, silently exit</span> + row:address:number<span class="Special"> <- </span>get-address x:address:screen/deref, cursor-row:offset + legal?:boolean<span class="Special"> <- </span>greater-or-equal row:address:number/deref, <span class="Constant">0:literal</span> + <span class="muControl">reply-unless</span> legal?:boolean, x:address:screen + legal?:boolean<span class="Special"> <- </span>lesser-than row:address:number/deref, height:number + <span class="muControl">reply-unless</span> legal?:boolean, x:address:screen + column:address:number<span class="Special"> <- </span>get-address x:address:screen/deref, cursor-column:offset + legal?:boolean<span class="Special"> <- </span>greater-or-equal column:address:number/deref, <span class="Constant">0:literal</span> + <span class="muControl">reply-unless</span> legal?:boolean, x:address:screen + legal?:boolean<span class="Special"> <- </span>lesser-than column:address:number/deref, width:number + <span class="muControl">reply-unless</span> legal?:boolean, x:address:screen <span class="Comment"># special-case: newline</span> <span class="Delimiter">{</span> newline?:boolean<span class="Special"> <- </span>equal c:character, <span class="Constant">10:literal/newline</span> -<span class="CommentedCode">#? $print c:character, [ ], newline?:boolean, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print c:character, [ ], newline?:boolean, 10:literal/newline</span> <span class="muControl">break-unless</span> newline?:boolean <span class="Delimiter">{</span> <span class="Comment"># unless cursor is already at bottom</span> @@ -146,11 +173,10 @@ container screen-cell [ <span class="muControl">reply</span> x:address:screen/same-as-ingredient:0 <span class="Delimiter">}</span> <span class="Comment"># save character in fake screen</span> -<span class="CommentedCode">#? $print row:address:number/deref, [, ], column:address:number/deref, [ </span> -<span class="CommentedCode">#? ] #? 1</span> index:number<span class="Special"> <- </span>multiply row:address:number/deref, width:number index:number<span class="Special"> <- </span>add index:number, column:address:number/deref buf:address:array:screen-cell<span class="Special"> <- </span>get x:address:screen/deref, data:offset + len:number<span class="Special"> <- </span>length buf:address:array:screen-cell/deref <span class="Comment"># special-case: backspace</span> <span class="Delimiter">{</span> backspace?:boolean<span class="Special"> <- </span>equal c:character, <span class="Constant">8:literal</span> @@ -170,8 +196,7 @@ container screen-cell [ <span class="Delimiter">}</span> <span class="muControl">reply</span> x:address:screen/same-as-ingredient:0 <span class="Delimiter">}</span> -<span class="CommentedCode">#? $print [saving character ], c:character, [ to fake screen ], cursor:address/screen, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [saving character ], c:character, [ to fake screen ], cursor:address/screen, 10:literal/newline</span> cursor:address:screen-cell<span class="Special"> <- </span>index-address buf:address:array:screen-cell/deref, index:number cursor-contents:address:character<span class="Special"> <- </span>get-address cursor:address:screen-cell/deref, contents:offset cursor-color:address:number<span class="Special"> <- </span>get-address cursor:address:screen-cell/deref, color:offset @@ -348,7 +373,7 @@ container screen-cell [ ] <span class="muRecipe">recipe</span> clear-line [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># if x exists, clear line in fake screen</span> <span class="Delimiter">{</span> @@ -359,8 +384,7 @@ container screen-cell [ <span class="Comment"># space over the entire line</span> <span class="CommentedCode">#? $start-tracing #? 1</span> <span class="Delimiter">{</span> -<span class="CommentedCode">#? $print column:address:number/deref, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print column:address:number/deref, 10:literal/newline</span> right:number<span class="Special"> <- </span>subtract width:number, <span class="Constant">1:literal</span> done?:boolean<span class="Special"> <- </span>greater-or-equal column:address:number/deref, right:number <span class="muControl">break-if</span> done?:boolean @@ -377,7 +401,7 @@ container screen-cell [ ] <span class="muRecipe">recipe</span> cursor-position [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># if x exists, lookup cursor in fake screen</span> <span class="Delimiter">{</span> @@ -391,7 +415,7 @@ container screen-cell [ ] <span class="muRecipe">recipe</span> move-cursor [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> new-row:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> new-column:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -441,23 +465,22 @@ container screen-cell [ ] <span class="muRecipe">recipe</span> cursor-down [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># if x exists, move cursor in fake screen</span> <span class="Delimiter">{</span> <span class="muControl">break-unless</span> x:address:screen <span class="Delimiter">{</span> - <span class="Comment"># if row < height</span> + <span class="Comment"># if row < height-1</span> height:number<span class="Special"> <- </span>get x:address:screen/deref, num-rows:offset row:address:number<span class="Special"> <- </span>get-address x:address:screen/deref, cursor-row:offset - at-bottom?:boolean<span class="Special"> <- </span>greater-or-equal row:address:number/deref, height:number + max:number<span class="Special"> <- </span>subtract height:number, <span class="Constant">1:literal</span> + at-bottom?:boolean<span class="Special"> <- </span>greater-or-equal row:address:number/deref, max:number <span class="muControl">break-if</span> at-bottom?:boolean <span class="Comment"># row = row+1</span> -<span class="CommentedCode">#? $print [AAA: ], row:address:number, [ -> ], row:address:number/deref, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [AAA: ], row:address:number, [ -> ], row:address:number/deref, 10:literal/newline</span> row:address:number/deref<span class="Special"> <- </span>add row:address:number/deref, <span class="Constant">1:literal</span> -<span class="CommentedCode">#? $print [BBB: ], row:address:number, [ -> ], row:address:number/deref, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [BBB: ], row:address:number, [ -> ], row:address:number/deref, 10:literal/newline</span> <span class="CommentedCode">#? $start-tracing #? 1</span> <span class="Delimiter">}</span> <span class="muControl">reply</span> x:address:screen/same-as-ingredient:0 @@ -468,15 +491,15 @@ container screen-cell [ ] <span class="muRecipe">recipe</span> cursor-up [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># if x exists, move cursor in fake screen</span> <span class="Delimiter">{</span> <span class="muControl">break-unless</span> x:address:screen <span class="Delimiter">{</span> - <span class="Comment"># if row >= 0</span> + <span class="Comment"># if row > 0</span> row:address:number<span class="Special"> <- </span>get-address x:address:screen/deref, cursor-row:offset - at-top?:boolean<span class="Special"> <- </span>lesser-than row:address:number/deref, <span class="Constant">0:literal</span> + at-top?:boolean<span class="Special"> <- </span>lesser-or-equal row:address:number/deref, <span class="Constant">0:literal</span> <span class="muControl">break-if</span> at-top?:boolean <span class="Comment"># row = row-1</span> row:address:number/deref<span class="Special"> <- </span>subtract row:address:number/deref, <span class="Constant">1:literal</span> @@ -489,16 +512,17 @@ container screen-cell [ ] <span class="muRecipe">recipe</span> cursor-right [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># if x exists, move cursor in fake screen</span> <span class="Delimiter">{</span> <span class="muControl">break-unless</span> x:address:screen <span class="Delimiter">{</span> - <span class="Comment"># if column < width</span> + <span class="Comment"># if column < width-1</span> width:number<span class="Special"> <- </span>get x:address:screen/deref, num-columns:offset column:address:number<span class="Special"> <- </span>get-address x:address:screen/deref, cursor-column:offset - at-bottom?:boolean<span class="Special"> <- </span>greater-or-equal column:address:number/deref, width:number + max:number<span class="Special"> <- </span>subtract width:number, <span class="Constant">1:literal</span> + at-bottom?:boolean<span class="Special"> <- </span>greater-or-equal column:address:number/deref, max:number <span class="muControl">break-if</span> at-bottom?:boolean <span class="Comment"># column = column+1</span> column:address:number/deref<span class="Special"> <- </span>add column:address:number/deref, <span class="Constant">1:literal</span> @@ -511,15 +535,15 @@ container screen-cell [ ] <span class="muRecipe">recipe</span> cursor-left [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># if x exists, move cursor in fake screen</span> <span class="Delimiter">{</span> <span class="muControl">break-unless</span> x:address:screen <span class="Delimiter">{</span> - <span class="Comment"># if column >= 0</span> + <span class="Comment"># if column > 0</span> column:address:number<span class="Special"> <- </span>get-address x:address:screen/deref, cursor-column:offset - at-top?:boolean<span class="Special"> <- </span>lesser-than column:address:number/deref, <span class="Constant">0:literal</span> + at-top?:boolean<span class="Special"> <- </span>lesser-or-equal column:address:number/deref, <span class="Constant">0:literal</span> <span class="muControl">break-if</span> at-top?:boolean <span class="Comment"># column = column-1</span> column:address:number/deref<span class="Special"> <- </span>subtract column:address:number/deref, <span class="Constant">1:literal</span> @@ -532,7 +556,7 @@ container screen-cell [ ] <span class="muRecipe">recipe</span> cursor-to-start-of-line [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> row:number, _, x:address:screen<span class="Special"> <- </span>cursor-position x:address:screen column:number<span class="Special"> <- </span>copy <span class="Constant">0:literal</span> @@ -541,7 +565,7 @@ container screen-cell [ ] <span class="muRecipe">recipe</span> cursor-to-next-line [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> x:address:screen<span class="Special"> <- </span>cursor-down x:address:screen x:address:screen<span class="Special"> <- </span>cursor-to-start-of-line x:address:screen @@ -549,7 +573,7 @@ container screen-cell [ ] <span class="muRecipe">recipe</span> screen-width [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># if x exists, move cursor in fake screen</span> <span class="Delimiter">{</span> @@ -563,7 +587,7 @@ container screen-cell [ ] <span class="muRecipe">recipe</span> screen-height [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># if x exists, move cursor in fake screen</span> <span class="Delimiter">{</span> @@ -577,7 +601,7 @@ container screen-cell [ ] <span class="muRecipe">recipe</span> hide-cursor [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># if x exists (not real display), do nothing</span> <span class="Delimiter">{</span> @@ -590,7 +614,7 @@ container screen-cell [ ] <span class="muRecipe">recipe</span> show-cursor [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># if x exists (not real display), do nothing</span> <span class="Delimiter">{</span> @@ -603,7 +627,7 @@ container screen-cell [ ] <span class="muRecipe">recipe</span> hide-screen [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># if x exists (not real display), do nothing</span> <span class="Delimiter">{</span> @@ -616,7 +640,7 @@ container screen-cell [ ] <span class="muRecipe">recipe</span> show-screen [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># if x exists (not real display), do nothing</span> <span class="Delimiter">{</span> @@ -629,7 +653,7 @@ container screen-cell [ ] <span class="muRecipe">recipe</span> print-string [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> s:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> color:number, color-found?:boolean<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -678,7 +702,7 @@ container screen-cell [ ] <span class="muRecipe">recipe</span> print-integer [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> n:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> color:number, color-found?:boolean<span class="Special"> <- </span><span class="Constant">next-ingredient</span> diff --git a/html/074console.mu.html b/html/074console.mu.html index 594f28c2..2b60d6f6 100644 --- a/html/074console.mu.html +++ b/html/074console.mu.html @@ -53,7 +53,7 @@ container console [ ] <span class="muRecipe">recipe</span> new-fake-console [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> result:address:console<span class="Special"> <- </span>new console:type buf:address:address:array:character<span class="Special"> <- </span>get-address result:address:console/deref, data:offset <span class="CommentedCode">#? $start-tracing #? 1</span> @@ -65,7 +65,7 @@ container console [ ] <span class="muRecipe">recipe</span> read-event [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:console<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Delimiter">{</span> <span class="muControl">break-unless</span> x:address:console @@ -92,7 +92,7 @@ container console [ <span class="Comment"># isn't unicode, so no arrow keys, page-up/page-down, etc. But you still get</span> <span class="Comment"># newlines, tabs, ctrl-d..</span> <span class="muRecipe">recipe</span> read-key [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> <span class="CommentedCode">#? $print default-space:address:array:location #? 1</span> <span class="CommentedCode">#? $exit #? 1</span> <span class="CommentedCode">#? $start-tracing #? 1</span> @@ -110,7 +110,7 @@ container console [ ] <span class="muRecipe">recipe</span> send-keys-to-channel [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> console:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -126,7 +126,7 @@ container console [ ] <span class="muRecipe">recipe</span> wait-for-event [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> console:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Delimiter">{</span> _, console:address, found?:boolean<span class="Special"> <- </span>read-event console:address @@ -136,7 +136,7 @@ container console [ <span class="Comment"># use this helper to skip rendering if there's lots of other events queued up</span> <span class="muRecipe">recipe</span> has-more-events? [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> console:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Delimiter">{</span> <span class="muControl">break-unless</span> console:address diff --git a/html/081run_interactive.cc.html b/html/081run_interactive.cc.html index 5183cee6..54b1456c 100644 --- a/html/081run_interactive.cc.html +++ b/html/081run_interactive.cc.html @@ -49,8 +49,10 @@ recipe main [ <span class="Comment"># result is null</span> <span class="traceContains">+mem: storing 0 in location 1</span> -<span class="Comment">//: run code in 'interactive mode', i.e. with warnings off, and recording</span> -<span class="Comment">//: output in case we want to print it to screen</span> +<span class="Comment">//: run code in 'interactive mode', i.e. with warnings off and return:</span> +<span class="Comment">//: stringified output in case we want to print it to screen</span> +<span class="Comment">//: any warnings encountered</span> +<span class="Comment">//: simulated screen any prints went to</span> <span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> RUN_INTERACTIVE<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> @@ -59,11 +61,13 @@ Recipe_ordinal[<span class="Constant">"run-interactive"</span>] = RUN_ <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> case RUN_INTERACTIVE: <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span> - products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">);</span> + products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">3</span><span class="Delimiter">);</span> bool new_code_pushed_to_stack = run_interactive<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> if <span class="Delimiter">(</span>!new_code_pushed_to_stack<span class="Delimiter">)</span> <span class="Delimiter">{</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>warnings_from_trace<span class="Delimiter">());</span> + products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> + clean_up_interactive<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Comment">// done with this instruction</span> <span class="Delimiter">}</span> else <span class="Delimiter">{</span> @@ -73,49 +77,53 @@ case RUN_INTERACTIVE: <span class="Delimiter">{</span> <span class="Delimiter">:(before "End Globals")</span> bool Running_interactive = <span class="Constant">false</span><span class="Delimiter">;</span> +long long int Old_screen = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Comment">// we can support one iteration of screen inside screen</span> <span class="Delimiter">:(before "End Setup")</span> Running_interactive = <span class="Constant">false</span><span class="Delimiter">;</span> +Old_screen = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">:(code)</span> -<span class="Comment">// reads a string, tries to call it as code, saving all warnings.</span> +<span class="Comment">// reads a string, tries to call it as code (treating it as a test), saving</span> +<span class="Comment">// all warnings.</span> <span class="Comment">// returns true if successfully called (no errors found during load and transform)</span> bool run_interactive<span class="Delimiter">(</span>long long int address<span class="Delimiter">)</span> <span class="Delimiter">{</span> if <span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"interactive"</span><span class="Delimiter">)</span> == Recipe_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">())</span> Recipe_ordinal[<span class="Constant">"interactive"</span>] = Next_recipe_ordinal++<span class="Delimiter">;</span> + Old_screen = Memory[SCREEN]<span class="Delimiter">;</span> +<span class="CommentedCode">//? cerr << "save screen: " << Old_screen << '\n'; //? 2</span> + <span class="Comment">// try to sandbox the run as best you can</span> + <span class="Comment">// todo: test this</span> + if <span class="Delimiter">(</span>!Current_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Comment">// not already sandboxed</span> + for <span class="Delimiter">(</span>long long int i = <span class="Constant">1</span><span class="Delimiter">;</span> i < Reserved_for_tests<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> + Memory<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>i<span class="Delimiter">);</span> + Name[Recipe_ordinal[<span class="Constant">"interactive"</span>]]<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> + <span class="Delimiter">}</span> +<span class="CommentedCode">//? cerr << "screen was at " << Name[Recipe_ordinal["interactive"]]["screen"] << '\n'; //? 1</span> + Name[Recipe_ordinal[<span class="Constant">"interactive"</span>]][<span class="Constant">"screen"</span>] = SCREEN<span class="Delimiter">;</span> +<span class="CommentedCode">//? cerr << "screen now at " << Name[Recipe_ordinal["interactive"]]["screen"] << '\n'; //? 1</span> string command = trim<span class="Delimiter">(</span>strip_comments<span class="Delimiter">(</span>to_string<span class="Delimiter">(</span>address<span class="Delimiter">)));</span> if <span class="Delimiter">(</span>command<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> -<span class="CommentedCode">//? tb_shutdown(); //? 1</span> -<span class="CommentedCode">//? cerr << command << '\n'; //? 2</span> Recipe<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>Recipe_ordinal[<span class="Constant">"interactive"</span>]<span class="Delimiter">);</span> Hide_warnings = <span class="Constant">true</span><span class="Delimiter">;</span> if <span class="Delimiter">(</span>!Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span> Trace_file = <span class="Constant">""</span><span class="Delimiter">;</span> <span class="Comment">// if there wasn't already a stream we don't want to save it</span> Trace_stream = new trace_stream<span class="Delimiter">;</span> + Trace_stream<span class="Delimiter">-></span>collect_layer = <span class="Constant">"warn"</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">// call run(string) but without the scheduling</span> - load<span class="Delimiter">(</span><span class="Constant">"recipe interactive [</span><span class="cSpecial">\n</span><span class="Constant">"</span>+command+<span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> + <span class="Comment">// we won't create a local scope so that we can get to the new screen after</span> + <span class="Comment">// we return from 'interactive'.</span> + load<span class="Delimiter">(</span>string<span class="Delimiter">(</span><span class="Constant">"recipe interactive [</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">)</span> + + <span class="Constant">"screen:address <- new-fake-screen 5, 5</span><span class="cSpecial">\n</span><span class="Constant">"</span> + + command + <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">"</span> + + <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> transform_all<span class="Delimiter">();</span> - if <span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span><span class="Constant">"warn"</span><span class="Delimiter">)</span> > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - Hide_warnings = <span class="Constant">false</span><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>trace_count<span class="Delimiter">(</span><span class="Constant">"warn"</span><span class="Delimiter">)</span> > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> Running_interactive = <span class="Constant">true</span><span class="Delimiter">;</span> Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>push_front<span class="Delimiter">(</span>call<span class="Delimiter">(</span>Recipe_ordinal[<span class="Constant">"interactive"</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="Delimiter">:(after "Starting Reply")</span> -if <span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">()</span> == <span class="Constant">"interactive"</span><span class="Delimiter">)</span> clean_up_interactive<span class="Delimiter">();</span> -<span class="Delimiter">:(after "Falling Through End Of Recipe")</span> -if <span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">()</span> == <span class="Constant">"interactive"</span><span class="Delimiter">)</span> clean_up_interactive<span class="Delimiter">();</span> -<span class="Delimiter">:(code)</span> -void clean_up_interactive<span class="Delimiter">()</span> <span class="Delimiter">{</span> -<span class="CommentedCode">//? static int foo = 0; //? 1</span> - Hide_warnings = <span class="Constant">false</span><span class="Delimiter">;</span> - Running_interactive = <span class="Constant">false</span><span class="Delimiter">;</span> -<span class="CommentedCode">//? ++foo; //? 1</span> -<span class="CommentedCode">//? if (foo == 1) tb_init(); //? 1</span> -<span class="Delimiter">}</span> - <span class="Delimiter">:(scenario "run_interactive_returns_stringified_result")</span> recipe main [ <span class="Comment"># try to interactively add 2 and 2</span> @@ -165,42 +173,65 @@ if <span class="Delimiter">(</span>Running_interactive<span class="Delimiter">)< <span class="Delimiter">:(code)</span> void record_products<span class="Delimiter">(</span>const instruction& instruction<span class="Delimiter">,</span> const vector<vector<double> >& products<span class="Delimiter">)</span> <span class="Delimiter">{</span> ostringstream out<span class="Delimiter">;</span> -<span class="CommentedCode">//? cerr << current_instruction().to_string() << '\n'; //? 1</span> for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// string</span> if <span class="Delimiter">(</span>i < SIZE<span class="Delimiter">(</span>instruction<span class="Delimiter">.</span>products<span class="Delimiter">))</span> <span class="Delimiter">{</span> -<span class="CommentedCode">//? cerr << "AA\n"; //? 1</span> -<span class="CommentedCode">//? cerr << instruction.products.size() << " vs " << i << '\n'; //? 1</span> if <span class="Delimiter">(</span>is_string<span class="Delimiter">(</span>instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span> -<span class="CommentedCode">//? cerr << "BB\n"; //? 1</span> assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)));</span> out << to_string<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">// End Record Product Special-cases</span> <span class="Delimiter">}</span> - for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span> -<span class="CommentedCode">//? cerr << "aa: " << i << ", " << j << ": " << products.at(i).at(j) << '\n'; //? 1</span> - out << products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)</span> << <span class="Constant">' '</span><span class="Delimiter">;</span> - <span class="Delimiter">}</span> + for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> ++j<span class="Delimiter">)</span> + out << products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)</span> << <span class="Constant">' '</span><span class="Delimiter">;</span> out << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="CommentedCode">//? cerr << "aa: {\n" << out.str() << "}\n"; //? 2</span> Most_recent_results = out<span class="Delimiter">.</span>str<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before "Complete Call Fallthrough")</span> if <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>operation == RUN_INTERACTIVE && !current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> - assert<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">)</span> <= <span class="Constant">2</span><span class="Delimiter">);</span> + assert<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">)</span> <= <span class="Constant">3</span><span class="Delimiter">);</span> <span class="Comment">// Send the results of the most recently executed instruction, regardless of</span> <span class="Comment">// call depth, to be converted to string and potentially printed to string.</span> vector<double> result<span class="Delimiter">;</span> result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_string<span class="Delimiter">(</span>Most_recent_results<span class="Delimiter">));</span> write_memory<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">),</span> result<span class="Delimiter">);</span> - if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">)</span> == <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">)</span> >= <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> vector<double> warnings<span class="Delimiter">;</span> warnings<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>warnings_from_trace<span class="Delimiter">());</span> write_memory<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">),</span> warnings<span class="Delimiter">);</span> <span class="Delimiter">}</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">)</span> >= <span class="Constant">3</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + vector<double> screen<span class="Delimiter">;</span> +<span class="CommentedCode">//? cerr << "returning screen " << Memory[SCREEN] << " to " << current_instruction().products.at(2).to_string() << " value " << current_instruction().products.at(2).value << '\n'; //? 1</span> + screen<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>Memory[SCREEN]<span class="Delimiter">);</span> + write_memory<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">),</span> screen<span class="Delimiter">);</span> + <span class="Delimiter">}</span> +<span class="Delimiter">}</span> + +<span class="Comment">//: clean up reply after we've popped it off the call-stack</span> +<span class="Comment">//: however, we need what was on the stack to decide whether to clean up</span> +<span class="Delimiter">:(after "Starting Reply")</span> +bool must_clean_up_interactive = <span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">()</span> == <span class="Constant">"interactive"</span><span class="Delimiter">);</span> +<span class="Delimiter">:(after "Falling Through End Of Recipe")</span> +bool must_clean_up_interactive = <span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">()</span> == <span class="Constant">"interactive"</span><span class="Delimiter">);</span> +<span class="Delimiter">:(before "End Reply")</span> +if <span class="Delimiter">(</span>must_clean_up_interactive<span class="Delimiter">)</span> clean_up_interactive<span class="Delimiter">();</span> +<span class="Delimiter">:(before "Complete Call Fallthrough")</span> +if <span class="Delimiter">(</span>must_clean_up_interactive<span class="Delimiter">)</span> clean_up_interactive<span class="Delimiter">();</span> +<span class="Delimiter">:(code)</span> +void clean_up_interactive<span class="Delimiter">()</span> <span class="Delimiter">{</span> + Hide_warnings = <span class="Constant">false</span><span class="Delimiter">;</span> + Running_interactive = <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Comment">// hack: assume collect_layer isn't set anywhere else</span> + if <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>collect_layer == <span class="Constant">"warn"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + delete Trace_stream<span class="Delimiter">;</span> + Trace_stream = <span class="Constant">NULL</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> +<span class="CommentedCode">//? cerr << "restore screen: " << Memory[SCREEN] << " to " << Old_screen << '\n'; //? 1</span> + Memory[SCREEN] = Old_screen<span class="Delimiter">;</span> + Old_screen = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> @@ -227,17 +258,13 @@ string to_string<span class="Delimiter">(</span>long long int address<span class <span class="Comment">// todo: unicode</span> tmp << <span class="Delimiter">(</span>char<span class="Delimiter">)(</span>int<span class="Delimiter">)</span>Memory[curr]<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="CommentedCode">//? tb_shutdown(); //? 1</span> -<span class="CommentedCode">//? cerr << tmp.str() << '\n'; //? 1</span> <span class="Identifier">return</span> tmp<span class="Delimiter">.</span>str<span class="Delimiter">();</span> <span class="Delimiter">}</span> long long int stringified_value_of_location<span class="Delimiter">(</span>long long int address<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// convert to string</span> ostringstream out<span class="Delimiter">;</span> -<span class="CommentedCode">//? trace(1, "foo") << "a: " << address; //? 1</span> out << Memory[address]<span class="Delimiter">;</span> -<span class="CommentedCode">//? trace(1, "foo") << "b: " << Memory[address]; //? 1</span> <span class="Identifier">return</span> new_string<span class="Delimiter">(</span>out<span class="Delimiter">.</span>str<span class="Delimiter">());</span> <span class="Delimiter">}</span> @@ -277,13 +304,6 @@ case RELOAD: <span class="Delimiter">{</span> Loading_interactive = <span class="Constant">true</span><span class="Delimiter">;</span> Hide_warnings = <span class="Constant">true</span><span class="Delimiter">;</span> load<span class="Delimiter">(</span>to_string<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span> -<span class="CommentedCode">//? static int foo = 0;</span> -<span class="CommentedCode">//? if (++foo == 2) {</span> -<span class="CommentedCode">//? tb_shutdown();</span> -<span class="CommentedCode">//? cerr << Recipe_ordinal["new-add"] << '\n';</span> -<span class="CommentedCode">//? cerr << Recipe[Recipe_ordinal["new-add"]].steps[2].to_string() << '\n';</span> -<span class="CommentedCode">//? exit(0);</span> -<span class="CommentedCode">//? }</span> transform_all<span class="Delimiter">();</span> Hide_warnings = <span class="Constant">false</span><span class="Delimiter">;</span> Loading_interactive = <span class="Constant">false</span><span class="Delimiter">;</span> diff --git a/html/082persist.cc.html b/html/082persist.cc.html new file mode 100644 index 00000000..cf056dba --- /dev/null +++ b/html/082persist.cc.html @@ -0,0 +1,109 @@ +<!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 - 082persist.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; } +.cSpecial { color: #008000; } +.Constant { color: #00a0a0; } +.Comment { color: #9090ff; } +.Delimiter { color: #a04060; } +.Identifier { color: #804000; } +.PreProc { color: #c000c0; } +.CommentedCode { color: #6c6c6c; } +--> +</style> + +<script type='text/javascript'> +<!-- + +--> +</script> +</head> +<body> +<pre id='vimCodeElement'> +<span class="Comment">//: Dead simple persistence.</span> +<span class="Comment">//: 'restore' - reads string from a file</span> +<span class="Comment">//: 'save' - writes string to a file</span> + +<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> +RESTORE<span class="Delimiter">,</span> +<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> +Recipe_ordinal[<span class="Constant">"restore"</span>] = RESTORE<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> +case RESTORE: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> + raise << <span class="Constant">"restore: illegal operand "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> + products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>new_string<span class="Delimiter">(</span>slurp<span class="Delimiter">(</span><span class="Constant">"lesson/"</span>+current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">)));</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +<span class="Delimiter">:(code)</span> +string slurp<span class="Delimiter">(</span>const string& filename<span class="Delimiter">)</span> <span class="Delimiter">{</span> +<span class="CommentedCode">//? cerr << filename << '\n'; //? 1</span> + ostringstream result<span class="Delimiter">;</span> + ifstream fin<span class="Delimiter">(</span>filename<span class="Delimiter">.</span>c_str<span class="Delimiter">());</span> + fin<span class="Delimiter">.</span>peek<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>!fin<span class="Delimiter">)</span> <span class="Identifier">return</span> result<span class="Delimiter">.</span>str<span class="Delimiter">();</span> <span class="Comment">// don't bother checking errno</span> + const int N = <span class="Constant">1024</span><span class="Delimiter">;</span> + char buf[N]<span class="Delimiter">;</span> + while <span class="Delimiter">(</span>!fin<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + bzero<span class="Delimiter">(</span>buf<span class="Delimiter">,</span> N<span class="Delimiter">);</span> + fin<span class="Delimiter">.</span>read<span class="Delimiter">(</span>buf<span class="Delimiter">,</span> N-<span class="Constant">1</span><span class="Delimiter">);</span> <span class="Comment">// leave at least one null</span> + result << buf<span class="Delimiter">;</span> + <span class="Delimiter">}</span> + fin<span class="Delimiter">.</span>close<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "=> " << result.str(); //? 1</span> + <span class="Identifier">return</span> result<span class="Delimiter">.</span>str<span class="Delimiter">();</span> +<span class="Delimiter">}</span> + +<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> +SAVE<span class="Delimiter">,</span> +<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> +Recipe_ordinal[<span class="Constant">"save"</span>] = SAVE<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> +case SAVE: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> + raise << <span class="Constant">"save: illegal operand 0 "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + string filename = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> + ostringstream tmp<span class="Delimiter">;</span> + tmp << ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> + filename = tmp<span class="Delimiter">.</span>str<span class="Delimiter">();</span> + <span class="Delimiter">}</span> + ofstream fout<span class="Delimiter">((</span><span class="Constant">"lesson/"</span>+filename<span class="Delimiter">).</span>c_str<span class="Delimiter">());</span> + if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> + raise << <span class="Constant">"save: illegal operand 1 "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + string contents = to_string<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> + fout << contents<span class="Delimiter">;</span> + fout<span class="Delimiter">.</span>close<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>!exists<span class="Delimiter">(</span><span class="Constant">"lesson/.git"</span><span class="Delimiter">))</span> <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Comment">// bug in git: git diff -q messes up --exit-code</span> + int status = system<span class="Delimiter">(</span><span class="Constant">"cd lesson; git add .; git diff HEAD --exit-code >/dev/null || git commit -a -m . >/dev/null"</span><span class="Delimiter">);</span> + if <span class="Delimiter">(</span>status != <span class="Constant">0</span><span class="Delimiter">)</span> + raise << <span class="Constant">"error in commit: contents "</span> << contents << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +<span class="Delimiter">:(code)</span> +bool exists<span class="Delimiter">(</span>const string& filename<span class="Delimiter">)</span> <span class="Delimiter">{</span> + struct stat dummy<span class="Delimiter">;</span> + <span class="Identifier">return</span> <span class="Constant">0</span> == stat<span class="Delimiter">(</span>filename<span class="Delimiter">.</span>c_str<span class="Delimiter">(),</span> &dummy<span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Delimiter">:(before "End Includes")</span> +<span class="PreProc">#include</span><span class="Constant"><sys/stat.h></span> +</pre> +</body> +</html> +<!-- vim: set foldmethod=manual : --> diff --git a/html/999spaces.cc.html b/html/999spaces.cc.html index 784a5cd5..afc434e3 100644 --- a/html/999spaces.cc.html +++ b/html/999spaces.cc.html @@ -47,8 +47,10 @@ assert<span class="Delimiter">(</span>Reserved_for_tests == <span class="Constan <span class="SalientComment">//:: Recipes</span> <span class="Comment">//:</span> <span class="Comment">//: 0 - unused (IDLE; do nothing)</span> -<span class="Comment">//: 1-99 - primitives</span> -<span class="Comment">//: 100-999 - defined in .mu files as sequences of primitives</span> +<span class="Comment">//: 1-199 - primitives</span> +assert<span class="Delimiter">(</span>MAX_PRIMITIVE_RECIPES < <span class="Constant">200</span><span class="Delimiter">);</span> +<span class="Comment">//: 200-999 - defined in .mu files as sequences of primitives</span> +assert<span class="Delimiter">(</span>Next_recipe_ordinal < <span class="Constant">1000</span><span class="Delimiter">);</span> <span class="Comment">//: 1000 onwards - reserved for tests, cleared between tests</span> <span class="SalientComment">//:: Depths for tracing</span> diff --git a/html/channel.mu.html b/html/channel.mu.html index d77a5057..2bdeb7cc 100644 --- a/html/channel.mu.html +++ b/html/channel.mu.html @@ -34,7 +34,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muRecipe">recipe</span> producer [ <span class="Comment"># produce numbers 1 to 5 on a channel</span> - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># n = 0</span> n:number<span class="Special"> <- </span>copy <span class="Constant">0:literal</span> @@ -52,7 +52,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muRecipe">recipe</span> consumer [ <span class="Comment"># consume and print integers from a channel</span> - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Delimiter">{</span> <span class="Comment"># read an integer from the channel</span> @@ -65,7 +65,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] <span class="muRecipe">recipe</span> main [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> chan:address:channel<span class="Special"> <- </span>new-channel <span class="Constant">3:literal</span> <span class="Comment"># create two background 'routines' that communicate by a channel</span> routine1:number<span class="Special"> <- </span>start-running producer:<span class="muRecipe">recipe</span>, chan:address:channel diff --git a/html/chessboard.mu.html b/html/chessboard.mu.html index 42e9f776..4e459564 100644 --- a/html/chessboard.mu.html +++ b/html/chessboard.mu.html @@ -101,27 +101,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<span class="CommentedCode">#? scenario foo [ #? 1</span> -<span class="CommentedCode">#? $print [aaa] #? 1</span> -<span class="CommentedCode">#? run [ #? 1</span> -<span class="CommentedCode">#? 1:number <- copy 34:literal #? 1</span> -<span class="CommentedCode">#? ] #? 1</span> -<span class="CommentedCode">#? memory-should-contain [ #? 1</span> -<span class="CommentedCode">#? 1 <- 34 #? 1</span> -<span class="CommentedCode">#? ] #? 1</span> -<span class="CommentedCode">#? $print [zzz] #? 1</span> -<span class="CommentedCode">#? ] #? 1</span> - <span class="SalientComment">## Here's how 'chessboard' is implemented.</span> <span class="muRecipe">recipe</span> chessboard [ <span class="CommentedCode">#? $start-tracing [schedule] #? 2</span> <span class="CommentedCode">#? $start-tracing #? 1</span> - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> console:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> -<span class="CommentedCode">#? $print [screen: ], screen:address, [, console: ], console:address, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [screen: ], screen:address, [, console: ], console:address, 10:literal/newline</span> board:address:array:address:array:character<span class="Special"> <- </span>initial-position <span class="Comment"># hook up stdin</span> stdin:address:channel<span class="Special"> <- </span>new-channel <span class="Constant">10:literal/capacity</span> @@ -133,31 +121,21 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } msg:address:array:character<span class="Special"> <- </span>new <span class="Constant">[Stupid text-mode chessboard. White pieces in uppercase; black pieces in lowercase. No checking for legal moves.</span> <span class="Constant">]</span> print-string screen:address, msg:address:array:character -<span class="CommentedCode">#? $print [aaa</span> -<span class="CommentedCode">#? ] #? 1</span> cursor-to-next-line screen:address print-board screen:address, board:address:array:address:array:character cursor-to-next-line screen:address msg:address:array:character<span class="Special"> <- </span>new <span class="Constant">[Type in your move as <from square>-<to square>. For example: 'a2-a4'. Then press <enter>.</span> <span class="Constant">]</span> print-string screen:address, msg:address:array:character -<span class="CommentedCode">#? $print [bbb</span> -<span class="CommentedCode">#? ] #? 1</span> cursor-to-next-line screen:address msg:address:array:character<span class="Special"> <- </span>new <span class="Constant">[Hit 'q' to exit.</span> <span class="Constant">]</span> print-string screen:address, msg:address:array:character -<span class="CommentedCode">#? $print [ccc</span> -<span class="CommentedCode">#? ] #? 1</span> <span class="Delimiter">{</span> cursor-to-next-line screen:address msg:address:array:character<span class="Special"> <- </span>new <span class="Constant">[move: ]</span> print-string screen:address, msg:address:array:character -<span class="CommentedCode">#? $print [ddd</span> -<span class="CommentedCode">#? ] #? 1</span> m:address:move, quit:boolean, error:boolean<span class="Special"> <- </span>read-move buffered-stdin:address:channel, screen:address -<span class="CommentedCode">#? $print [eee</span> -<span class="CommentedCode">#? ] #? 1</span> <span class="muControl">break-if</span> quit:boolean, +quit:offset buffered-stdin:address:channel<span class="Special"> <- </span>clear-channel buffered-stdin:address:channel <span class="Comment"># cleanup after error. todo: test this?</span> <span class="muControl">loop-if</span> error:boolean @@ -167,13 +145,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">loop</span> <span class="Delimiter">}</span> <span class="Constant"> +quit</span> -<span class="CommentedCode">#? $print [aaa] #? 1</span> ] <span class="SalientComment">## a board is an array of files, a file is an array of characters (squares)</span> <span class="muRecipe">recipe</span> new-board [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> initial-position:address:array:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># assert(length(initial-position) == 64)</span> len:number<span class="Special"> <- </span>length initial-position:address:array:number/deref @@ -194,7 +171,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] <span class="muRecipe">recipe</span> new-file [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> position:address:array:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> index:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> index:number<span class="Special"> <- </span>multiply index:number, <span class="Constant">8:literal</span> @@ -213,18 +190,16 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] <span class="muRecipe">recipe</span> print-board [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> board:address:array:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> row:number<span class="Special"> <- </span>copy <span class="Constant">7:literal</span> <span class="Comment"># start printing from the top of the board</span> <span class="Comment"># print each row</span> -<span class="CommentedCode">#? $print [printing board to screen ], screen:address, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [printing board to screen ], screen:address, 10:literal/newline</span> <span class="Delimiter">{</span> done?:boolean<span class="Special"> <- </span>lesser-than row:number, <span class="Constant">0:literal</span> <span class="muControl">break-if</span> done?:boolean -<span class="CommentedCode">#? $print [printing rank ], row:number, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [printing rank ], row:number, 10:literal/newline</span> <span class="Comment"># print rank number as a legend</span> rank:number<span class="Special"> <- </span>add row:number, <span class="Constant">1:literal</span> print-integer screen:address, rank:number @@ -262,7 +237,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment"># board:address:array:address:array:character <- initial-position</span> <span class="muRecipe">recipe</span> initial-position [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> <span class="Comment"># layout in memory (in raster order):</span> <span class="Comment"># R P _ _ _ _ p r</span> <span class="Comment"># N P _ _ _ _ p n</span> @@ -322,7 +297,7 @@ container move [ <span class="Comment"># result:address:move, quit?:boolean, error?:boolean <- read-move stdin:address:channel, screen:address</span> <span class="Comment"># prints only error messages to screen</span> <span class="muRecipe">recipe</span> read-move [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> stdin:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="CommentedCode">#? $print screen:address #? 1</span> @@ -357,7 +332,7 @@ container move [ <span class="Comment"># file:number, quit:boolean, error:boolean <- read-file stdin:address:channel, screen:address</span> <span class="Comment"># valid values for file: 0-7</span> <span class="muRecipe">recipe</span> read-file [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> stdin:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> c:character, stdin:address:channel<span class="Special"> <- </span>read stdin:address:channel @@ -384,8 +359,7 @@ container move [ <span class="muControl">reply</span> <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/quit</span>, <span class="Constant">1:literal/error</span> <span class="Delimiter">}</span> file:number<span class="Special"> <- </span>subtract c:character, <span class="Constant">97:literal</span> <span class="Comment"># 'a'</span> -<span class="CommentedCode">#? $print file:number, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print file:number, 10:literal/newline</span> <span class="Comment"># 'a' <= file <= 'h'</span> <span class="Delimiter">{</span> above-min:boolean<span class="Special"> <- </span>greater-or-equal file:number, <span class="Constant">0:literal</span> @@ -410,7 +384,7 @@ container move [ <span class="Comment"># rank:number <- read-rank stdin:address:channel, screen:address</span> <span class="Comment"># valid values: 0-7, -1 (quit), -2 (error)</span> <span class="muRecipe">recipe</span> read-rank [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> stdin:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> c:character, stdin:address:channel<span class="Special"> <- </span>read stdin:address:channel @@ -432,8 +406,7 @@ container move [ <span class="muControl">reply</span> <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/quit</span>, <span class="Constant">1:literal/error</span> <span class="Delimiter">}</span> rank:number<span class="Special"> <- </span>subtract c:character, <span class="Constant">49:literal</span> <span class="Comment"># '1'</span> -<span class="CommentedCode">#? $print rank:number, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print rank:number, 10:literal/newline</span> <span class="Comment"># assert'1' <= rank <= '8'</span> <span class="Delimiter">{</span> above-min:boolean<span class="Special"> <- </span>greater-or-equal rank:number, <span class="Constant">0:literal</span> @@ -457,7 +430,7 @@ container move [ <span class="Comment"># read a character from the given channel and check that it's what we expect</span> <span class="Comment"># return true on error</span> <span class="muRecipe">recipe</span> expect-from-channel [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> stdin:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> expected:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -477,30 +450,25 @@ container move [ run [ <span class="CommentedCode">#? $start-tracing #? 1</span> 1:address:channel<span class="Special"> <- </span>new-channel <span class="Constant">2:literal</span> -<span class="CommentedCode">#? $print [aaa channel address: ], 1:address:channel, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [aaa channel address: ], 1:address:channel, 10:literal/newline</span> 2:number/routine<span class="Special"> <- </span>start-running read-move:<span class="muRecipe">recipe</span>, 1:address:channel, screen:address <span class="Comment"># 'read-move' is waiting for input</span> wait-for-routine 2:number -<span class="CommentedCode">#? $print [bbb channel address: ], 1:address:channel, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [bbb channel address: ], 1:address:channel, 10:literal/newline</span> 3:number<span class="Special"> <- </span>routine-state 2:number/id -<span class="CommentedCode">#? $print [I: routine ], 2:number, [ state ], 3:number [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [I: routine ], 2:number, [ state ], 3:number 10:literal/newline</span> 4:boolean/waiting?<span class="Special"> <- </span>equal 3:number/routine-state, <span class="Constant">2:literal/waiting</span> assert 4:boolean/waiting?, [ F read-move-blocking: routine failed to pause <span class="muRecipe">after</span> coming up (<span class="muRecipe">before</span> any keys were pressed)] <span class="Comment"># press 'a'</span> -<span class="CommentedCode">#? $print [ccc channel address: ], 1:address:channel, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [ccc channel address: ], 1:address:channel, 10:literal/newline</span> <span class="CommentedCode">#? $exit #? 1</span> 1:address:channel<span class="Special"> <- </span>write 1:address:channel, <span class="Constant">97:literal</span> <span class="Comment"># 'a'</span> restart 2:number/routine <span class="Comment"># 'read-move' still waiting for input</span> wait-for-routine 2:number 3:number<span class="Special"> <- </span>routine-state 2:number/id -<span class="CommentedCode">#? $print [II: routine ], 2:number, [ state ], 3:number [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [II: routine ], 2:number, [ state ], 3:number 10:literal/newline</span> 4:boolean/waiting?<span class="Special"> <- </span>equal 3:number/routine-state, <span class="Constant">2:literal/waiting</span> assert 4:boolean/waiting?, [ F read-move-blocking: routine failed to pause <span class="muRecipe">after</span> rank 'a'] @@ -510,8 +478,7 @@ F read-move-blocking: routine failed to pause <span class="muRecipe">after</span <span class="Comment"># 'read-move' still waiting for input</span> wait-for-routine 2:number 3:number<span class="Special"> <- </span>routine-state 2:number/id -<span class="CommentedCode">#? $print [III: routine ], 2:number, [ state ], 3:number [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [III: routine ], 2:number, [ state ], 3:number 10:literal/newline</span> 4:boolean/waiting?<span class="Special"> <- </span>equal 3:number/routine-state, <span class="Constant">2:literal/waiting</span> assert 4:boolean/waiting?, [ F read-move-blocking: routine failed to pause <span class="muRecipe">after</span> file 'a2'] @@ -521,8 +488,7 @@ F read-move-blocking: routine failed to pause <span class="muRecipe">after</span <span class="Comment"># 'read-move' still waiting for input</span> wait-for-routine 2:number 3:number<span class="Special"> <- </span>routine-state 2:number -<span class="CommentedCode">#? $print [IV: routine ], 2:number, [ state ], 3:number [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [IV: routine ], 2:number, [ state ], 3:number 10:literal/newline</span> 4:boolean/waiting?<span class="Special"> <- </span>equal 3:number/routine-state, <span class="Constant">2:literal/waiting</span> assert 4:boolean/waiting?/routine-state, [ F read-move-blocking: routine failed to pause <span class="muRecipe">after</span> hyphen 'a2-'] @@ -532,8 +498,7 @@ F read-move-blocking: routine failed to pause <span class="muRecipe">after</span <span class="Comment"># 'read-move' still waiting for input</span> wait-for-routine 2:number 3:number<span class="Special"> <- </span>routine-state 2:number -<span class="CommentedCode">#? $print [V: routine ], 2:number, [ state ], 3:number [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [V: routine ], 2:number, [ state ], 3:number 10:literal/newline</span> 4:boolean/waiting?<span class="Special"> <- </span>equal 3:number/routine-state, <span class="Constant">2:literal/waiting</span> assert 4:boolean/waiting?/routine-state, [ F read-move-blocking: routine failed to pause <span class="muRecipe">after</span> rank 'a2-a'] @@ -543,8 +508,7 @@ F read-move-blocking: routine failed to pause <span class="muRecipe">after</span <span class="Comment"># 'read-move' still waiting for input</span> wait-for-routine 2:number 3:number<span class="Special"> <- </span>routine-state 2:number -<span class="CommentedCode">#? $print [VI: routine ], 2:number, [ state ], 3:number [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [VI: routine ], 2:number, [ state ], 3:number 10:literal/newline</span> 4:boolean/waiting?<span class="Special"> <- </span>equal 3:number/routine-state, <span class="Constant">2:literal/waiting</span> assert 4:boolean/waiting?, [ F read-move-blocking: routine failed to pause <span class="muRecipe">after</span> file 'a2-a4'] @@ -554,8 +518,7 @@ F read-move-blocking: routine failed to pause <span class="muRecipe">after</span <span class="Comment"># 'read-move' now completes</span> wait-for-routine 2:number 3:number<span class="Special"> <- </span>routine-state 2:number -<span class="CommentedCode">#? $print [VII: routine ], 2:number, [ state ], 3:number [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [VII: routine ], 2:number, [ state ], 3:number 10:literal/newline</span> 4:boolean/completed?<span class="Special"> <- </span>equal 3:number/routine-state, <span class="Constant">1:literal/completed</span> assert 4:boolean/completed?, [ F read-move-blocking: routine failed to terminate on newline] @@ -659,27 +622,22 @@ F read-move-file: routine failed to pause <span class="muRecipe">after</span> co ] <span class="muRecipe">recipe</span> make-move [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> b:address:array:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> m:address:move<span class="Special"> <- </span><span class="Constant">next-ingredient</span> from-file:number<span class="Special"> <- </span>get m:address:move/deref, from-file:offset -<span class="CommentedCode">#? $print from-file:number, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print from-file:number, 10:literal/newline</span> from-rank:number<span class="Special"> <- </span>get m:address:move/deref, from-rank:offset -<span class="CommentedCode">#? $print from-rank:number, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print from-rank:number, 10:literal/newline</span> to-file:number<span class="Special"> <- </span>get m:address:move/deref, to-file:offset -<span class="CommentedCode">#? $print to-file:number, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print to-file:number, 10:literal/newline</span> to-rank:number<span class="Special"> <- </span>get m:address:move/deref, to-rank:offset -<span class="CommentedCode">#? $print to-rank:number, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print to-rank:number, 10:literal/newline</span> f:address:array:character<span class="Special"> <- </span>index b:address:array:address:array:character/deref, from-file:number src:address:character/square<span class="Special"> <- </span>index-address f:address:array:character/deref, from-rank:number f:address:array:character<span class="Special"> <- </span>index b:address:array:address:array:character/deref, to-file:number dest:address:character/square<span class="Special"> <- </span>index-address f:address:array:character/deref, to-rank:number -<span class="CommentedCode">#? $print src:address:character/deref, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print src:address:character/deref, 10:literal/newline</span> dest:address:character/deref/square<span class="Special"> <- </span>copy src:address:character/deref/square src:address:character/deref/square<span class="Special"> <- </span>copy <span class="Constant">32:literal</span> <span class="Comment"># ' '</span> <span class="muControl">reply</span> b:address:array:address:array:character/same-as-ingredient:0 diff --git a/html/counters.mu.html b/html/counters.mu.html index 1e76afdf..7bba9ad8 100644 --- a/html/counters.mu.html +++ b/html/counters.mu.html @@ -39,7 +39,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] <span class="muRecipe">recipe</span> increment-counter [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> 0:address:array:location/names:new-counter<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># setup outer space; it *must* come from 'new-counter'</span> x:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> n:number/space:1<span class="Special"> <- </span>add n:number/space:1, x:number @@ -47,7 +47,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] <span class="muRecipe">recipe</span> main [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> <span class="Comment"># counter A</span> a:address:array:location<span class="Special"> <- </span>new-counter <span class="Constant">34:literal</span> <span class="Comment"># counter B</span> diff --git a/html/edit.mu.html b/html/edit.mu.html index 078fac53..fd76d06c 100644 --- a/html/edit.mu.html +++ b/html/edit.mu.html @@ -36,17 +36,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment"># Environment for learning programming using mu.</span> <span class="muRecipe">recipe</span> main [ - <span class="Constant">new-default-space</span> - open-console - initial-recipe:address:array:character<span class="Special"> <- </span>new <span class="Constant">[recipe new-add [</span> -<span class="Constant"> x:number <- next-ingredient</span> -<span class="Constant"> y:number <- next-ingredient</span> -<span class="Constant"> z:number <- add x:number, y:number</span> -<span class="Constant"> reply z:number</span> -<span class="Constant">]</span>] - initial-sandbox:address:array:character<span class="Special"> <- </span>new <span class="Constant">[new-add 2:literal, 3:literal]</span> + <span class="Constant">local-scope</span> + open-console <span class="CommentedCode">#? 1</span> + initial-recipe:address:array:character<span class="Special"> <- </span>restore <span class="Constant">[recipes.mu]</span> +<span class="CommentedCode">#? $exit #? 1</span> + initial-sandbox:address:array:character<span class="Special"> <- </span>new <span class="Constant">[test 2, 2]</span> env:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment <span class="Constant">0:literal/screen</span>, initial-recipe:address:array:character, initial-sandbox:address:array:character - render-all <span class="Constant">0:literal/address</span>, env:address:programming-environment-data event-loop <span class="Constant">0:literal/screen</span>, <span class="Constant">0:literal/console</span>, env:address:programming-environment-data ] @@ -59,7 +54,7 @@ container programming-environment-data [ ] <span class="muRecipe">recipe</span> new-programming-environment [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> initial-recipe-contents:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> initial-sandbox-contents:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -85,8 +80,7 @@ container programming-environment-data [ new-right:number<span class="Special"> <- </span>add new-left:number, <span class="Constant">5:literal</span> current-sandbox:address:address:editor-data<span class="Special"> <- </span>get-address result:address:programming-environment-data/deref, current-sandbox:offset current-sandbox:address:address:editor-data/deref<span class="Special"> <- </span>new-editor initial-sandbox-contents:address:array:character, screen:address, new-left:number, width:number - <span class="Comment"># initialize cursor</span> - update-cursor screen:address, recipes:address:address:editor-data/deref, current-sandbox:address:address:editor-data/deref, <span class="Constant">0:literal/focus-in-recipes</span> + screen:address<span class="Special"> <- </span>render-all screen:address, result:address:programming-environment-data <span class="muControl">reply</span> result:address:programming-environment-data ] @@ -126,7 +120,7 @@ container editor-data [ <span class="Comment"># top/left/right constrain the screen area available to the new editor.</span> <span class="Comment"># right is exclusive.</span> <span class="muRecipe">recipe</span> new-editor [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> s:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># no clipping of bounds</span> @@ -196,7 +190,7 @@ container editor-data [ <span class="Comment"># bottom:number, screen:address <- render screen:address, editor:address:editor-data</span> <span class="muRecipe">recipe</span> render [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="muControl">reply-unless</span> editor:address:editor-data, <span class="Constant">1:literal/top</span>, screen:address/same-as-ingredient:0 @@ -204,6 +198,9 @@ container editor-data [ screen-height:number<span class="Special"> <- </span>screen-height screen:address right:number<span class="Special"> <- </span>get editor:address:editor-data/deref, right:offset hide-screen screen:address + <span class="Comment"># highlight mu code with color</span> + color:number<span class="Special"> <- </span>copy <span class="Constant">7:literal/white</span> + highlighting-state:number<span class="Special"> <- </span>copy <span class="Constant">0:literal/normal</span> <span class="Comment"># traversing editor</span> curr:address:duplex-list<span class="Special"> <- </span>get editor:address:editor-data/deref, data:offset prev:address:duplex-list<span class="Special"> <- </span>copy curr:address:duplex-list @@ -231,6 +228,7 @@ container editor-data [ before-cursor:address:address:duplex-list/deref<span class="Special"> <- </span>prev-duplex curr:address:duplex-list <span class="Delimiter">}</span> c:character<span class="Special"> <- </span>get curr:address:duplex-list/deref, value:offset + color:number, highlighting-state:number<span class="Special"> <- </span>get-color color:number, highlighting-state:number, c:character <span class="Delimiter">{</span> <span class="Comment"># newline? move to left rather than 0</span> newline?:boolean<span class="Special"> <- </span>equal c:character, <span class="Constant">10:literal/newline</span> @@ -267,7 +265,7 @@ container editor-data [ <span class="Comment"># don't increment curr</span> <span class="muControl">loop</span> <span class="Constant">+next-character:label</span> <span class="Delimiter">}</span> - print-character screen:address, c:character + print-character screen:address, c:character, color:number curr:address:duplex-list<span class="Special"> <- </span>next-duplex curr:address:duplex-list prev:address:duplex-list<span class="Special"> <- </span>next-duplex prev:address:duplex-list column:number<span class="Special"> <- </span>add column:number, <span class="Constant">1:literal</span> @@ -300,10 +298,11 @@ container editor-data [ ] <span class="Comment"># row:number, screen:address <- render-string screen:address, s:address:array:character, left:number, right:number, color:number, row:number</span> +<span class="Comment"># move cursor at start of next line</span> <span class="Comment"># print a string 's' to 'editor' in 'color' starting at 'row'</span> -<span class="Comment"># leave cursor at start of next line</span> +<span class="Comment"># clear rest of last line, but don't move cursor to next line</span> <span class="muRecipe">recipe</span> render-string [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> s:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> left:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -368,8 +367,77 @@ container editor-data [ <span class="muControl">reply</span> row:number/same-as-ingredient:5, screen:address/same-as-ingredient:0 ] +<span class="Comment"># row:number, screen:address <- render-screen screen:address, sandbox-screen:address, left:number, right:number, row:number</span> +<span class="Comment"># print the fake sandbox screen to 'screen' with appropriate delimiters</span> +<span class="Comment"># leave cursor at start of next line</span> +<span class="muRecipe">recipe</span> render-screen [ + <span class="Constant">local-scope</span> + screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + s:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + left:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + right:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + row:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + row:number<span class="Special"> <- </span>add row:number, <span class="Constant">1:literal</span> + <span class="muControl">reply-unless</span> s:address:screen, row:number/same-as-ingredient:4, screen:address/same-as-ingredient:0 + <span class="Comment"># print 'screen:'</span> + header:address:array:character<span class="Special"> <- </span>new <span class="Constant">[screen:]</span> + row:number<span class="Special"> <- </span>subtract row:number, <span class="Constant">1:literal</span> <span class="Comment"># compensate for render-string below</span> + row:number<span class="Special"> <- </span>render-string screen:address, header:address:array:character, left:number, right:number, <span class="Constant">245:literal/grey</span>, row:number + <span class="Comment"># newline</span> + row:number<span class="Special"> <- </span>add row:number, <span class="Constant">1:literal</span> + move-cursor screen:address, row:number, left:number + <span class="Comment"># start printing s</span> + column:number<span class="Special"> <- </span>copy left:number + s-width:number<span class="Special"> <- </span>screen-width s:address:screen + s-height:number<span class="Special"> <- </span>screen-height s:address:screen + buf:address:array:screen-cell<span class="Special"> <- </span>get s:address:screen/deref, data:offset + stop-printing:number<span class="Special"> <- </span>add left:number, s-width:number, <span class="Constant">3:literal</span> + max-column:number<span class="Special"> <- </span>min stop-printing:number, right:number + i:number<span class="Special"> <- </span>copy <span class="Constant">0:literal</span> + len:number<span class="Special"> <- </span>length buf:address:array:screen-cell/deref + screen-height:number<span class="Special"> <- </span>screen-height screen:address + <span class="Delimiter">{</span> + done?:boolean<span class="Special"> <- </span>greater-or-equal i:number, len:number + <span class="muControl">break-if</span> done?:boolean + done?:boolean<span class="Special"> <- </span>greater-or-equal row:number, screen-height:number + <span class="muControl">break-if</span> done?:boolean + column:number<span class="Special"> <- </span>copy left:number + move-cursor screen:address, row:number, column:number + <span class="Comment"># initial leader for each row: two spaces and a '.'</span> + print-character screen:address, <span class="Constant">32:literal/space</span>, <span class="Constant">245:literal/grey</span> + print-character screen:address, <span class="Constant">32:literal/space</span>, <span class="Constant">245:literal/grey</span> + print-character screen:address, <span class="Constant">46:literal/full-stop</span>, <span class="Constant">245:literal/grey</span> + column:number<span class="Special"> <- </span>add left:number, <span class="Constant">3:literal</span> + <span class="Delimiter">{</span> + <span class="Comment"># print row</span> + row-done?:boolean<span class="Special"> <- </span>greater-or-equal column:number, max-column:number + <span class="muControl">break-if</span> row-done?:boolean + curr:screen-cell<span class="Special"> <- </span>index buf:address:array:screen-cell/deref, i:number + c:character<span class="Special"> <- </span>get curr:screen-cell, contents:offset + print-character screen:address, c:character, <span class="Constant">245:literal/grey</span> + column:number<span class="Special"> <- </span>add column:number, <span class="Constant">1:literal</span> + i:number<span class="Special"> <- </span>add i:number, <span class="Constant">1:literal</span> + <span class="muControl">loop</span> + <span class="Delimiter">}</span> + <span class="Comment"># print final '.'</span> + print-character screen:address, <span class="Constant">46:literal/full-stop</span>, <span class="Constant">245:literal/grey</span> + column:number<span class="Special"> <- </span>add column:number, <span class="Constant">1:literal</span> + <span class="Delimiter">{</span> + <span class="Comment"># clear rest of current line</span> + line-done?:boolean<span class="Special"> <- </span>greater-than column:number, right:number + <span class="muControl">break-if</span> line-done?:boolean + print-character screen:address, <span class="Constant">32:literal/space</span> + column:number<span class="Special"> <- </span>add column:number, <span class="Constant">1:literal</span> + <span class="muControl">loop</span> + <span class="Delimiter">}</span> + row:number<span class="Special"> <- </span>add row:number, <span class="Constant">1:literal</span> + <span class="muControl">loop</span> + <span class="Delimiter">}</span> + <span class="muControl">reply</span> row:number/same-as-ingredient:4, screen:address/same-as-ingredient:0 +] + <span class="muRecipe">recipe</span> clear-line-delimited [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> left:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> right:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -438,7 +506,7 @@ container editor-data [ <span class="Constant"> .def .</span> <span class="Constant"> . .</span> ] - screen-should-contain-in-color, <span class="Constant">245:literal/grey</span> [ + screen-should-contain-in-color <span class="Constant">245:literal/grey</span> [ <span class="Constant"> . .</span> <span class="Constant"> . ↩.</span> <span class="Constant"> . .</span> @@ -460,7 +528,7 @@ container editor-data [ <span class="Constant"> .e .</span> <span class="Constant"> . .</span> ] - screen-should-contain-in-color, <span class="Constant">245:literal/grey</span> [ + screen-should-contain-in-color <span class="Constant">245:literal/grey</span> [ <span class="Constant"> . .</span> <span class="Constant"> . ↩.</span> <span class="Constant"> . .</span> @@ -487,10 +555,116 @@ container editor-data [ ] ] +<span class="SalientComment">## highlighting mu code</span> + +<span class="muScenario">scenario</span> render-colors-comments [ + assume-screen <span class="Constant">5:literal/width</span>, <span class="Constant">5:literal/height</span> + run [ + s:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span> +<span class="Constant"># de</span> +<span class="Constant">f]</span> + new-editor s:address:array:character, screen:address, <span class="Constant">0:literal/left</span>, <span class="Constant">5:literal/right</span> + ] + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .abc .</span> + <span class="Constant"> .# de .</span> + <span class="Constant"> .f .</span> + <span class="Constant"> . .</span> + ] + screen-should-contain-in-color <span class="Constant">12:literal/lightblue</span>, [ + <span class="Constant"> . .</span> + <span class="Constant"> . .</span> + <span class="Constant"> .# de .</span> + <span class="Constant"> . .</span> + <span class="Constant"> . .</span> + ] + screen-should-contain-in-color <span class="Constant">7:literal/white</span>, [ + <span class="Constant"> . .</span> + <span class="Constant"> .abc .</span> + <span class="Constant"> . .</span> + <span class="Constant"> .f .</span> + <span class="Constant"> . .</span> + ] +] + +<span class="Comment"># color:number, highlighting-state:number <- get-color color:number, highlighting-state:number, c:character</span> +<span class="muRecipe">recipe</span> get-color [ + <span class="Constant">local-scope</span> + color:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + highlighting-state:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + c:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + color-is-white?:boolean<span class="Special"> <- </span>equal color:number, <span class="Constant">7:literal/white</span> +<span class="CommentedCode">#? $print [character: ], c:character, 10:literal/newline #? 1</span> + <span class="Comment"># if color is white and next character is '#', switch color to blue</span> + <span class="Delimiter">{</span> + <span class="muControl">break-unless</span> color-is-white?:boolean + starting-comment?:boolean<span class="Special"> <- </span>equal c:character, <span class="Constant">35:literal/#</span> + <span class="muControl">break-unless</span> starting-comment?:boolean +<span class="CommentedCode">#? $print [switch color back to blue], 10:literal/newline #? 1</span> + color:number<span class="Special"> <- </span>copy <span class="Constant">12:literal/lightblue</span> + <span class="muControl">jump</span> <span class="Constant">+exit:label</span> + <span class="Delimiter">}</span> + <span class="Comment"># if color is blue and next character is newline, switch color to white</span> + <span class="Delimiter">{</span> + color-is-blue?:boolean<span class="Special"> <- </span>equal color:number, <span class="Constant">12:literal/lightblue</span> + <span class="muControl">break-unless</span> color-is-blue?:boolean + ending-comment?:boolean<span class="Special"> <- </span>equal c:character, <span class="Constant">10:literal/newline</span> + <span class="muControl">break-unless</span> ending-comment?:boolean +<span class="CommentedCode">#? $print [switch color back to white], 10:literal/newline #? 1</span> + color:number<span class="Special"> <- </span>copy <span class="Constant">7:literal/white</span> + <span class="muControl">jump</span> <span class="Constant">+exit:label</span> + <span class="Delimiter">}</span> + <span class="Comment"># if color is white (no comments) and next character is '<', switch color to red</span> + <span class="Delimiter">{</span> + <span class="muControl">break-unless</span> color-is-white?:boolean + starting-assignment?:boolean<span class="Special"> <- </span>equal c:character, <span class="Constant">60:literal/<</span> + <span class="muControl">break-unless</span> starting-assignment?:boolean + color:number<span class="Special"> <- </span>copy <span class="Constant">1:literal/red</span> + <span class="muControl">jump</span> <span class="Constant">+exit:label</span> + <span class="Delimiter">}</span> + <span class="Comment"># if color is red and next character is space, switch color to white</span> + <span class="Delimiter">{</span> + color-is-red?:boolean<span class="Special"> <- </span>equal color:number, <span class="Constant">1:literal/red</span> + <span class="muControl">break-unless</span> color-is-red?:boolean + ending-assignment?:boolean<span class="Special"> <- </span>equal c:character, <span class="Constant">32:literal/space</span> + <span class="muControl">break-unless</span> ending-assignment?:boolean + color:number<span class="Special"> <- </span>copy <span class="Constant">7:literal/white</span> + <span class="muControl">jump</span> <span class="Constant">+exit:label</span> + <span class="Delimiter">}</span> + <span class="Comment"># otherwise no change</span> +<span class="Constant"> +exit</span> + <span class="muControl">reply</span> color:number, highlighting-state:number +] + +<span class="muScenario">scenario</span> render-colors-assignment [ + assume-screen <span class="Constant">8:literal/width</span>, <span class="Constant">5:literal/height</span> + run [ + s:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span> +<span class="Constant">d <- e</span> +<span class="Constant">f]</span> + new-editor s:address:array:character, screen:address, <span class="Constant">0:literal/left</span>, <span class="Constant">8:literal/right</span> + ] + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .abc .</span> + <span class="Constant"> .d <- e .</span> + <span class="Constant"> .f .</span> + <span class="Constant"> . .</span> + ] + screen-should-contain-in-color <span class="Constant">1:literal/red</span>, [ + <span class="Constant"> . .</span> + <span class="Constant"> . .</span> + <span class="Constant"> . <- .</span> + <span class="Constant"> . .</span> + <span class="Constant"> . .</span> + ] +] + <span class="SalientComment">## handling events from the keyboard, mouse, touch screen, ...</span> <span class="muRecipe">recipe</span> event-loop [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> console:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -513,13 +687,26 @@ container editor-data [ do-run?:boolean<span class="Special"> <- </span>equal k:address:number/deref, <span class="Constant">65526:literal/F10</span> <span class="muControl">break-unless</span> do-run?:boolean run-sandboxes env:address:programming-environment-data - <span class="muControl">jump</span> <span class="Constant">+continue:label</span> + screen:address<span class="Special"> <- </span>render-sandbox-side screen:address, env:address:programming-environment-data + <span class="Comment"># F10 doesn't mess with the recipe side</span> + update-cursor screen:address, recipes:address:editor-data, current-sandbox:address:editor-data, sandbox-in-focus?:address:boolean/deref + show-screen screen:address + <span class="muControl">loop</span> <span class="Constant">+next-event:label</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> - <span class="Comment"># 'touch' event - send to both editors</span> + <span class="Comment"># 'touch' event</span> <span class="Delimiter">{</span> t:address:touch-event<span class="Special"> <- </span>maybe-convert e:event, touch:variant <span class="muControl">break-unless</span> t:address:touch-event + <span class="Comment"># on a sandbox delete icon? process delete</span> + <span class="Delimiter">{</span> + was-delete?:boolean<span class="Special"> <- </span>delete-sandbox t:address:touch-event/deref, env:address:programming-environment-data + <span class="muControl">break-unless</span> was-delete?:boolean + screen:address<span class="Special"> <- </span>render-sandbox-side screen:address, env:address:programming-environment-data, <span class="Constant">1:literal/clear</span> + update-cursor screen:address, recipes:address:editor-data, current-sandbox:address:editor-data, sandbox-in-focus?:address:boolean/deref + <span class="muControl">loop</span> <span class="Constant">+next-event:label</span> + <span class="Delimiter">}</span> + <span class="Comment"># if not, send to both editors</span> _<span class="Special"> <- </span>move-cursor-in-editor screen:address, recipes:address:editor-data, t:address:touch-event/deref sandbox-in-focus?:address:boolean/deref<span class="Special"> <- </span>move-cursor-in-editor screen:address, current-sandbox:address:editor-data, t:address:touch-event/deref <span class="muControl">jump</span> <span class="Constant">+continue:label</span> @@ -536,12 +723,14 @@ container editor-data [ <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Constant"> +continue</span> - <span class="Comment"># if no more events currently left to process, render</span> + <span class="Comment"># if no more events currently left to process, render.</span> + <span class="Comment"># we rely on 'render' to update 'before-cursor' on pointer events, but</span> + <span class="Comment"># they won't usually come fast enough to trigger this.</span> <span class="Comment"># todo: test this</span> <span class="Delimiter">{</span> more-events?:boolean<span class="Special"> <- </span>has-more-events? console:address <span class="muControl">break-if</span> more-events?:boolean - render-all screen:address, env:address:programming-environment-data + render-minimal screen:address, env:address:programming-environment-data <span class="Delimiter">}</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> @@ -549,7 +738,7 @@ container editor-data [ <span class="Comment"># helper for testing a single editor</span> <span class="muRecipe">recipe</span> editor-event-loop [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> console:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -582,16 +771,17 @@ container editor-data [ ] <span class="muRecipe">recipe</span> handle-event [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> console:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> e:event<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="muControl">reply-unless</span> editor:address:editor-data - <span class="Comment"># typing a character</span> + <span class="Comment"># character</span> <span class="Delimiter">{</span> c:address:character<span class="Special"> <- </span>maybe-convert e:event, text:variant <span class="muControl">break-unless</span> c:address:character + <span class="Comment"># check for special characters</span> <span class="Comment"># unless it's a backspace</span> <span class="Delimiter">{</span> backspace?:boolean<span class="Special"> <- </span>equal c:address:character/deref, <span class="Constant">8:literal/backspace</span> @@ -599,10 +789,39 @@ container editor-data [ delete-before-cursor editor:address:editor-data <span class="muControl">reply</span> <span class="Delimiter">}</span> + <span class="Comment"># ctrl-a</span> + <span class="Delimiter">{</span> + ctrl-a?:boolean<span class="Special"> <- </span>equal c:address:character/deref, <span class="Constant">1:literal/ctrl-a</span> + <span class="muControl">break-unless</span> ctrl-a?:boolean + move-to-start-of-line editor:address:editor-data + <span class="muControl">reply</span> + <span class="Delimiter">}</span> + <span class="Comment"># ctrl-e</span> + <span class="Delimiter">{</span> + ctrl-e?:boolean<span class="Special"> <- </span>equal c:address:character/deref, <span class="Constant">5:literal/ctrl-e</span> + <span class="muControl">break-unless</span> ctrl-e?:boolean + move-to-end-of-line editor:address:editor-data + <span class="muControl">reply</span> + <span class="Delimiter">}</span> + <span class="Comment"># ctrl-u</span> + <span class="Delimiter">{</span> + ctrl-u?:boolean<span class="Special"> <- </span>equal c:address:character/deref, <span class="Constant">21:literal/ctrl-u</span> + <span class="muControl">break-unless</span> ctrl-u?:boolean + delete-to-start-of-line editor:address:editor-data + <span class="muControl">reply</span> + <span class="Delimiter">}</span> + <span class="Comment"># ctrl-k</span> + <span class="Delimiter">{</span> + ctrl-k?:boolean<span class="Special"> <- </span>equal c:address:character/deref, <span class="Constant">11:literal/ctrl-k</span> + <span class="muControl">break-unless</span> ctrl-k?:boolean + delete-to-end-of-line editor:address:editor-data + <span class="muControl">reply</span> + <span class="Delimiter">}</span> + <span class="Comment"># otherwise type it in</span> insert-at-cursor editor:address:editor-data, c:address:character/deref, screen:address <span class="muControl">reply</span> <span class="Delimiter">}</span> - <span class="Comment"># otherwise it's a special key to control the editor</span> + <span class="Comment"># otherwise it's a special key</span> k:address:number<span class="Special"> <- </span>maybe-convert e:event, keycode:variant assert k:address:number, <span class="Constant">[event was of unknown type; neither keyboard nor mouse]</span> d:address:duplex-list<span class="Special"> <- </span>get editor:address:editor-data/deref, data:offset @@ -716,12 +935,26 @@ container editor-data [ cursor-row:address:number/deref<span class="Special"> <- </span>subtract cursor-row:address:number/deref, <span class="Constant">1:literal</span> <span class="Comment"># that's it; render will adjust cursor-column as necessary</span> <span class="Delimiter">}</span> + <span class="Comment"># home</span> + <span class="Delimiter">{</span> + home?:boolean<span class="Special"> <- </span>equal k:address:number/deref, <span class="Constant">65521:literal/home</span> + <span class="muControl">break-unless</span> home?:boolean + move-to-start-of-line editor:address:editor-data + <span class="muControl">reply</span> + <span class="Delimiter">}</span> + <span class="Comment"># end</span> + <span class="Delimiter">{</span> + end?:boolean<span class="Special"> <- </span>equal k:address:number/deref, <span class="Constant">65520:literal/end</span> + <span class="muControl">break-unless</span> end?:boolean + move-to-end-of-line editor:address:editor-data + <span class="muControl">reply</span> + <span class="Delimiter">}</span> ] <span class="Comment"># process click, return if it was on current editor</span> <span class="Comment"># todo: ignores menu bar (for now just displays shortcuts)</span> <span class="muRecipe">recipe</span> move-cursor-in-editor [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> t:touch-event<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -738,18 +971,16 @@ container editor-data [ cursor-row:address:number/deref<span class="Special"> <- </span>get t:touch-event, row:offset cursor-column:address:number<span class="Special"> <- </span>get-address editor:address:editor-data/deref, cursor-column:offset cursor-column:address:number/deref<span class="Special"> <- </span>get t:touch-event, column:offset - render screen:address, editor:address:editor-data <span class="Comment"># gain focus</span> <span class="muControl">reply</span> <span class="Constant">1:literal/true</span> ] <span class="muRecipe">recipe</span> insert-at-cursor [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> c:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> -<span class="CommentedCode">#? $print [insert ], c:character, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [insert ], c:character, 10:literal/newline</span> before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address editor:address:editor-data/deref, before-cursor:offset d:address:duplex-list<span class="Special"> <- </span>get editor:address:editor-data/deref, data:offset insert-duplex c:character, before-cursor:address:address:duplex-list/deref @@ -771,8 +1002,7 @@ container editor-data [ <span class="Delimiter">{</span> <span class="Comment"># if we're at the column just before the wrap indicator</span> wrap-column:number<span class="Special"> <- </span>subtract right:number, <span class="Constant">1:literal</span> -<span class="CommentedCode">#? $print [wrap? ], cursor-column:address:number/deref, [ vs ], wrap-column:number, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [wrap? ], cursor-column:address:number/deref, [ vs ], wrap-column:number, 10:literal/newline</span> at-wrap?:boolean<span class="Special"> <- </span>greater-or-equal cursor-column:address:number/deref, wrap-column:number <span class="muControl">break-unless</span> at-wrap?:boolean <span class="CommentedCode">#? $print [wrap!</span> @@ -792,7 +1022,7 @@ container editor-data [ ] <span class="muRecipe">recipe</span> delete-before-cursor [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address editor:address:editor-data/deref, before-cursor:offset d:address:duplex-list<span class="Special"> <- </span>get editor:address:editor-data/deref, data:offset @@ -806,14 +1036,13 @@ container editor-data [ before-cursor:address:address:duplex-list/deref<span class="Special"> <- </span>copy prev:address:duplex-list cursor-column:address:number<span class="Special"> <- </span>get-address editor:address:editor-data/deref, cursor-column:offset cursor-column:address:number/deref<span class="Special"> <- </span>subtract cursor-column:address:number/deref, <span class="Constant">1:literal</span> -<span class="CommentedCode">#? $print [delete-before-cursor: ], cursor-column:address:number/deref, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [delete-before-cursor: ], cursor-column:address:number/deref, 10:literal/newline</span> ] <span class="Comment"># takes a pointer 'curr' into the doubly-linked list and its sentinel, counts</span> <span class="Comment"># the length of the previous line before the 'curr' pointer.</span> <span class="muRecipe">recipe</span> previous-line-length [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> curr:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span> start:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span> result:number<span class="Special"> <- </span>copy <span class="Constant">0:literal</span> @@ -834,24 +1063,159 @@ container editor-data [ <span class="muControl">reply</span> result:number ] +<span class="muRecipe">recipe</span> move-to-start-of-line [ + <span class="Constant">local-scope</span> + editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Comment"># update cursor column</span> + left:number<span class="Special"> <- </span>get editor:address:editor-data/deref, left:offset + cursor-column:address:number<span class="Special"> <- </span>get-address editor:address:editor-data/deref, cursor-column:offset + cursor-column:address:number/deref<span class="Special"> <- </span>copy left:number + <span class="Comment"># update before-cursor</span> + before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address editor:address:editor-data/deref, before-cursor:offset + init:address:duplex-list<span class="Special"> <- </span>get editor:address:editor-data/deref, data:offset + <span class="Comment"># while not at start of line, move </span> + <span class="Delimiter">{</span> + at-start-of-text?:boolean<span class="Special"> <- </span>equal before-cursor:address:address:duplex-list/deref, init:address:duplex-list + <span class="muControl">break-if</span> at-start-of-text?:boolean + prev:character<span class="Special"> <- </span>get before-cursor:address:address:duplex-list/deref/deref, value:offset + at-start-of-line?:boolean<span class="Special"> <- </span>equal prev:character, <span class="Constant">10:literal/newline</span> + <span class="muControl">break-if</span> at-start-of-line?:boolean + before-cursor:address:address:duplex-list/deref<span class="Special"> <- </span>prev-duplex before-cursor:address:address:duplex-list/deref + assert before-cursor:address:address:duplex-list/deref, <span class="Constant">[move-to-start-of-line tried to move before start of text]</span> + <span class="muControl">loop</span> + <span class="Delimiter">}</span> +] + +<span class="muRecipe">recipe</span> move-to-end-of-line [ + <span class="Constant">local-scope</span> + editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address editor:address:editor-data/deref, before-cursor:offset + cursor-column:address:number<span class="Special"> <- </span>get-address editor:address:editor-data/deref, cursor-column:offset + <span class="Comment"># while not at start of line, move </span> + <span class="Delimiter">{</span> + next:address:duplex-list<span class="Special"> <- </span>next-duplex before-cursor:address:address:duplex-list/deref + <span class="muControl">break-unless</span> next:address:duplex-list <span class="Comment"># end of text</span> + nextc:character<span class="Special"> <- </span>get next:address:duplex-list/deref, value:offset + at-end-of-line?:boolean<span class="Special"> <- </span>equal nextc:character, <span class="Constant">10:literal/newline</span> + <span class="muControl">break-if</span> at-end-of-line?:boolean + before-cursor:address:address:duplex-list/deref<span class="Special"> <- </span>copy next:address:duplex-list + cursor-column:address:number/deref<span class="Special"> <- </span>add cursor-column:address:number/deref, <span class="Constant">1:literal</span> + <span class="muControl">loop</span> + <span class="Delimiter">}</span> + <span class="Comment"># move one past end of line</span> + cursor-column:address:number/deref<span class="Special"> <- </span>add cursor-column:address:number/deref, <span class="Constant">1:literal</span> +] + +<span class="muRecipe">recipe</span> delete-to-start-of-line [ + <span class="Constant">local-scope</span> + editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Comment"># compute range to delete</span> + init:address:duplex-list<span class="Special"> <- </span>get editor:address:editor-data/deref, data:offset + before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address editor:address:editor-data/deref, before-cursor:offset + start:address:duplex-list<span class="Special"> <- </span>copy before-cursor:address:address:duplex-list/deref + end:address:duplex-list<span class="Special"> <- </span>next-duplex before-cursor:address:address:duplex-list/deref + <span class="Delimiter">{</span> + at-start-of-text?:boolean<span class="Special"> <- </span>equal start:address:duplex-list, init:address:duplex-list + <span class="muControl">break-if</span> at-start-of-text?:boolean + curr:character<span class="Special"> <- </span>get start:address:duplex-list/deref, value:offset + at-start-of-line?:boolean<span class="Special"> <- </span>equal curr:character, <span class="Constant">10:literal/newline</span> + <span class="muControl">break-if</span> at-start-of-line?:boolean + start:address:duplex-list<span class="Special"> <- </span>prev-duplex start:address:duplex-list + assert start:address:duplex-list, <span class="Constant">[delete-to-start-of-line tried to move before start of text]</span> + <span class="muControl">loop</span> + <span class="Delimiter">}</span> + <span class="Comment"># snip it out</span> + start-next:address:address:duplex-list<span class="Special"> <- </span>get-address start:address:duplex-list/deref, next:offset + start-next:address:address:duplex-list/deref<span class="Special"> <- </span>copy end:address:duplex-list + end-prev:address:address:duplex-list<span class="Special"> <- </span>get-address end:address:duplex-list/deref, prev:offset + end-prev:address:address:duplex-list/deref<span class="Special"> <- </span>copy start:address:duplex-list + <span class="Comment"># adjust cursor</span> + before-cursor:address:address:duplex-list/deref<span class="Special"> <- </span>prev-duplex end:address:duplex-list + left:number<span class="Special"> <- </span>get editor:address:editor-data/deref, left:offset + cursor-column:address:number<span class="Special"> <- </span>get-address editor:address:editor-data/deref, cursor-column:offset + cursor-column:address:number/deref<span class="Special"> <- </span>copy left:number +] + +<span class="muRecipe">recipe</span> delete-to-end-of-line [ + <span class="Constant">local-scope</span> + editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Comment"># compute range to delete</span> + start:address:duplex-list<span class="Special"> <- </span>get editor:address:editor-data/deref, before-cursor:offset + end:address:duplex-list<span class="Special"> <- </span>next-duplex start:address:duplex-list + <span class="Delimiter">{</span> + at-end-of-text?:boolean<span class="Special"> <- </span>equal end:address:duplex-list, <span class="Constant">0:literal/null</span> + <span class="muControl">break-if</span> at-end-of-text?:boolean + curr:character<span class="Special"> <- </span>get end:address:duplex-list/deref, value:offset + at-end-of-line?:boolean<span class="Special"> <- </span>equal curr:character, <span class="Constant">10:literal/newline</span> + <span class="muControl">break-if</span> at-end-of-line?:boolean + end:address:duplex-list<span class="Special"> <- </span>next-duplex end:address:duplex-list + <span class="muControl">loop</span> + <span class="Delimiter">}</span> + <span class="Comment"># snip it out</span> + start-next:address:address:duplex-list<span class="Special"> <- </span>get-address start:address:duplex-list/deref, next:offset + start-next:address:address:duplex-list/deref<span class="Special"> <- </span>copy end:address:duplex-list + <span class="Delimiter">{</span> + <span class="muControl">break-unless</span> end:address:duplex-list + end-prev:address:address:duplex-list<span class="Special"> <- </span>get-address end:address:duplex-list/deref, prev:offset + end-prev:address:address:duplex-list/deref<span class="Special"> <- </span>copy start:address:duplex-list + <span class="Delimiter">}</span> +] + <span class="muRecipe">recipe</span> render-all [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> + screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + screen:address<span class="Special"> <- </span>render-recipes screen:address, env:address:programming-environment-data + screen:address<span class="Special"> <- </span>render-sandbox-side screen:address, env:address:programming-environment-data + recipes:address:editor-data<span class="Special"> <- </span>get env:address:programming-environment-data/deref, recipes:offset + current-sandbox:address:editor-data<span class="Special"> <- </span>get env:address:programming-environment-data/deref, current-sandbox:offset + sandbox-in-focus?:boolean<span class="Special"> <- </span>get env:address:programming-environment-data/deref, sandbox-in-focus?:offset + update-cursor screen:address, recipes:address:editor-data, current-sandbox:address:editor-data, sandbox-in-focus?:boolean + show-screen screen:address + <span class="muControl">reply</span> screen:address/same-as-ingredient:0 +] + +<span class="muRecipe">recipe</span> render-minimal [ + <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> recipes:address:editor-data<span class="Special"> <- </span>get env:address:programming-environment-data/deref, recipes:offset current-sandbox:address:editor-data<span class="Special"> <- </span>get env:address:programming-environment-data/deref, current-sandbox:offset sandbox-in-focus?:boolean<span class="Special"> <- </span>get env:address:programming-environment-data/deref, sandbox-in-focus?:offset - <span class="Comment"># render recipes, along with any warnings</span> + <span class="Delimiter">{</span> + <span class="muControl">break-if</span> sandbox-in-focus?:boolean + screen:address<span class="Special"> <- </span>render-recipes screen:address, env:address:programming-environment-data + cursor-row:number<span class="Special"> <- </span>get recipes:address:editor-data/deref, cursor-row:offset + cursor-column:number<span class="Special"> <- </span>get recipes:address:editor-data/deref, cursor-column:offset + <span class="Delimiter">}</span> + <span class="Delimiter">{</span> + <span class="muControl">break-unless</span> sandbox-in-focus?:boolean + screen:address<span class="Special"> <- </span>render-sandbox-side screen:address, env:address:programming-environment-data + cursor-row:number<span class="Special"> <- </span>get current-sandbox:address:editor-data/deref, cursor-row:offset + cursor-column:number<span class="Special"> <- </span>get current-sandbox:address:editor-data/deref, cursor-column:offset + <span class="Delimiter">}</span> + move-cursor screen:address, cursor-row:number, cursor-column:number + show-screen screen:address + <span class="muControl">reply</span> screen:address/same-as-ingredient:0 +] + +<span class="muRecipe">recipe</span> render-recipes [ + <span class="Constant">local-scope</span> + screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + recipes:address:editor-data<span class="Special"> <- </span>get env:address:programming-environment-data/deref, recipes:offset + <span class="Comment"># render recipes</span> left:number<span class="Special"> <- </span>get recipes:address:editor-data/deref, left:offset right:number<span class="Special"> <- </span>get recipes:address:editor-data/deref, right:offset row:number, screen:address<span class="Special"> <- </span>render screen:address, recipes:address:editor-data recipe-warnings:address:array:character<span class="Special"> <- </span>get env:address:programming-environment-data/deref, recipe-warnings:offset <span class="Delimiter">{</span> + <span class="Comment"># print any warnings</span> <span class="muControl">break-unless</span> recipe-warnings:address:array:character row:number, screen:address<span class="Special"> <- </span>render-string screen:address, recipe-warnings:address:array:character, left:number, right:number, <span class="Constant">1:literal/red</span>, row:number <span class="Delimiter">}</span> <span class="Delimiter">{</span> - <span class="Comment"># no warnings? move to next lin</span> + <span class="Comment"># no warnings? move to next line</span> <span class="muControl">break-if</span> recipe-warnings:address:array:character row:number<span class="Special"> <- </span>add row:number, <span class="Constant">1:literal</span> <span class="Delimiter">}</span> @@ -861,7 +1225,15 @@ container editor-data [ row:number<span class="Special"> <- </span>add row:number, <span class="Constant">1:literal</span> move-cursor screen:address, row:number, left:number clear-line-delimited screen:address, left:number, right:number - <span class="Comment"># render sandboxes along with warnings for each</span> + <span class="muControl">reply</span> screen:address/same-as-ingredient:0 +] + +<span class="muRecipe">recipe</span> render-sandbox-side [ + <span class="Constant">local-scope</span> + screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + clear:boolean<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + current-sandbox:address:editor-data<span class="Special"> <- </span>get env:address:programming-environment-data/deref, current-sandbox:offset left:number<span class="Special"> <- </span>get current-sandbox:address:editor-data/deref, left:offset right:number<span class="Special"> <- </span>get current-sandbox:address:editor-data/deref, right:offset row:number, screen:address<span class="Special"> <- </span>render screen:address, current-sandbox:address:editor-data @@ -873,36 +1245,63 @@ container editor-data [ row:number<span class="Special"> <- </span>add row:number, <span class="Constant">1:literal</span> move-cursor screen:address, row:number, left:number clear-line-delimited screen:address, left:number, right:number - update-cursor screen:address, recipes:address:editor-data, current-sandbox:address:editor-data, sandbox-in-focus?:boolean - show-screen screen:address + <span class="muControl">reply-unless</span> clear:boolean, screen:address/same-as-ingredient:0 + screen-height:number<span class="Special"> <- </span>screen-height screen:address + <span class="Delimiter">{</span> + at-bottom-of-screen?:boolean<span class="Special"> <- </span>greater-or-equal row:number, screen-height:number + <span class="muControl">break-if</span> at-bottom-of-screen?:boolean + move-cursor screen:address, row:number, left:number + clear-line-delimited screen:address, left:number, right:number + row:number<span class="Special"> <- </span>add row:number, <span class="Constant">1:literal</span> + <span class="muControl">loop</span> + <span class="Delimiter">}</span> <span class="muControl">reply</span> screen:address/same-as-ingredient:0 ] <span class="muRecipe">recipe</span> render-sandboxes [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> sandbox:address:sandbox-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> left:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> right:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> row:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="muControl">reply-unless</span> sandbox:address:sandbox-data, row:number/same-as-ingredient:4, screen:address/same-as-ingredient:0 - screen-height:number<span class="Special"> <- </span>screen-width screen:address + screen-height:number<span class="Special"> <- </span>screen-height screen:address at-bottom?:boolean<span class="Special"> <- </span>greater-or-equal row:number screen-height:number <span class="muControl">reply-if</span> at-bottom?:boolean, row:number/same-as-ingredient:4, screen:address/same-as-ingredient:0 +<span class="CommentedCode">#? $print [rendering sandbox ], sandbox:address:sandbox-data, 10:literal/newline</span> + <span class="Comment"># render sandbox menu</span> + row:number<span class="Special"> <- </span>add row:number, <span class="Constant">1:literal</span> + move-cursor screen:address, row:number, left:number + clear-line-delimited screen:address, left:number, right:number + print-character screen:address, <span class="Constant">120:literal/x</span>, <span class="Constant">245:literal/grey</span> + <span class="Comment"># save menu row so we can detect clicks to it later</span> + starting-row:address:number<span class="Special"> <- </span>get-address sandbox:address:sandbox-data/deref, starting-row-on-screen:offset + starting-row:address:number/deref<span class="Special"> <- </span>copy row:number <span class="Comment"># render sandbox contents</span> sandbox-data:address:array:character<span class="Special"> <- </span>get sandbox:address:sandbox-data/deref, data:offset row:number, screen:address<span class="Special"> <- </span>render-string screen:address, sandbox-data:address:array:character, left:number, right:number, <span class="Constant">7:literal/white</span>, row:number - <span class="Comment"># render sandbox warnings or response, in that order</span> + <span class="Comment"># render sandbox warnings, screen or response, in that order</span> sandbox-response:address:array:character<span class="Special"> <- </span>get sandbox:address:sandbox-data/deref, response:offset sandbox-warnings:address:array:character<span class="Special"> <- </span>get sandbox:address:sandbox-data/deref, warnings:offset + sandbox-screen:address<span class="Special"> <- </span>get sandbox:address:sandbox-data/deref, screen:offset <span class="Delimiter">{</span> <span class="muControl">break-unless</span> sandbox-warnings:address:array:character row:number, screen:address<span class="Special"> <- </span>render-string screen:address, sandbox-warnings:address:array:character, left:number, right:number, <span class="Constant">1:literal/red</span>, row:number <span class="Delimiter">}</span> <span class="Delimiter">{</span> <span class="muControl">break-if</span> sandbox-warnings:address:array:character + empty-screen?:boolean<span class="Special"> <- </span>fake-screen-is-clear? sandbox-screen:address + <span class="muControl">break-if</span> empty-screen?:boolean + row:number, screen:address<span class="Special"> <- </span>render-screen screen:address, sandbox-screen:address, left:number, right:number, row:number + <span class="Delimiter">}</span> + <span class="Delimiter">{</span> + <span class="muControl">break-if</span> sandbox-warnings:address:array:character + <span class="muControl">break-unless</span> empty-screen?:boolean row:number, screen:address<span class="Special"> <- </span>render-string screen:address, sandbox-response:address:array:character, left:number, right:number, <span class="Constant">245:literal/grey</span>, row:number <span class="Delimiter">}</span> + at-bottom?:boolean<span class="Special"> <- </span>greater-or-equal row:number screen-height:number + <span class="muControl">reply-if</span> at-bottom?:boolean, row:number/same-as-ingredient:4, screen:address/same-as-ingredient:0 <span class="Comment"># draw solid line after sandbox</span> draw-horizontal screen:address, row:number, left:number, right:number, <span class="Constant">9473:literal/horizontal-double</span> <span class="Comment"># draw next sandbox</span> @@ -912,7 +1311,7 @@ container editor-data [ ] <span class="muRecipe">recipe</span> update-cursor [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> recipes:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> current-sandbox:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -1774,6 +2173,425 @@ d] ] ] +<span class="muScenario">scenario</span> editor-moves-to-start-of-line-with-ctrl-a [ + assume-screen <span class="Constant">10:literal/width</span>, <span class="Constant">5:literal/height</span> + 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> +<span class="Constant">456]</span> + 2:address:editor-data<span class="Special"> <- </span>new-editor 1:address:array:character, screen:address, <span class="Constant">0:literal/left</span>, <span class="Constant">10:literal/right</span> + <span class="Comment"># start on second line, press ctrl-a</span> + assume-console [ + left-click 2, 3 + type <span class="Constant">[a]</span> <span class="Comment"># ctrl-a</span> + ] + 3:event/ctrl-a<span class="Special"> <- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">1:literal/ctrl-a</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span> + replace-in-console <span class="Constant">97:literal/a</span>, 3:event/ctrl-a + run [ + editor-event-loop screen:address, console:address, 2:address:editor-data + 4:number<span class="Special"> <- </span>get 2:address:editor-data/deref, cursor-row:offset + 5:number<span class="Special"> <- </span>get 2:address:editor-data/deref, cursor-column:offset + ] + <span class="Comment"># cursor moves to start of line</span> + memory-should-contain [ + 4<span class="Special"> <- </span>2 + 5<span class="Special"> <- </span>0 + ] +] + +<span class="muScenario">scenario</span> editor-moves-to-start-of-line-with-ctrl-a-2 [ + assume-screen <span class="Constant">10:literal/width</span>, <span class="Constant">5:literal/height</span> + 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> +<span class="Constant">456]</span> + 2:address:editor-data<span class="Special"> <- </span>new-editor 1:address:array:character, screen:address, <span class="Constant">0:literal/left</span>, <span class="Constant">10:literal/right</span> + <span class="Comment"># start on first line (no newline before), press ctrl-a</span> + assume-console [ + left-click 1, 3 + type <span class="Constant">[a]</span> <span class="Comment"># ctrl-a</span> + ] + 3:event/ctrl-a<span class="Special"> <- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">1:literal/ctrl-a</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span> + replace-in-console <span class="Constant">97:literal/a</span>, 3:event/ctrl-a + run [ + editor-event-loop screen:address, console:address, 2:address:editor-data + 4:number<span class="Special"> <- </span>get 2:address:editor-data/deref, cursor-row:offset + 5:number<span class="Special"> <- </span>get 2:address:editor-data/deref, cursor-column:offset + ] + <span class="Comment"># cursor moves to start of line</span> + memory-should-contain [ + 4<span class="Special"> <- </span>1 + 5<span class="Special"> <- </span>0 + ] +] + +<span class="muScenario">scenario</span> editor-moves-to-start-of-line-with-home [ + assume-screen <span class="Constant">10:literal/width</span>, <span class="Constant">5:literal/height</span> + 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> +<span class="Constant">456]</span> + 2:address:editor-data<span class="Special"> <- </span>new-editor 1:address:array:character, screen:address, <span class="Constant">0:literal/left</span>, <span class="Constant">10:literal/right</span> + <span class="Comment"># start on second line, press 'home'</span> + assume-console [ + left-click 2, 3 + press 65521 <span class="Comment"># 'home'</span> + ] + run [ + editor-event-loop screen:address, console:address, 2:address:editor-data + 3:number<span class="Special"> <- </span>get 2:address:editor-data/deref, cursor-row:offset + 4:number<span class="Special"> <- </span>get 2:address:editor-data/deref, cursor-column:offset + ] + <span class="Comment"># cursor moves to start of line</span> + memory-should-contain [ + 3<span class="Special"> <- </span>2 + 4<span class="Special"> <- </span>0 + ] +] + +<span class="muScenario">scenario</span> editor-moves-to-start-of-line-with-home-2 [ + assume-screen <span class="Constant">10:literal/width</span>, <span class="Constant">5:literal/height</span> + 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> +<span class="Constant">456]</span> + 2:address:editor-data<span class="Special"> <- </span>new-editor 1:address:array:character, screen:address, <span class="Constant">0:literal/left</span>, <span class="Constant">10:literal/right</span> + <span class="Comment"># start on first line (no newline before), press 'home'</span> + assume-console [ + left-click 1, 3 + press 65521 <span class="Comment"># 'home'</span> + ] + run [ + editor-event-loop screen:address, console:address, 2:address:editor-data + 3:number<span class="Special"> <- </span>get 2:address:editor-data/deref, cursor-row:offset + 4:number<span class="Special"> <- </span>get 2:address:editor-data/deref, cursor-column:offset + ] + <span class="Comment"># cursor moves to start of line</span> + memory-should-contain [ + 3<span class="Special"> <- </span>1 + 4<span class="Special"> <- </span>0 + ] +] + +<span class="muScenario">scenario</span> editor-moves-to-start-of-line-with-ctrl-e [ + assume-screen <span class="Constant">10:literal/width</span>, <span class="Constant">5:literal/height</span> + 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> +<span class="Constant">456]</span> + 2:address:editor-data<span class="Special"> <- </span>new-editor 1:address:array:character, screen:address, <span class="Constant">0:literal/left</span>, <span class="Constant">10:literal/right</span> + <span class="Comment"># start on first line, press ctrl-e</span> + assume-console [ + left-click 1, 1 + type <span class="Constant">[e]</span> <span class="Comment"># ctrl-e</span> + ] + 3:event/ctrl-e<span class="Special"> <- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">5:literal/ctrl-e</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span> + replace-in-console <span class="Constant">101:literal/e</span>, 3:event/ctrl-e + run [ + editor-event-loop screen:address, console:address, 2:address:editor-data + 4:number<span class="Special"> <- </span>get 2:address:editor-data/deref, cursor-row:offset + 5:number<span class="Special"> <- </span>get 2:address:editor-data/deref, cursor-column:offset + ] + <span class="Comment"># cursor moves to end of line</span> + memory-should-contain [ + 4<span class="Special"> <- </span>1 + 5<span class="Special"> <- </span>3 + ] + <span class="Comment"># editor inserts future characters at cursor</span> + assume-console [ + type <span class="Constant">[z]</span> + ] + run [ + editor-event-loop screen:address, console:address, 2:address:editor-data + 4:number<span class="Special"> <- </span>get 2:address:editor-data/deref, cursor-row:offset + 5:number<span class="Special"> <- </span>get 2:address:editor-data/deref, cursor-column:offset + ] + memory-should-contain [ + 4<span class="Special"> <- </span>1 + 5<span class="Special"> <- </span>4 + ] + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .123z .</span> + <span class="Constant"> .456 .</span> + <span class="Constant"> . .</span> + ] +] + +<span class="muScenario">scenario</span> editor-moves-to-end-of-line-with-ctrl-e-2 [ + assume-screen <span class="Constant">10:literal/width</span>, <span class="Constant">5:literal/height</span> + 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> +<span class="Constant">456]</span> + 2:address:editor-data<span class="Special"> <- </span>new-editor 1:address:array:character, screen:address, <span class="Constant">0:literal/left</span>, <span class="Constant">10:literal/right</span> + <span class="Comment"># start on second line (no newline after), press ctrl-e</span> + assume-console [ + left-click 2, 1 + type <span class="Constant">[e]</span> <span class="Comment"># ctrl-e</span> + ] + 3:event/ctrl-e<span class="Special"> <- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">5:literal/ctrl-e</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span> + replace-in-console <span class="Constant">101:literal/e</span>, 3:event/ctrl-e + run [ + editor-event-loop screen:address, console:address, 2:address:editor-data + 4:number<span class="Special"> <- </span>get 2:address:editor-data/deref, cursor-row:offset + 5:number<span class="Special"> <- </span>get 2:address:editor-data/deref, cursor-column:offset + ] + <span class="Comment"># cursor moves to end of line</span> + memory-should-contain [ + 4<span class="Special"> <- </span>2 + 5<span class="Special"> <- </span>3 + ] +] + +<span class="muScenario">scenario</span> editor-moves-to-end-of-line-with-end [ + assume-screen <span class="Constant">10:literal/width</span>, <span class="Constant">5:literal/height</span> + 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> +<span class="Constant">456]</span> + 2:address:editor-data<span class="Special"> <- </span>new-editor 1:address:array:character, screen:address, <span class="Constant">0:literal/left</span>, <span class="Constant">10:literal/right</span> + <span class="Comment"># start on first line, press 'end'</span> + assume-console [ + left-click 1, 1 + press 65520 <span class="Comment"># 'end'</span> + ] + run [ + editor-event-loop screen:address, console:address, 2:address:editor-data + 3:number<span class="Special"> <- </span>get 2:address:editor-data/deref, cursor-row:offset + 4:number<span class="Special"> <- </span>get 2:address:editor-data/deref, cursor-column:offset + ] + <span class="Comment"># cursor moves to end of line</span> + memory-should-contain [ + 3<span class="Special"> <- </span>1 + 4<span class="Special"> <- </span>3 + ] +] + +<span class="muScenario">scenario</span> editor-moves-to-end-of-line-with-end-2 [ + assume-screen <span class="Constant">10:literal/width</span>, <span class="Constant">5:literal/height</span> + 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> +<span class="Constant">456]</span> + 2:address:editor-data<span class="Special"> <- </span>new-editor 1:address:array:character, screen:address, <span class="Constant">0:literal/left</span>, <span class="Constant">10:literal/right</span> + <span class="Comment"># start on second line (no newline after), press 'end'</span> + assume-console [ + left-click 2, 1 + press 65520 <span class="Comment"># 'end'</span> + ] + run [ + editor-event-loop screen:address, console:address, 2:address:editor-data + 3:number<span class="Special"> <- </span>get 2:address:editor-data/deref, cursor-row:offset + 4:number<span class="Special"> <- </span>get 2:address:editor-data/deref, cursor-column:offset + ] + <span class="Comment"># cursor moves to end of line</span> + memory-should-contain [ + 3<span class="Special"> <- </span>2 + 4<span class="Special"> <- </span>3 + ] +] + +<span class="muScenario">scenario</span> editor-deletes-to-start-of-line-with-ctrl-u [ + assume-screen <span class="Constant">10:literal/width</span>, <span class="Constant">5:literal/height</span> + 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> +<span class="Constant">456]</span> + 2:address:editor-data<span class="Special"> <- </span>new-editor 1:address:array:character, screen:address, <span class="Constant">0:literal/left</span>, <span class="Constant">10:literal/right</span> + <span class="Comment"># start on second line, press ctrl-u</span> + assume-console [ + left-click 2, 2 + type <span class="Constant">[u]</span> <span class="Comment"># ctrl-u</span> + ] + 3:event/ctrl-a<span class="Special"> <- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">21:literal/ctrl-u</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span> + replace-in-console <span class="Constant">117:literal/u</span>, 3:event/ctrl-u + run [ + editor-event-loop screen:address, console:address, 2:address:editor-data + ] + <span class="Comment"># cursor deletes to start of line</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .123 .</span> + <span class="Constant"> .6 .</span> + <span class="Constant"> . .</span> + ] +] + +<span class="muScenario">scenario</span> editor-deletes-to-start-of-line-with-ctrl-u-2 [ + assume-screen <span class="Constant">10:literal/width</span>, <span class="Constant">5:literal/height</span> + 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> +<span class="Constant">456]</span> + 2:address:editor-data<span class="Special"> <- </span>new-editor 1:address:array:character, screen:address, <span class="Constant">0:literal/left</span>, <span class="Constant">10:literal/right</span> + <span class="Comment"># start on first line (no newline before), press ctrl-u</span> + assume-console [ + left-click 1, 2 + type <span class="Constant">[u]</span> <span class="Comment"># ctrl-u</span> + ] + 3:event/ctrl-u<span class="Special"> <- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">21:literal/ctrl-a</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span> + replace-in-console <span class="Constant">117:literal/a</span>, 3:event/ctrl-u + run [ + editor-event-loop screen:address, console:address, 2:address:editor-data + ] + <span class="Comment"># cursor deletes to start of line</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .3 .</span> + <span class="Constant"> .456 .</span> + <span class="Constant"> . .</span> + ] +] + +<span class="muScenario">scenario</span> editor-deletes-to-start-of-line-with-ctrl-u-3 [ + assume-screen <span class="Constant">10:literal/width</span>, <span class="Constant">5:literal/height</span> + 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> +<span class="Constant">456]</span> + 2:address:editor-data<span class="Special"> <- </span>new-editor 1:address:array:character, screen:address, <span class="Constant">0:literal/left</span>, <span class="Constant">10:literal/right</span> + <span class="Comment"># start past end of line, press ctrl-u</span> + assume-console [ + left-click 1, 3 + type <span class="Constant">[u]</span> <span class="Comment"># ctrl-u</span> + ] + 3:event/ctrl-u<span class="Special"> <- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">21:literal/ctrl-a</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span> + replace-in-console <span class="Constant">117:literal/a</span>, 3:event/ctrl-u + run [ + editor-event-loop screen:address, console:address, 2:address:editor-data + ] + <span class="Comment"># cursor deletes to start of line</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> . .</span> + <span class="Constant"> .456 .</span> + <span class="Constant"> . .</span> + ] +] + +<span class="muScenario">scenario</span> editor-deletes-to-end-of-line-with-ctrl-k [ + assume-screen <span class="Constant">10:literal/width</span>, <span class="Constant">5:literal/height</span> + 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> +<span class="Constant">456]</span> + 2:address:editor-data<span class="Special"> <- </span>new-editor 1:address:array:character, screen:address, <span class="Constant">0:literal/left</span>, <span class="Constant">10:literal/right</span> + <span class="Comment"># start on first line, press ctrl-k</span> + assume-console [ + left-click 1, 1 + type <span class="Constant">[k]</span> <span class="Comment"># ctrl-k</span> + ] + 3:event/ctrl-k<span class="Special"> <- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">11:literal/ctrl-k</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span> + replace-in-console <span class="Constant">107:literal/k</span>, 3:event/ctrl-k + run [ + editor-event-loop screen:address, console:address, 2:address:editor-data + ] + <span class="Comment"># cursor deletes to end of line</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .1 .</span> + <span class="Constant"> .456 .</span> + <span class="Constant"> . .</span> + ] +] + +<span class="muScenario">scenario</span> editor-deletes-to-end-of-line-with-ctrl-k-2 [ + assume-screen <span class="Constant">10:literal/width</span>, <span class="Constant">5:literal/height</span> + 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> +<span class="Constant">456]</span> + 2:address:editor-data<span class="Special"> <- </span>new-editor 1:address:array:character, screen:address, <span class="Constant">0:literal/left</span>, <span class="Constant">10:literal/right</span> + <span class="Comment"># start on second line (no newline after), press ctrl-k</span> + assume-console [ + left-click 2, 1 + type <span class="Constant">[k]</span> <span class="Comment"># ctrl-k</span> + ] + 3:event/ctrl-k<span class="Special"> <- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">11:literal/ctrl-k</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span> + replace-in-console <span class="Constant">107:literal/k</span>, 3:event/ctrl-k + run [ + editor-event-loop screen:address, console:address, 2:address:editor-data + ] + <span class="Comment"># cursor deletes to end of line</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .123 .</span> + <span class="Constant"> .4 .</span> + <span class="Constant"> . .</span> + ] +] + +<span class="muScenario">scenario</span> editor-deletes-to-end-of-line-with-ctrl-k-3 [ + assume-screen <span class="Constant">10:literal/width</span>, <span class="Constant">5:literal/height</span> + 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> +<span class="Constant">456]</span> + 2:address:editor-data<span class="Special"> <- </span>new-editor 1:address:array:character, screen:address, <span class="Constant">0:literal/left</span>, <span class="Constant">10:literal/right</span> + <span class="Comment"># start at end of line</span> + assume-console [ + left-click 1, 2 + type <span class="Constant">[k]</span> <span class="Comment"># ctrl-k</span> + ] + 3:event/ctrl-k<span class="Special"> <- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">11:literal/ctrl-k</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span> + replace-in-console <span class="Constant">107:literal/k</span>, 3:event/ctrl-k + run [ + editor-event-loop screen:address, console:address, 2:address:editor-data + ] + <span class="Comment"># cursor deletes to end of line</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .12 .</span> + <span class="Constant"> .456 .</span> + <span class="Constant"> . .</span> + ] +] + +<span class="muScenario">scenario</span> editor-deletes-to-end-of-line-with-ctrl-k-4 [ + assume-screen <span class="Constant">10:literal/width</span>, <span class="Constant">5:literal/height</span> + 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> +<span class="Constant">456]</span> + 2:address:editor-data<span class="Special"> <- </span>new-editor 1:address:array:character, screen:address, <span class="Constant">0:literal/left</span>, <span class="Constant">10:literal/right</span> + <span class="Comment"># start past end of line</span> + assume-console [ + left-click 1, 3 + type <span class="Constant">[k]</span> <span class="Comment"># ctrl-k</span> + ] + 3:event/ctrl-k<span class="Special"> <- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">11:literal/ctrl-k</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span> + replace-in-console <span class="Constant">107:literal/k</span>, 3:event/ctrl-k + run [ + editor-event-loop screen:address, console:address, 2:address:editor-data + ] + <span class="Comment"># cursor deletes to end of line</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .123 .</span> + <span class="Constant"> .456 .</span> + <span class="Constant"> . .</span> + ] +] + +<span class="muScenario">scenario</span> editor-deletes-to-end-of-line-with-ctrl-k-5 [ + assume-screen <span class="Constant">10:literal/width</span>, <span class="Constant">5:literal/height</span> + 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> +<span class="Constant">456]</span> + 2:address:editor-data<span class="Special"> <- </span>new-editor 1:address:array:character, screen:address, <span class="Constant">0:literal/left</span>, <span class="Constant">10:literal/right</span> + <span class="Comment"># start at end of text</span> + assume-console [ + left-click 2, 2 + type <span class="Constant">[k]</span> <span class="Comment"># ctrl-k</span> + ] + 3:event/ctrl-k<span class="Special"> <- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">11:literal/ctrl-k</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span> + replace-in-console <span class="Constant">107:literal/k</span>, 3:event/ctrl-k + run [ + editor-event-loop screen:address, console:address, 2:address:editor-data + ] + <span class="Comment"># cursor deletes to end of line</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .123 .</span> + <span class="Constant"> .45 .</span> + <span class="Constant"> . .</span> + ] +] + +<span class="muScenario">scenario</span> editor-deletes-to-end-of-line-with-ctrl-k-6 [ + assume-screen <span class="Constant">10:literal/width</span>, <span class="Constant">5:literal/height</span> + 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> +<span class="Constant">456]</span> + 2:address:editor-data<span class="Special"> <- </span>new-editor 1:address:array:character, screen:address, <span class="Constant">0:literal/left</span>, <span class="Constant">10:literal/right</span> + <span class="Comment"># start past end of text</span> + assume-console [ + left-click 2, 3 + type <span class="Constant">[k]</span> <span class="Comment"># ctrl-k</span> + ] + 3:event/ctrl-k<span class="Special"> <- </span>merge <span class="Constant">0:literal/text</span>, <span class="Constant">11:literal/ctrl-k</span>, <span class="Constant">0:literal/dummy</span>, <span class="Constant">0:literal/dummy</span> + replace-in-console <span class="Constant">107:literal/k</span>, 3:event/ctrl-k + run [ + editor-event-loop screen:address, console:address, 2:address:editor-data + ] + <span class="Comment"># cursor deletes to end of line</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .123 .</span> + <span class="Constant"> .456 .</span> + <span class="Constant"> . .</span> + ] +] + <span class="muScenario">scenario</span> point-at-multiple-editors [ assume-screen <span class="Constant">30:literal/width</span>, <span class="Constant">5:literal/height</span> <span class="Comment"># initialize both halves of screen</span> @@ -1852,7 +2670,7 @@ d] screen-should-contain [ <span class="Constant"> . run (F10) .</span> <span class="Constant"> .abc ┊def .</span> - <span class="Constant"> . ┊ .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> <span class="Constant"> . ┊ .</span> <span class="Constant"> . ┊ .</span> ] @@ -1873,8 +2691,7 @@ d] screen-should-contain [ <span class="Constant"> . run (F10) .</span> <span class="Constant"> .␣bc ┊def .</span> -<span class="Comment"># artifact of fake console: no events = no render</span> -<span class="Comment"># .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━.</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━.</span> <span class="Constant"> . ┊ .</span> ] <span class="Comment"># now try typing a letter</span> @@ -1901,12 +2718,14 @@ container sandbox-data [ data:address:array:character response:address:array:character warnings:address:array:character + starting-row-on-screen:number <span class="Comment"># to track clicks on delete</span> + screen:address:screen <span class="Comment"># prints in the sandbox go here</span> next-sandbox:address:sandbox-data ] <span class="muScenario">scenario</span> run-and-show-results [ $close-trace <span class="Comment"># trace too long for github</span> - assume-screen <span class="Constant">100:literal/width</span>, <span class="Constant">12:literal/height</span> + assume-screen <span class="Constant">100:literal/width</span>, <span class="Constant">15:literal/height</span> <span class="Comment"># recipe editor is empty</span> 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span> <span class="Comment"># sandbox editor contains an instruction without storing outputs</span> @@ -1924,6 +2743,7 @@ container sandbox-data [ <span class="Constant"> . run (F10) .</span> <span class="Constant"> . ┊ .</span> <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ x.</span> <span class="Constant"> . ┊divide-with-remainder 11:literal, 3:literal .</span> <span class="Constant"> . ┊3 .</span> <span class="Constant"> . ┊2 .</span> @@ -1934,16 +2754,18 @@ container sandbox-data [ <span class="Constant"> . .</span> <span class="Constant"> . .</span> <span class="Constant"> . .</span> + <span class="Constant"> . .</span> <span class="Constant"> . divide-with-remainder 11:literal, 3:literal .</span> <span class="Constant"> . .</span> <span class="Constant"> . .</span> <span class="Constant"> . .</span> <span class="Constant"> . .</span> ] - screen-should-contain-in-color, <span class="Constant">245:literal/grey</span>, [ + screen-should-contain-in-color <span class="Constant">245:literal/grey</span>, [ <span class="Constant"> . .</span> <span class="Constant"> . ┊ .</span> <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ x.</span> <span class="Constant"> . ┊ .</span> <span class="Constant"> . ┊3 .</span> <span class="Constant"> . ┊2 .</span> @@ -1964,9 +2786,11 @@ container sandbox-data [ <span class="Constant"> . run (F10) .</span> <span class="Constant"> . ┊ .</span> <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ x.</span> <span class="Constant"> . ┊add 2:literal, 2:literal .</span> <span class="Constant"> . ┊4 .</span> <span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ x.</span> <span class="Constant"> . ┊divide-with-remainder 11:literal, 3:literal .</span> <span class="Constant"> . ┊3 .</span> <span class="Constant"> . ┊2 .</span> @@ -1976,19 +2800,21 @@ container sandbox-data [ ] <span class="muRecipe">recipe</span> run-sandboxes [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> recipes:address:editor-data<span class="Special"> <- </span>get env:address:programming-environment-data/deref, recipes:offset current-sandbox:address:editor-data<span class="Special"> <- </span>get env:address:programming-environment-data/deref, current-sandbox:offset - <span class="Comment"># load code from recipe editor, save any warnings</span> + <span class="Comment"># copy code from recipe editor, persist, load into mu, save any warnings</span> in:address:array:character<span class="Special"> <- </span>editor-contents recipes:address:editor-data + save <span class="Constant">[recipes.mu]</span>, in:address:array:character recipe-warnings:address:address:array:character<span class="Special"> <- </span>get-address env:address:programming-environment-data/deref, recipe-warnings:offset recipe-warnings:address:address:array:character/deref<span class="Special"> <- </span>reload in:address:array:character <span class="Comment"># check contents of right editor (sandbox)</span> <span class="Delimiter">{</span> sandbox-contents:address:array:character<span class="Special"> <- </span>editor-contents current-sandbox:address:editor-data <span class="muControl">break-unless</span> sandbox-contents:address:array:character - <span class="Comment"># if contents exist, run them and turn them into a new sandbox-data</span> + <span class="Comment"># if contents exist, first save them</span> + <span class="Comment"># run them and turn them into a new sandbox-data</span> new-sandbox:address:sandbox-data<span class="Special"> <- </span>new sandbox-data:type data:address:address:array:character<span class="Special"> <- </span>get-address new-sandbox:address:sandbox-data/deref, data:offset data:address:address:array:character/deref<span class="Special"> <- </span>copy sandbox-contents:address:array:character @@ -2001,17 +2827,74 @@ container sandbox-data [ init:address:address:duplex-list<span class="Special"> <- </span>get-address current-sandbox:address:editor-data/deref, data:offset init:address:address:duplex-list/deref<span class="Special"> <- </span>push-duplex <span class="Constant">167:literal/§</span>, <span class="Constant">0:literal/tail</span> <span class="Delimiter">}</span> - <span class="Comment"># rerun other sandboxes</span> + <span class="Comment"># save all sandboxes before running, just in case we die when running</span> + curr:address:sandbox-data<span class="Special"> <- </span>get env:address:programming-environment-data/deref, sandbox:offset + filename:number<span class="Special"> <- </span>copy <span class="Constant">0:literal</span> + <span class="Delimiter">{</span> + <span class="muControl">break-unless</span> curr:address:sandbox-data + data:address:address:array:character<span class="Special"> <- </span>get-address curr:address:sandbox-data/deref, data:offset + save filename:number, data:address:address:array:character/deref + filename:number<span class="Special"> <- </span>add filename:number, <span class="Constant">1:literal</span> + curr:address:sandbox-data<span class="Special"> <- </span>get curr:address:sandbox-data/deref, next-sandbox:offset + <span class="muControl">loop</span> + <span class="Delimiter">}</span> + <span class="Comment"># run all sandboxes</span> curr:address:sandbox-data<span class="Special"> <- </span>get env:address:programming-environment-data/deref, sandbox:offset <span class="Delimiter">{</span> <span class="muControl">break-unless</span> curr:address:sandbox-data data:address:address:array:character<span class="Special"> <- </span>get-address curr:address:sandbox-data/deref, data:offset response:address:address:array:character<span class="Special"> <- </span>get-address curr:address:sandbox-data/deref, response:offset warnings:address:address:array:character<span class="Special"> <- </span>get-address curr:address:sandbox-data/deref, warnings:offset - response:address:address:array:character/deref, warnings:address:address:array:character/deref<span class="Special"> <- </span>run-interactive data:address:address:array:character/deref + fake-screen:address:address:screen<span class="Special"> <- </span>get-address curr:address:sandbox-data/deref, screen:offset + response:address:address:array:character/deref, warnings:address:address:array:character/deref, fake-screen:address:address:screen/deref<span class="Special"> <- </span>run-interactive data:address:address:array:character/deref +<span class="CommentedCode">#? $print warnings:address:address:array:character/deref, [ ], warnings:address:address:array:character/deref/deref, 10:literal/newline</span> + curr:address:sandbox-data<span class="Special"> <- </span>get curr:address:sandbox-data/deref, next-sandbox:offset + <span class="muControl">loop</span> + <span class="Delimiter">}</span> +] + +<span class="Comment"># was-deleted?:boolean <- delete-sandbox t:touch-event, env:address:programming-environment-data</span> +<span class="muRecipe">recipe</span> delete-sandbox [ + <span class="Constant">local-scope</span> + t:touch-event<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + click-column:number<span class="Special"> <- </span>get t:touch-event, column:offset + current-sandbox:address:editor-data<span class="Special"> <- </span>get env:address:programming-environment-data/deref, current-sandbox:offset + right:number<span class="Special"> <- </span>get current-sandbox:address:editor-data/deref, right:offset +<span class="CommentedCode">#? $print [comparing column ], click-column:number, [ vs ], right:number, 10:literal/newline</span> + at-right?:boolean<span class="Special"> <- </span>equal click-column:number, right:number + <span class="muControl">reply-unless</span> at-right?:boolean, <span class="Constant">0:literal/false</span> +<span class="CommentedCode">#? $print [trying to delete</span> +<span class="CommentedCode">#? ] #? 1</span> + click-row:number<span class="Special"> <- </span>get t:touch-event, row:offset + prev:address:address:sandbox-data<span class="Special"> <- </span>get-address env:address:programming-environment-data/deref, sandbox:offset +<span class="CommentedCode">#? $print [prev: ], prev:address:address:sandbox-data, [ -> ], prev:address:address:sandbox-data/deref, 10:literal/newline</span> + curr:address:sandbox-data<span class="Special"> <- </span>get env:address:programming-environment-data/deref, sandbox:offset + <span class="Delimiter">{</span> +<span class="CommentedCode">#? $print [next sandbox</span> +<span class="CommentedCode">#? ] #? 1</span> + <span class="muControl">break-unless</span> curr:address:sandbox-data + <span class="Comment"># more sandboxes to check</span> + <span class="Delimiter">{</span> +<span class="CommentedCode">#? $print [checking</span> +<span class="CommentedCode">#? ] #? 1</span> + target-row:number<span class="Special"> <- </span>get curr:address:sandbox-data/deref, starting-row-on-screen:offset +<span class="CommentedCode">#? $print [comparing row ], target-row:number, [ vs ], click-row:number, 10:literal/newline</span> + delete-curr?:boolean<span class="Special"> <- </span>equal target-row:number, click-row:number + <span class="muControl">break-unless</span> delete-curr?:boolean +<span class="CommentedCode">#? $print [found!</span> +<span class="CommentedCode">#? ] #? 1</span> + <span class="Comment"># delete this sandbox, rerender and stop</span> + prev:address:address:sandbox-data/deref<span class="Special"> <- </span>get curr:address:sandbox-data/deref, next-sandbox:offset +<span class="CommentedCode">#? $print [setting prev: ], prev:address:address:sandbox-data, [ -> ], prev:address:address:sandbox-data/deref, 10:literal/newline</span> + <span class="muControl">reply</span> <span class="Constant">1:literal/true</span> + <span class="Delimiter">}</span> + prev:address:address:sandbox-data<span class="Special"> <- </span>get-address curr:address:sandbox-data/deref, next-sandbox:offset +<span class="CommentedCode">#? $print [prev: ], prev:address:address:sandbox-data, [ -> ], prev:address:address:sandbox-data/deref, 10:literal/newline</span> curr:address:sandbox-data<span class="Special"> <- </span>get curr:address:sandbox-data/deref, next-sandbox:offset <span class="muControl">loop</span> <span class="Delimiter">}</span> + <span class="muControl">reply</span> <span class="Constant">0:literal/false</span> ] <span class="muScenario">scenario</span> run-updates-results [ @@ -2037,9 +2920,10 @@ container sandbox-data [ <span class="Constant"> . run (F10) .</span> <span class="Constant"> . ┊ .</span> <span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> - <span class="Constant"> .z:number <- add 2:literal, 2:literal ┊foo .</span> - <span class="Constant"> .] ┊4 .</span> -<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> .z:number <- add 2:literal, 2:literal ┊ x.</span> + <span class="Constant"> .] ┊foo .</span> + <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 .</span> + <span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> <span class="Constant"> . ┊ .</span> ] <span class="Comment"># make a change (incrementing one of the args to 'add'), then rerun</span> @@ -2058,9 +2942,10 @@ container sandbox-data [ <span class="Constant"> . run (F10) .</span> <span class="Constant"> . ┊ .</span> <span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> - <span class="Constant"> .z:number <- add 2:literal, 3:literal ┊foo .</span> - <span class="Constant"> .] ┊5 .</span> -<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> .z:number <- add 2:literal, 3:literal ┊ x.</span> + <span class="Constant"> .] ┊foo .</span> + <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊5 .</span> + <span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> <span class="Constant"> . ┊ .</span> ] ] @@ -2085,6 +2970,7 @@ container sandbox-data [ <span class="Constant"> . run (F10) .</span> <span class="Constant"> . ┊ .</span> <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ x.</span> <span class="Constant"> . ┊get 1234:number, foo:offset .</span> <span class="Constant"> . ┊unknown element foo in container number .</span> <span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> @@ -2094,12 +2980,14 @@ container sandbox-data [ <span class="Constant"> . .</span> <span class="Constant"> . .</span> <span class="Constant"> . .</span> + <span class="Constant"> . .</span> <span class="Constant"> . get 1234:number, foo:offset .</span> <span class="Constant"> . .</span> <span class="Constant"> . .</span> <span class="Constant"> . .</span> ] - screen-should-contain-in-color, <span class="Constant">1:literal/red</span>, [ + screen-should-contain-in-color <span class="Constant">1:literal/red</span>, [ + <span class="Constant"> . .</span> <span class="Constant"> . .</span> <span class="Constant"> . .</span> <span class="Constant"> . .</span> @@ -2107,10 +2995,11 @@ container sandbox-data [ <span class="Constant"> . unknown element foo in container number .</span> <span class="Constant"> . .</span> ] - screen-should-contain-in-color, <span class="Constant">245:literal/grey</span>, [ + screen-should-contain-in-color <span class="Constant">245:literal/grey</span>, [ <span class="Constant"> . .</span> <span class="Constant"> . ┊ .</span> <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ x.</span> <span class="Constant"> . ┊ .</span> <span class="Constant"> . ┊ .</span> <span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> @@ -2118,8 +3007,137 @@ container sandbox-data [ ] ] +<span class="muScenario">scenario</span> run-instruction-and-print-warnings-only-once [ + $close-trace <span class="Comment"># trace too long for github</span> + assume-screen <span class="Constant">100:literal/width</span>, <span class="Constant">10:literal/height</span> + <span class="Comment"># left editor is empty</span> + 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span> + <span class="Comment"># right editor contains an illegal instruction</span> + 2:address:array:character<span class="Special"> <- </span>new <span class="Constant">[get 1234:number, foo:offset]</span> + 3:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, 1:address:array:character, 2:address:array:character + <span class="Comment"># run the code in the editors multiple times</span> + assume-console [ + press 65526 <span class="Comment"># F10</span> + press 65526 <span class="Comment"># F10</span> + ] + run [ + event-loop screen:address, console:address, 3:address:programming-environment-data + ] + <span class="Comment"># check that screen prints error message just once</span> + screen-should-contain [ + <span class="Constant"> . run (F10) .</span> + <span class="Constant"> . ┊ .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ x.</span> + <span class="Constant"> . ┊get 1234:number, foo:offset .</span> + <span class="Constant"> . ┊unknown element foo in container number .</span> + <span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ .</span> + ] +] + +<span class="muScenario">scenario</span> deleting-sandboxes [ + $close-trace <span class="Comment"># trace too long for github</span> + assume-screen <span class="Constant">100:literal/width</span>, <span class="Constant">15:literal/height</span> + 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span> + 2:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span> + 3:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, 1:address:array:character, 2:address:array:character + <span class="Comment"># run a few commands</span> + assume-console [ + left-click 1, 80 + type <span class="Constant">[divide-with-remainder 11:literal, 3:literal]</span> + press 65526 <span class="Comment"># F10</span> + type <span class="Constant">[add 2:literal, 2:literal]</span> + press 65526 <span class="Comment"># F10</span> + ] + run [ + event-loop screen:address, console:address, 3:address:programming-environment-data + ] + screen-should-contain [ + <span class="Constant"> . run (F10) .</span> + <span class="Constant"> . ┊ .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ x.</span> + <span class="Constant"> . ┊add 2:literal, 2:literal .</span> + <span class="Constant"> . ┊4 .</span> + <span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ x.</span> + <span class="Constant"> . ┊divide-with-remainder 11:literal, 3:literal .</span> + <span class="Constant"> . ┊3 .</span> + <span class="Constant"> . ┊2 .</span> + <span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ .</span> + ] + <span class="Comment"># delete second sandbox</span> + assume-console [ + left-click 7, 99 + ] + run [ + event-loop screen:address, console:address, 3:address:programming-environment-data + ] + screen-should-contain [ + <span class="Constant"> . run (F10) .</span> + <span class="Constant"> . ┊ .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ x.</span> + <span class="Constant"> . ┊add 2:literal, 2:literal .</span> + <span class="Constant"> . ┊4 .</span> + <span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ .</span> + <span class="Constant"> . ┊ .</span> + ] + <span class="Comment"># delete first sandbox</span> + assume-console [ + left-click 3, 99 + ] + run [ + event-loop screen:address, console:address, 3:address:programming-environment-data + ] + screen-should-contain [ + <span class="Constant"> . run (F10) .</span> + <span class="Constant"> . ┊ .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ .</span> + <span class="Constant"> . ┊ .</span> + ] +] + +<span class="muScenario">scenario</span> run-instruction-manages-screen-per-sandbox [ + $close-trace <span class="Comment"># trace too long for github #? 1</span> + assume-screen <span class="Constant">100:literal/width</span>, <span class="Constant">20:literal/height</span> + <span class="Comment"># left editor is empty</span> + 1:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span> + <span class="Comment"># right editor contains an illegal instruction</span> + 2:address:array:character<span class="Special"> <- </span>new <span class="Constant">[print-integer screen:address, 4]</span> + 3:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, 1:address:array:character, 2:address:array:character + <span class="Comment"># run the code in the editor</span> + assume-console [ + press 65526 <span class="Comment"># F10</span> + ] + run [ + event-loop screen:address, console:address, 3:address:programming-environment-data + ] + <span class="Comment"># check that it prints a little 5x5 toy screen</span> + <span class="Comment"># hack: screen address is brittle</span> + screen-should-contain [ + <span class="Constant"> . run (F10) .</span> + <span class="Constant"> . ┊ .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ x.</span> + <span class="Constant"> . ┊print-integer screen:address, 4 .</span> + <span class="Constant"> . ┊screen: .</span> + <span class="Constant"> . ┊ .4 . .</span> + <span class="Constant"> . ┊ . . .</span> + <span class="Constant"> . ┊ . . .</span> + <span class="Constant"> . ┊ . . .</span> + <span class="Constant"> . ┊ . . .</span> + <span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ .</span> + ] +] + <span class="muRecipe">recipe</span> editor-contents [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> buf:address:buffer<span class="Special"> <- </span>new-buffer <span class="Constant">80:literal</span> curr:address:duplex-list<span class="Special"> <- </span>get editor:address:editor-data/deref, data:offset @@ -2159,7 +3177,7 @@ container sandbox-data [ <span class="SalientComment">## helpers for drawing editor borders</span> <span class="muRecipe">recipe</span> draw-box [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> top:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> left:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -2187,7 +3205,7 @@ container sandbox-data [ ] <span class="muRecipe">recipe</span> draw-horizontal [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> row:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> x:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -2219,7 +3237,7 @@ container sandbox-data [ ] <span class="muRecipe">recipe</span> draw-vertical [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> col:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> x:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -2246,7 +3264,7 @@ container sandbox-data [ ] <span class="muRecipe">recipe</span> draw-top-left [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> top:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> left:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -2261,7 +3279,7 @@ container sandbox-data [ ] <span class="muRecipe">recipe</span> draw-top-right [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> top:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> right:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -2276,7 +3294,7 @@ container sandbox-data [ ] <span class="muRecipe">recipe</span> draw-bottom-left [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> bottom:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> left:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -2291,7 +3309,7 @@ container sandbox-data [ ] <span class="muRecipe">recipe</span> draw-bottom-right [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> bottom:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> right:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -2306,7 +3324,7 @@ container sandbox-data [ ] <span class="muRecipe">recipe</span> print-string-with-gradient-background [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> s:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> color:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -2316,8 +3334,7 @@ container sandbox-data [ color-range:number<span class="Special"> <- </span>subtract bg-color2:number, bg-color1:number color-quantum:number<span class="Special"> <- </span>divide color-range:number, len:number <span class="CommentedCode">#? close-console #? 2</span> -<span class="CommentedCode">#? $print len:number, [, ], color-range:number, [, ], color-quantum:number, [ </span> -<span class="CommentedCode">#? ] #? 2</span> +<span class="CommentedCode">#? $print len:number, [, ], color-range:number, [, ], color-quantum:number, 10:literal/newline</span> <span class="CommentedCode">#? #? $exit #? 3</span> bg-color:number<span class="Special"> <- </span>copy bg-color1:number i:number<span class="Special"> <- </span>copy <span class="Constant">0:literal</span> @@ -2328,8 +3345,7 @@ container sandbox-data [ print-character x:address:screen, c:character, color:number, bg-color:number i:number<span class="Special"> <- </span>add i:number, <span class="Constant">1:literal</span> bg-color:number<span class="Special"> <- </span>add bg-color:number, color-quantum:number -<span class="CommentedCode">#? $print [=> ], bg-color:number, [ </span> -<span class="CommentedCode">#? ] #? 1</span> +<span class="CommentedCode">#? $print [=> ], bg-color:number, 10:literal/newline</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> <span class="CommentedCode">#? $exit #? 1</span> diff --git a/html/factorial.mu.html b/html/factorial.mu.html index 41a725b6..5545f582 100644 --- a/html/factorial.mu.html +++ b/html/factorial.mu.html @@ -34,14 +34,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment"># example program: compute the factorial of 5</span> <span class="muRecipe">recipe</span> main [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> x:number<span class="Special"> <- </span>factorial <span class="Constant">5:literal</span> $print <span class="Constant">[result: ]</span>, x:number, <span class="Constant">[ </span> <span class="Constant">]</span> ] <span class="muRecipe">recipe</span> factorial [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> n:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Delimiter">{</span> <span class="Comment"># if n=0 return 1</span> diff --git a/html/tangle.mu.html b/html/tangle.mu.html index f68a77f3..0e4ec070 100644 --- a/html/tangle.mu.html +++ b/html/tangle.mu.html @@ -39,7 +39,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment"># possibilities.</span> <span class="muRecipe">recipe</span> factorial [ - <span class="Constant">new-default-space</span> + <span class="Constant">local-scope</span> n:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Delimiter">{</span> <span class="Constant"> +base-case</span> diff --git a/index.html b/index.html index 9926243c..40aea7b9 100644 --- a/index.html +++ b/index.html @@ -40,8 +40,10 @@ also supports first-class functions and delimited continuations. print primitives that inject a screen <em>dependency</em> which can be faked for testing. <li><a href='html/chessboard.mu.html'>chessboard.mu</a>: putting it all -together, the big kahuna: a complete console program along with thorough tests -of its behavior including both screen and keyboard handling. +together, a little console program along with thorough tests of its behavior +including both screen and keyboard handling. +<li><a href='html/edit.mu.html'>edit.mu</a>: the programming environment I +plan to use to teach programming. </ul> <p><b>Part I</b>: basic infrastructure @@ -156,12 +158,12 @@ the real screen with fake ones for testing. <br/><a href='html/072scenario_screen.cc.html'>072scenario_screen.cc</a>: writing tests that check what is printed to screen. (<a href='html/073scenario_screen_test.mu.html'>examples</a>) -<br/><a href='html/074keyboard.mu.html'>074keyboard.mu</a>: helpers that can -swap the real keyboard with fake ones for testing. -<br/><a href='html/075scenario_keyboard.cc.html'>075scenario_keyboard.cc</a>: -writing tests using a fake keyboard. -(<a href='html/076scenario_keyboard_test.mu.html'>examples</a>) -<br/><a href='html/077trace_browser.cc.html'>077trace_browser.cc</a>: a +<br/><a href='html/074console.mu.html'>074console.mu</a>: helpers that can +swap the real keyboard and mouse with fake ones for testing. +<br/><a href='html/075scenario_console.cc.html'>075scenario_console.cc</a>: +writing tests for keyboard and mouse using the fakes. +(<a href='html/076scenario_console_test.mu.html'>examples</a>) +<br/><a href='html/080trace_browser.cc.html'>080trace_browser.cc</a>: a zoomable UI for inspecting traces generated by mu programs. Allows both scanning a high-level view and drilling down into selective details. |