diff options
Diffstat (limited to 'html')
66 files changed, 4547 insertions, 2622 deletions
diff --git a/html/000organization.cc.html b/html/000organization.cc.html index b882e19c..bbc09e8d 100644 --- a/html/000organization.cc.html +++ b/html/000organization.cc.html @@ -14,10 +14,9 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background- body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } .Delimiter { color: #a04060; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.PreProc { color: #c000c0; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } -.PreProc { color: #c000c0; } .Identifier { color: #804000; } --> </style> @@ -132,7 +131,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment">// Globals</span> <span class="Comment">// End Globals</span> -<span class="Normal">int</span> main<span class="Delimiter">(</span><span class="Normal">int</span> argc<span class="Delimiter">,</span> <span class="Normal">char</span>* argv[]<span class="Delimiter">)</span> <span class="Delimiter">{</span> +int main<span class="Delimiter">(</span>int argc<span class="Delimiter">,</span> char* argv[]<span class="Delimiter">)</span> <span class="Delimiter">{</span> atexit<span class="Delimiter">(</span>teardown<span class="Delimiter">);</span> <span class="Comment">// End One-time Setup</span> @@ -149,11 +148,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment">//: Without directives or with the :(code) directive, lines get added at the</span> <span class="Comment">//: end.</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> setup<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void setup<span class="Delimiter">()</span> <span class="Delimiter">{</span> <span class="Comment">// End Setup</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> teardown<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void teardown<span class="Delimiter">()</span> <span class="Delimiter">{</span> <span class="Comment">// End Teardown</span> <span class="Delimiter">}</span> </pre> diff --git a/html/001help.cc.html b/html/001help.cc.html index d82d1685..3802c699 100644 --- a/html/001help.cc.html +++ b/html/001help.cc.html @@ -13,13 +13,12 @@ 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; } -.SalientComment { color: #00ffff; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } .PreProc { color: #c000c0; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.Constant { color: #00a0a0; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } +.SalientComment { color: #00ffff; } .Identifier { color: #804000; } --> </style> @@ -36,7 +35,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment">//: This should give you a sense for what to look forward to in later layers.</span> <span class="Delimiter">:(before "End Commandline Parsing")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>argc <= <span class="Constant">1</span> || is_equal<span class="Delimiter">(</span>argv[<span class="Constant">1</span>]<span class="Delimiter">,</span> <span class="Constant">"--help"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> +if <span class="Delimiter">(</span>argc <= <span class="Constant">1</span> || is_equal<span class="Delimiter">(</span>argv[<span class="Constant">1</span>]<span class="Delimiter">,</span> <span class="Constant">"--help"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Comment">// this is the functionality later layers will provide</span> <span class="Comment">// currently no automated tests for commandline arg parsing</span> cerr << <span class="Constant">"To load files and run 'main':</span><span class="cSpecial">\n</span><span class="Constant">"</span> @@ -59,7 +58,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment">//: way, our makefile contains a little command to automatically generate</span> <span class="Comment">//: declarations for them.</span> <span class="Delimiter">:(code)</span> -<span class="Normal">bool</span> is_equal<span class="Delimiter">(</span><span class="Normal">char</span>* s<span class="Delimiter">,</span> <span class="Normal">const</span> <span class="Normal">char</span>* lit<span class="Delimiter">)</span> <span class="Delimiter">{</span> +bool is_equal<span class="Delimiter">(</span>char* s<span class="Delimiter">,</span> const char* lit<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> strncmp<span class="Delimiter">(</span>s<span class="Delimiter">,</span> lit<span class="Delimiter">,</span> strlen<span class="Delimiter">(</span>lit<span class="Delimiter">))</span> == <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -112,7 +111,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment">// yadda-yadda. Instead use this macro below to perform an unsafe cast to</span> <span class="Comment">// signed. We'll just give up immediately if a container's every too large.</span> <span class="Delimiter">:(before "End Includes")</span> -<span class="PreProc">#define SIZE(X) (assert(X</span><span class="Delimiter">.</span><span class="PreProc">size() < (</span><span class="Constant">1LL</span><span class="PreProc"><<(</span><span class="Normal">sizeof</span><span class="PreProc">(</span><span class="Normal">long</span><span class="PreProc"> </span><span class="Normal">long</span><span class="PreProc"> </span><span class="Normal">int</span><span class="PreProc">)*</span><span class="Constant">8</span><span class="PreProc">-</span><span class="Constant">2</span><span class="PreProc">)))</span><span class="Delimiter">,</span><span class="PreProc"> </span><span class="Normal">static_cast</span><span class="PreProc"><</span><span class="Normal">long</span><span class="PreProc"> </span><span class="Normal">long</span><span class="PreProc"> </span><span class="Normal">int</span><span class="PreProc">>(X</span><span class="Delimiter">.</span><span class="PreProc">size()))</span> +<span class="PreProc">#define SIZE(X) (assert(X</span><span class="Delimiter">.</span><span class="PreProc">size() < (</span><span class="Constant">1LL</span><span class="PreProc"><<(</span>sizeof<span class="PreProc">(</span>long<span class="PreProc"> </span>long<span class="PreProc"> </span>int<span class="PreProc">)*</span><span class="Constant">8</span><span class="PreProc">-</span><span class="Constant">2</span><span class="PreProc">)))</span><span class="Delimiter">,</span><span class="PreProc"> </span>static_cast<span class="PreProc"><</span>long<span class="PreProc"> </span>long<span class="PreProc"> </span>int<span class="PreProc">>(X</span><span class="Delimiter">.</span><span class="PreProc">size()))</span> <span class="Comment">//</span> <span class="Comment">// 5. Integer overflow is still impossible to guard against. Maybe after</span> <span class="Comment">// reading <a href="http://www.cs.utah.edu/~regehr/papers/overflow12.pdf">http://www.cs.utah.edu/~regehr/papers/overflow12.pdf</a></span> @@ -121,16 +120,16 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="PreProc">#include</span><span class="Constant"><assert.h></span> <span class="PreProc">#include</span><span class="Constant"><iostream></span> -<span class="Normal">using</span> std::istream<span class="Delimiter">;</span> -<span class="Normal">using</span> std::ostream<span class="Delimiter">;</span> -<span class="Normal">using</span> std::iostream<span class="Delimiter">;</span> -<span class="Normal">using</span> std::cin<span class="Delimiter">;</span> -<span class="Normal">using</span> std::cout<span class="Delimiter">;</span> -<span class="Normal">using</span> std::cerr<span class="Delimiter">;</span> +using std::istream<span class="Delimiter">;</span> +using std::ostream<span class="Delimiter">;</span> +using std::iostream<span class="Delimiter">;</span> +using std::cin<span class="Delimiter">;</span> +using std::cout<span class="Delimiter">;</span> +using std::cerr<span class="Delimiter">;</span> <span class="PreProc">#include</span><span class="Constant"><cstring></span> <span class="PreProc">#include</span><span class="Constant"><string></span> -<span class="Normal">using</span> std::string<span class="Delimiter">;</span> +using std::string<span class="Delimiter">;</span> </pre> </body> </html> diff --git a/html/002test.cc.html b/html/002test.cc.html index 52b32d33..d6d5ece6 100644 --- a/html/002test.cc.html +++ b/html/002test.cc.html @@ -13,14 +13,13 @@ 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; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } -.Comment { color: #9090ff; } -.Delimiter { color: #a04060; } .CommentedCode { color: #6c6c6c; } .PreProc { color: #c000c0; } +.Comment { color: #9090ff; } +.Delimiter { color: #a04060; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } --> </style> @@ -43,19 +42,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment">//: subsets of the program.</span> <span class="Delimiter">:(before "End Types")</span> -<span class="Normal">typedef</span> <span class="Normal">void</span> <span class="Delimiter">(</span>*test_fn<span class="Delimiter">)(</span><span class="Normal">void</span><span class="Delimiter">);</span> +typedef void <span class="Delimiter">(</span>*test_fn<span class="Delimiter">)(</span>void<span class="Delimiter">);</span> <span class="Delimiter">:(before "End Globals")</span> -<span class="Normal">const</span> test_fn Tests[] = <span class="Delimiter">{</span> +const test_fn Tests[] = <span class="Delimiter">{</span> <span class="PreProc"> #include </span><span class="Constant">"test_list"</span> <span class="Comment">// auto-generated; see makefile</span> <span class="Delimiter">};</span> -<span class="Normal">bool</span> Run_tests = <span class="Constant">false</span><span class="Delimiter">;</span> -<span class="Normal">bool</span> Passed = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Comment">// set this to false inside any test to indicate failure</span> -<span class="Normal">long</span> Num_failures = <span class="Constant">0</span><span class="Delimiter">;</span> +bool Run_tests = <span class="Constant">false</span><span class="Delimiter">;</span> +bool Passed = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Comment">// set this to false inside any test to indicate failure</span> +long Num_failures = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="PreProc">#define CHECK(X) \</span> -<span class="PreProc"> </span><span class="Normal">if</span><span class="PreProc"> (!(X)) </span><span class="Delimiter">{</span><span class="PreProc"> \</span> +<span class="PreProc"> </span>if<span class="PreProc"> (!(X)) </span><span class="Delimiter">{</span><span class="PreProc"> \</span> <span class="PreProc"> ++Num_failures</span><span class="Delimiter">;</span><span class="PreProc"> \</span> <span class="PreProc"> cerr << </span><span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span><span class="PreProc"> << __FUNCTION__ << </span><span class="Constant">"("</span><span class="PreProc"> << </span><span class="Constant">__FILE__</span><span class="PreProc"> << </span><span class="Constant">":"</span><span class="PreProc"> << </span><span class="Constant">__LINE__</span><span class="PreProc"> << </span><span class="Constant">"): "</span><span class="PreProc"> << #X << </span><span class="cSpecial">'\n'</span><span class="Delimiter">;</span><span class="PreProc"> \</span> <span class="PreProc"> Passed = </span><span class="Constant">false</span><span class="Delimiter">;</span><span class="PreProc"> \</span> @@ -63,7 +62,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="PreProc"> </span><span class="Delimiter">}</span> <span class="PreProc">#define CHECK_EQ(X</span><span class="Delimiter">,</span><span class="PreProc"> Y) \</span> -<span class="PreProc"> </span><span class="Normal">if</span><span class="PreProc"> ((X) != (Y)) </span><span class="Delimiter">{</span><span class="PreProc"> \</span> +<span class="PreProc"> </span>if<span class="PreProc"> ((X) != (Y)) </span><span class="Delimiter">{</span><span class="PreProc"> \</span> <span class="PreProc"> ++Num_failures</span><span class="Delimiter">;</span><span class="PreProc"> \</span> <span class="PreProc"> cerr << </span><span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span><span class="PreProc"> << __FUNCTION__ << </span><span class="Constant">"("</span><span class="PreProc"> << </span><span class="Constant">__FILE__</span><span class="PreProc"> << </span><span class="Constant">":"</span><span class="PreProc"> << </span><span class="Constant">__LINE__</span><span class="PreProc"> << </span><span class="Constant">"): "</span><span class="PreProc"> << #X << </span><span class="Constant">" == "</span><span class="PreProc"> << #Y << </span><span class="cSpecial">'\n'</span><span class="Delimiter">;</span><span class="PreProc"> \</span> <span class="PreProc"> cerr << </span><span class="Constant">" got "</span><span class="PreProc"> << (X) << </span><span class="cSpecial">'\n'</span><span class="Delimiter">;</span><span class="PreProc"> </span><span class="Comment">/*</span><span class="Comment"> BEWARE: multiple eval </span><span class="Comment">*/</span><span class="PreProc"> \</span> @@ -75,25 +74,25 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } Passed = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End Commandline Parsing")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>argc > <span class="Constant">1</span> && is_equal<span class="Delimiter">(</span>argv[<span class="Constant">1</span>]<span class="Delimiter">,</span> <span class="Constant">"test"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> +if <span class="Delimiter">(</span>argc > <span class="Constant">1</span> && is_equal<span class="Delimiter">(</span>argv[<span class="Constant">1</span>]<span class="Delimiter">,</span> <span class="Constant">"test"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> Run_tests = <span class="Constant">true</span><span class="Delimiter">;</span> --argc<span class="Delimiter">;</span> ++argv<span class="Delimiter">;</span> <span class="Comment">// shift 'test' out of commandline args</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Main")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>Run_tests<span class="Delimiter">)</span> <span class="Delimiter">{</span> +if <span class="Delimiter">(</span>Run_tests<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// Test Runs</span> <span class="Comment">// we run some tests and then exit; assume no state need be maintained afterward</span> <span class="Comment">// End Test Run Initialization</span> - <span class="Normal">time_t</span> t<span class="Delimiter">;</span> time<span class="Delimiter">(</span>&t<span class="Delimiter">);</span> + time_t t<span class="Delimiter">;</span> time<span class="Delimiter">(</span>&t<span class="Delimiter">);</span> cerr << <span class="Constant">"C tests: "</span> << ctime<span class="Delimiter">(</span>&t<span class="Delimiter">);</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">size_t</span> i=<span class="Constant">0</span><span class="Delimiter">;</span> i < <span class="Normal">sizeof</span><span class="Delimiter">(</span>Tests<span class="Delimiter">)</span>/<span class="Normal">sizeof</span><span class="Delimiter">(</span>Tests[<span class="Constant">0</span>]<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>size_t i=<span class="Constant">0</span><span class="Delimiter">;</span> i < sizeof<span class="Delimiter">(</span>Tests<span class="Delimiter">)</span>/sizeof<span class="Delimiter">(</span>Tests[<span class="Constant">0</span>]<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << i << '\n'; //? 2</span> run_test<span class="Delimiter">(</span>i<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Comment">// End Tests</span> cerr << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Num_failures > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Num_failures > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> cerr << Num_failures << <span class="Constant">" failure"</span> << <span class="Delimiter">(</span>Num_failures > <span class="Constant">1</span> ? <span class="Constant">"s"</span> : <span class="Constant">""</span><span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> @@ -103,8 +102,8 @@ Passed = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> run_test<span class="Delimiter">(</span><span class="Normal">size_t</span> i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>i >= <span class="Normal">sizeof</span><span class="Delimiter">(</span>Tests<span class="Delimiter">)</span>/<span class="Normal">sizeof</span><span class="Delimiter">(</span>Tests[<span class="Constant">0</span>]<span class="Delimiter">))</span> <span class="Delimiter">{</span> +void run_test<span class="Delimiter">(</span>size_t i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>i >= sizeof<span class="Delimiter">(</span>Tests<span class="Delimiter">)</span>/sizeof<span class="Delimiter">(</span>Tests[<span class="Constant">0</span>]<span class="Delimiter">))</span> <span class="Delimiter">{</span> cerr << <span class="Constant">"no test "</span> << i << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -112,22 +111,34 @@ Passed = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Comment">// End Test Setup</span> <span class="Delimiter">(</span>*Tests[i]<span class="Delimiter">)();</span> teardown<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Passed<span class="Delimiter">)</span> cerr << <span class="Constant">"."</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>Passed<span class="Delimiter">)</span> cerr << <span class="Constant">"."</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">bool</span> is_integer<span class="Delimiter">(</span><span class="Normal">const</span> string& s<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Identifier">return</span> s<span class="Delimiter">.</span>find_first_not_of<span class="Delimiter">(</span><span class="Constant">"0123456789-"</span><span class="Delimiter">)</span> == string::npos<span class="Delimiter">;</span> +bool is_integer<span class="Delimiter">(</span>const string& s<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Identifier">return</span> s<span class="Delimiter">.</span>find_first_not_of<span class="Delimiter">(</span><span class="Constant">"0123456789-"</span><span class="Delimiter">)</span> == string::npos + && s<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">'-'</span><span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">)</span> == string::npos + && s<span class="Delimiter">.</span>find_first_of<span class="Delimiter">(</span><span class="Constant">"0123456789"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> to_integer<span class="Delimiter">(</span>string n<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">char</span>* end = <span class="Constant">NULL</span><span class="Delimiter">;</span> +long long int to_integer<span class="Delimiter">(</span>string n<span class="Delimiter">)</span> <span class="Delimiter">{</span> + char* end = <span class="Constant">NULL</span><span class="Delimiter">;</span> <span class="Comment">// safe because string.c_str() is guaranteed to be null-terminated</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> result = strtoll<span class="Delimiter">(</span>n<span class="Delimiter">.</span>c_str<span class="Delimiter">(),</span> &end<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">any base</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>*end != <span class="cSpecial">'\0'</span><span class="Delimiter">)</span> cerr << <span class="Constant">"tried to convert "</span> << n << <span class="Constant">" to number</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span> + long long int result = strtoll<span class="Delimiter">(</span>n<span class="Delimiter">.</span>c_str<span class="Delimiter">(),</span> &end<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">any base</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">);</span> + if <span class="Delimiter">(</span>*end != <span class="cSpecial">'\0'</span><span class="Delimiter">)</span> cerr << <span class="Constant">"tried to convert "</span> << n << <span class="Constant">" to number</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span> assert<span class="Delimiter">(</span>*end == <span class="cSpecial">'\0'</span><span class="Delimiter">);</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> +void test_is_integer<span class="Delimiter">()</span> <span class="Delimiter">{</span> + CHECK<span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span><span class="Constant">"1234"</span><span class="Delimiter">));</span> + CHECK<span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span><span class="Constant">"-1"</span><span class="Delimiter">));</span> + CHECK<span class="Delimiter">(</span>!is_integer<span class="Delimiter">(</span><span class="Constant">"234.0"</span><span class="Delimiter">));</span> + CHECK<span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span><span class="Constant">"-567"</span><span class="Delimiter">));</span> + CHECK<span class="Delimiter">(</span>!is_integer<span class="Delimiter">(</span><span class="Constant">"89-0"</span><span class="Delimiter">));</span> + CHECK<span class="Delimiter">(</span>!is_integer<span class="Delimiter">(</span><span class="Constant">"-"</span><span class="Delimiter">));</span> + CHECK<span class="Delimiter">(</span>!is_integer<span class="Delimiter">(</span><span class="Constant">"1e3"</span><span class="Delimiter">));</span> <span class="Comment">// not supported</span> +<span class="Delimiter">}</span> + <span class="Delimiter">:(before "End Includes")</span> <span class="PreProc">#include</span><span class="Constant"><cstdlib></span> </pre> diff --git a/html/003trace.cc.html b/html/003trace.cc.html index 6894ecfc..6209ed7b 100644 --- a/html/003trace.cc.html +++ b/html/003trace.cc.html @@ -13,14 +13,13 @@ 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; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } .PreProc { color: #c000c0; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.Identifier { color: #804000; } +.Constant { color: #00a0a0; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .CommentedCode { color: #6c6c6c; } -.Identifier { color: #804000; } --> </style> @@ -115,64 +114,64 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment">// End Tracing // hack to ensure most code in this layer comes before anything else</span> <span class="Delimiter">:(before "End Tracing")</span> -<span class="Normal">bool</span> Hide_warnings = <span class="Constant">false</span><span class="Delimiter">;</span> +bool Hide_warnings = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End Setup")</span> <span class="CommentedCode">//? cerr << "AAA setup\n"; //? 2</span> Hide_warnings = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End Types")</span> -<span class="Normal">struct</span> trace_line <span class="Delimiter">{</span> - <span class="Normal">int</span> depth<span class="Delimiter">;</span> <span class="Comment">// optional field just to help browse traces later</span> +struct trace_line <span class="Delimiter">{</span> + int depth<span class="Delimiter">;</span> <span class="Comment">// optional field just to help browse traces later</span> string label<span class="Delimiter">;</span> string contents<span class="Delimiter">;</span> trace_line<span class="Delimiter">(</span>string l<span class="Delimiter">,</span> string c<span class="Delimiter">)</span> :depth<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">),</span> label<span class="Delimiter">(</span>l<span class="Delimiter">),</span> contents<span class="Delimiter">(</span>c<span class="Delimiter">)</span> <span class="Delimiter">{}</span> - trace_line<span class="Delimiter">(</span><span class="Normal">int</span> d<span class="Delimiter">,</span> string l<span class="Delimiter">,</span> string c<span class="Delimiter">)</span> :depth<span class="Delimiter">(</span>d<span class="Delimiter">),</span> label<span class="Delimiter">(</span>l<span class="Delimiter">),</span> contents<span class="Delimiter">(</span>c<span class="Delimiter">)</span> <span class="Delimiter">{}</span> + trace_line<span class="Delimiter">(</span>int d<span class="Delimiter">,</span> string l<span class="Delimiter">,</span> string c<span class="Delimiter">)</span> :depth<span class="Delimiter">(</span>d<span class="Delimiter">),</span> label<span class="Delimiter">(</span>l<span class="Delimiter">),</span> contents<span class="Delimiter">(</span>c<span class="Delimiter">)</span> <span class="Delimiter">{}</span> <span class="Delimiter">};</span> <span class="Delimiter">:(before "End Tracing")</span> -<span class="Normal">struct</span> trace_stream <span class="Delimiter">{</span> +struct trace_stream <span class="Delimiter">{</span> vector<trace_line> past_lines<span class="Delimiter">;</span> <span class="Comment">// accumulator for current line</span> ostringstream* curr_stream<span class="Delimiter">;</span> string curr_layer<span class="Delimiter">;</span> - <span class="Normal">int</span> curr_depth<span class="Delimiter">;</span> + int curr_depth<span class="Delimiter">;</span> string dump_layer<span class="Delimiter">;</span> set<string> collect_layers<span class="Delimiter">;</span> <span class="Comment">// if not empty, ignore all absent 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> <span class="Normal">if</span> <span class="Delimiter">(</span>curr_stream<span class="Delimiter">)</span> <span class="Normal">delete</span> curr_stream<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> 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> - ostream& stream<span class="Delimiter">(</span><span class="Normal">int</span> depth<span class="Delimiter">,</span> string layer<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!is_collecting<span class="Delimiter">(</span>layer<span class="Delimiter">))</span> <span class="Identifier">return</span> null_stream<span class="Delimiter">;</span> - curr_stream = <span class="Normal">new</span> ostringstream<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>!is_collecting<span class="Delimiter">(</span>layer<span class="Delimiter">))</span> <span class="Identifier">return</span> null_stream<span class="Delimiter">;</span> + curr_stream = new ostringstream<span class="Delimiter">;</span> curr_layer = layer<span class="Delimiter">;</span> curr_depth = depth<span class="Delimiter">;</span> <span class="Identifier">return</span> *curr_stream<span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">bool</span> is_collecting<span class="Delimiter">(</span><span class="Normal">const</span> string& layer<span class="Delimiter">)</span> <span class="Delimiter">{</span> + bool is_collecting<span class="Delimiter">(</span>const string& layer<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> collect_layers<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> || collect_layers<span class="Delimiter">.</span>find<span class="Delimiter">(</span>layer<span class="Delimiter">)</span> != collect_layers<span class="Delimiter">.</span>end<span class="Delimiter">();</span> <span class="Delimiter">}</span> - <span class="Normal">bool</span> is_narrowly_collecting<span class="Delimiter">(</span><span class="Normal">const</span> string& layer<span class="Delimiter">)</span> <span class="Delimiter">{</span> + bool is_narrowly_collecting<span class="Delimiter">(</span>const string& layer<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> collect_layers<span class="Delimiter">.</span>find<span class="Delimiter">(</span>layer<span class="Delimiter">)</span> != collect_layers<span class="Delimiter">.</span>end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Comment">// be sure to call this before messing with curr_stream or curr_layer</span> - <span class="Normal">void</span> newline<span class="Delimiter">()</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!curr_stream<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + void newline<span class="Delimiter">()</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!curr_stream<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> string curr_contents = curr_stream<span class="Delimiter">-></span>str<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr_contents<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>curr_contents<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> past_lines<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>trace_line<span class="Delimiter">(</span>curr_depth<span class="Delimiter">,</span> trim<span class="Delimiter">(</span>curr_layer<span class="Delimiter">),</span> curr_contents<span class="Delimiter">));</span> <span class="Comment">// preserve indent in contents</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr_layer == dump_layer || curr_layer == <span class="Constant">"dump"</span> || dump_layer == <span class="Constant">"all"</span> || + if <span class="Delimiter">(</span>curr_layer == dump_layer || curr_layer == <span class="Constant">"dump"</span> || dump_layer == <span class="Constant">"all"</span> || <span class="Delimiter">(</span>!Hide_warnings && curr_layer == <span class="Constant">"warn"</span><span class="Delimiter">))</span> <span class="CommentedCode">//? if (dump_layer == "all" && (Current_routine->id == 3 || curr_layer == "schedule")) //? 1</span> cerr << curr_layer << <span class="Constant">": "</span> << curr_contents << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> - <span class="Normal">delete</span> curr_stream<span class="Delimiter">;</span> + delete curr_stream<span class="Delimiter">;</span> curr_stream = <span class="Constant">NULL</span><span class="Delimiter">;</span> curr_layer<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> curr_depth = <span class="Constant">0</span><span class="Delimiter">;</span> @@ -182,9 +181,9 @@ Hide_warnings = <span class="Constant">false</span><span class="Delimiter">;</sp string readable_contents<span class="Delimiter">(</span>string layer<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// missing layer = everything</span> ostringstream output<span class="Delimiter">;</span> layer = trim<span class="Delimiter">(</span>layer<span class="Delimiter">);</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>vector<trace_line>::iterator p = past_lines<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != past_lines<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>layer<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> || layer == p<span class="Delimiter">-></span>label<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>p<span class="Delimiter">-></span>depth<span class="Delimiter">)</span> + for <span class="Delimiter">(</span>vector<trace_line>::iterator p = past_lines<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != past_lines<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> + if <span class="Delimiter">(</span>layer<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> || layer == p<span class="Delimiter">-></span>label<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>p<span class="Delimiter">-></span>depth<span class="Delimiter">)</span> output << std::setw<span class="Delimiter">(</span><span class="Constant">4</span><span class="Delimiter">)</span> << p<span class="Delimiter">-></span>depth << <span class="Constant">' '</span><span class="Delimiter">;</span> output << p<span class="Delimiter">-></span>label << <span class="Constant">": "</span> << p<span class="Delimiter">-></span>contents << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -203,34 +202,34 @@ trace_stream* Trace_stream = <span class="Constant">NULL</span><span class="Deli <span class="PreProc">#define raise ((!Trace_stream || !Hide_warnings) ? (tb_shutdown()</span><span class="Delimiter">,</span><span class="PreProc">cerr) </span><span class="Comment">/*</span><span class="Comment">do print</span><span class="Comment">*/</span><span class="PreProc"> : Trace_stream</span><span class="Delimiter">-></span><span class="PreProc">stream(</span><span class="Constant">"warn"</span><span class="PreProc">))</span> <span class="Delimiter">:(before "End Types")</span> -<span class="Normal">struct</span> end <span class="Delimiter">{};</span> +struct end <span class="Delimiter">{};</span> <span class="Delimiter">:(before "End Tracing")</span> -ostream& <span class="Normal">operator</span><<<span class="Delimiter">(</span>ostream& os<span class="Delimiter">,</span> unused end<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">)</span> Trace_stream<span class="Delimiter">-></span>newline<span class="Delimiter">();</span> +ostream& operator<<<span class="Delimiter">(</span>ostream& os<span class="Delimiter">,</span> unused end<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">)</span> Trace_stream<span class="Delimiter">-></span>newline<span class="Delimiter">();</span> <span class="Identifier">return</span> os<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="PreProc">#define CLEAR_TRACE </span><span class="Normal">delete</span><span class="PreProc"> Trace_stream</span><span class="Delimiter">,</span><span class="PreProc"> Trace_stream = </span><span class="Normal">new</span><span class="PreProc"> trace_stream</span><span class="Delimiter">;</span> +<span class="PreProc">#define CLEAR_TRACE </span>delete<span class="PreProc"> Trace_stream</span><span class="Delimiter">,</span><span class="PreProc"> Trace_stream = </span>new<span class="PreProc"> trace_stream</span><span class="Delimiter">;</span> -<span class="PreProc">#define DUMP(layer) </span><span class="Normal">if</span><span class="PreProc"> (Trace_stream) cerr << Trace_stream</span><span class="Delimiter">-></span><span class="PreProc">readable_contents(layer)</span><span class="Delimiter">;</span> +<span class="PreProc">#define DUMP(layer) </span>if<span class="PreProc"> (Trace_stream) cerr << Trace_stream</span><span class="Delimiter">-></span><span class="PreProc">readable_contents(layer)</span><span class="Delimiter">;</span> <span class="Comment">// All scenarios save their traces in the repo, just like code. This gives</span> <span class="Comment">// future readers more meat when they try to make sense of a new project.</span> -<span class="Normal">static</span> string Trace_dir = <span class="Constant">".traces/"</span><span class="Delimiter">;</span> +static string Trace_dir = <span class="Constant">".traces/"</span><span class="Delimiter">;</span> string Trace_file<span class="Delimiter">;</span> <span class="Comment">// Trace_stream is a resource, lease_tracer uses RAII to manage it.</span> -<span class="Normal">struct</span> lease_tracer <span class="Delimiter">{</span> - lease_tracer<span class="Delimiter">()</span> <span class="Delimiter">{</span> Trace_stream = <span class="Normal">new</span> trace_stream<span class="Delimiter">;</span> <span class="Delimiter">}</span> +struct lease_tracer <span class="Delimiter">{</span> + lease_tracer<span class="Delimiter">()</span> <span class="Delimiter">{</span> Trace_stream = new trace_stream<span class="Delimiter">;</span> <span class="Delimiter">}</span> ~lease_tracer<span class="Delimiter">()</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << "write to file? " << Trace_file << "$\n"; //? 2</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Trace_file<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!Trace_file<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << "writing\n"; //? 2</span> ofstream fout<span class="Delimiter">((</span>Trace_dir+Trace_file<span class="Delimiter">).</span>c_str<span class="Delimiter">());</span> fout << Trace_stream<span class="Delimiter">-></span>readable_contents<span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">);</span> fout<span class="Delimiter">.</span>close<span class="Delimiter">();</span> <span class="Delimiter">}</span> - <span class="Normal">delete</span> Trace_stream<span class="Delimiter">,</span> Trace_stream = <span class="Constant">NULL</span><span class="Delimiter">,</span> Trace_file = <span class="Constant">""</span><span class="Delimiter">;</span> + delete Trace_stream<span class="Delimiter">,</span> Trace_stream = <span class="Constant">NULL</span><span class="Delimiter">,</span> Trace_file = <span class="Constant">""</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">};</span> @@ -242,47 +241,47 @@ START_TRACING_UNTIL_END_OF_SCOPE <span class="PreProc">#define CHECK_TRACE_CONTENTS(</span><span class="Delimiter">...</span><span class="PreProc">) check_trace_contents(__FUNCTION__</span><span class="Delimiter">,</span><span class="PreProc"> </span><span class="Constant">__FILE__</span><span class="Delimiter">,</span><span class="PreProc"> </span><span class="Constant">__LINE__</span><span class="Delimiter">,</span><span class="PreProc"> __VA_ARGS__)</span> <span class="Delimiter">:(before "End Tracing")</span> -<span class="Normal">bool</span> check_trace_contents<span class="Delimiter">(</span>string FUNCTION<span class="Delimiter">,</span> string <span class="Normal">FILE</span><span class="Delimiter">,</span> <span class="Normal">int</span> LINE<span class="Delimiter">,</span> string expected<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// missing layer == anywhere</span> +bool check_trace_contents<span class="Delimiter">(</span>string FUNCTION<span class="Delimiter">,</span> string FILE<span class="Delimiter">,</span> int LINE<span class="Delimiter">,</span> string expected<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// missing layer == anywhere</span> vector<string> expected_lines = split<span class="Delimiter">(</span>expected<span class="Delimiter">,</span> <span class="Constant">"^D"</span><span class="Delimiter">);</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> curr_expected_line = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>curr_expected_line < SIZE<span class="Delimiter">(</span>expected_lines<span class="Delimiter">)</span> && expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>empty<span class="Delimiter">())</span> + long long int curr_expected_line = <span class="Constant">0</span><span class="Delimiter">;</span> + while <span class="Delimiter">(</span>curr_expected_line < SIZE<span class="Delimiter">(</span>expected_lines<span class="Delimiter">)</span> && expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>empty<span class="Delimiter">())</span> ++curr_expected_line<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr_expected_line == SIZE<span class="Delimiter">(</span>expected_lines<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>curr_expected_line == SIZE<span class="Delimiter">(</span>expected_lines<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> string layer<span class="Delimiter">,</span> contents<span class="Delimiter">;</span> split_layer_contents<span class="Delimiter">(</span>expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">),</span> &layer<span class="Delimiter">,</span> &contents<span class="Delimiter">);</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>vector<trace_line>::iterator p = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>vector<trace_line>::iterator p = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << "AAA " << layer << ' ' << p->label << '\n'; //? 1</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>layer != p<span class="Delimiter">-></span>label<span class="Delimiter">)</span> + if <span class="Delimiter">(</span>layer != p<span class="Delimiter">-></span>label<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="CommentedCode">//? cerr << "BBB ^" << contents << "$ ^" << p->contents << "$\n"; //? 1</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>contents != trim<span class="Delimiter">(</span>p<span class="Delimiter">-></span>contents<span class="Delimiter">))</span> + if <span class="Delimiter">(</span>contents != trim<span class="Delimiter">(</span>p<span class="Delimiter">-></span>contents<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="CommentedCode">//? cerr << "CCC\n"; //? 1</span> ++curr_expected_line<span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>curr_expected_line < SIZE<span class="Delimiter">(</span>expected_lines<span class="Delimiter">)</span> && expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>empty<span class="Delimiter">())</span> + while <span class="Delimiter">(</span>curr_expected_line < SIZE<span class="Delimiter">(</span>expected_lines<span class="Delimiter">)</span> && expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>empty<span class="Delimiter">())</span> ++curr_expected_line<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr_expected_line == SIZE<span class="Delimiter">(</span>expected_lines<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>curr_expected_line == SIZE<span class="Delimiter">(</span>expected_lines<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> split_layer_contents<span class="Delimiter">(</span>expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">),</span> &layer<span class="Delimiter">,</span> &contents<span class="Delimiter">);</span> <span class="Delimiter">}</span> ++Num_failures<span class="Delimiter">;</span> - cerr << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span> << FUNCTION << <span class="Constant">"("</span> << <span class="Normal">FILE</span> << <span class="Constant">":"</span> << LINE << <span class="Constant">"): missing ["</span> << contents << <span class="Constant">"] in trace:</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span> + cerr << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span> << FUNCTION << <span class="Constant">"("</span> << FILE << <span class="Constant">":"</span> << LINE << <span class="Constant">"): missing ["</span> << contents << <span class="Constant">"] in trace:</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span> DUMP<span class="Delimiter">(</span>layer<span class="Delimiter">);</span> <span class="CommentedCode">//? exit(0); //? 1</span> Passed = <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> -<span class="Normal">void</span> split_layer_contents<span class="Delimiter">(</span><span class="Normal">const</span> string& s<span class="Delimiter">,</span> string* layer<span class="Delimiter">,</span> string* contents<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">static</span> <span class="Normal">const</span> string delim<span class="Delimiter">(</span><span class="Constant">": "</span><span class="Delimiter">);</span> - <span class="Normal">size_t</span> pos = s<span class="Delimiter">.</span>find<span class="Delimiter">(</span>delim<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>pos == string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void split_layer_contents<span class="Delimiter">(</span>const string& s<span class="Delimiter">,</span> string* layer<span class="Delimiter">,</span> string* contents<span class="Delimiter">)</span> <span class="Delimiter">{</span> + static const string delim<span class="Delimiter">(</span><span class="Constant">": "</span><span class="Delimiter">);</span> + size_t pos = s<span class="Delimiter">.</span>find<span class="Delimiter">(</span>delim<span class="Delimiter">);</span> + if <span class="Delimiter">(</span>pos == string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span> *layer = <span class="Constant">""</span><span class="Delimiter">;</span> *contents = trim<span class="Delimiter">(</span>s<span class="Delimiter">);</span> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> + else <span class="Delimiter">{</span> *layer = trim<span class="Delimiter">(</span>s<span class="Delimiter">.</span>substr<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">,</span> pos<span class="Delimiter">));</span> *contents = trim<span class="Delimiter">(</span>s<span class="Delimiter">.</span>substr<span class="Delimiter">(</span>pos+SIZE<span class="Delimiter">(</span>delim<span class="Delimiter">)));</span> <span class="Delimiter">}</span> @@ -290,17 +289,17 @@ START_TRACING_UNTIL_END_OF_SCOPE ^L -<span class="Normal">int</span> trace_count<span class="Delimiter">(</span>string layer<span class="Delimiter">)</span> <span class="Delimiter">{</span> +int trace_count<span class="Delimiter">(</span>string layer<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> trace_count<span class="Delimiter">(</span>layer<span class="Delimiter">,</span> <span class="Constant">""</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">int</span> trace_count<span class="Delimiter">(</span>string layer<span class="Delimiter">,</span> string line<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">long</span> result = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>vector<trace_line>::iterator p = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>layer == p<span class="Delimiter">-></span>label<span class="Delimiter">)</span> <span class="Delimiter">{</span> +int trace_count<span class="Delimiter">(</span>string layer<span class="Delimiter">,</span> string line<span class="Delimiter">)</span> <span class="Delimiter">{</span> + long result = <span class="Constant">0</span><span class="Delimiter">;</span> + for <span class="Delimiter">(</span>vector<trace_line>::iterator p = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>layer == p<span class="Delimiter">-></span>label<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << "a: " << line << "$\n"; //? 1</span> <span class="CommentedCode">//? cerr << "b: " << trim(p->contents) << "$\n"; //? 1</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>line == <span class="Constant">""</span> || line == trim<span class="Delimiter">(</span>p<span class="Delimiter">-></span>contents<span class="Delimiter">))</span> + if <span class="Delimiter">(</span>line == <span class="Constant">""</span> || line == trim<span class="Delimiter">(</span>p<span class="Delimiter">-></span>contents<span class="Delimiter">))</span> ++result<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> @@ -309,7 +308,7 @@ START_TRACING_UNTIL_END_OF_SCOPE <span class="PreProc">#define CHECK_TRACE_WARNS() CHECK(trace_count(</span><span class="Constant">"warn"</span><span class="PreProc">) > </span><span class="Constant">0</span><span class="PreProc">)</span> <span class="PreProc">#define CHECK_TRACE_DOESNT_WARN() \</span> -<span class="PreProc"> </span><span class="Normal">if</span><span class="PreProc"> (trace_count(</span><span class="Constant">"warn"</span><span class="PreProc">) > </span><span class="Constant">0</span><span class="PreProc">) </span><span class="Delimiter">{</span><span class="PreProc"> \</span> +<span class="PreProc"> </span>if<span class="PreProc"> (trace_count(</span><span class="Constant">"warn"</span><span class="PreProc">) > </span><span class="Constant">0</span><span class="PreProc">) </span><span class="Delimiter">{</span><span class="PreProc"> \</span> <span class="PreProc"> ++Num_failures</span><span class="Delimiter">;</span><span class="PreProc"> \</span> <span class="PreProc"> cerr << </span><span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span><span class="PreProc"> << __FUNCTION__ << </span><span class="Constant">"("</span><span class="PreProc"> << </span><span class="Constant">__FILE__</span><span class="PreProc"> << </span><span class="Constant">":"</span><span class="PreProc"> << </span><span class="Constant">__LINE__</span><span class="PreProc"> << </span><span class="Constant">"): unexpected warnings</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span><span class="PreProc"> \</span> <span class="PreProc"> DUMP(</span><span class="Constant">"warn"</span><span class="PreProc">)</span><span class="Delimiter">;</span><span class="PreProc"> \</span> @@ -317,11 +316,11 @@ START_TRACING_UNTIL_END_OF_SCOPE <span class="PreProc"> </span><span class="Identifier">return</span><span class="Delimiter">;</span><span class="PreProc"> \</span> <span class="PreProc"> </span><span class="Delimiter">}</span> -<span class="Normal">bool</span> trace_doesnt_contain<span class="Delimiter">(</span>string layer<span class="Delimiter">,</span> string line<span class="Delimiter">)</span> <span class="Delimiter">{</span> +bool trace_doesnt_contain<span class="Delimiter">(</span>string layer<span class="Delimiter">,</span> string line<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> trace_count<span class="Delimiter">(</span>layer<span class="Delimiter">,</span> line<span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">bool</span> trace_doesnt_contain<span class="Delimiter">(</span>string expected<span class="Delimiter">)</span> <span class="Delimiter">{</span> +bool trace_doesnt_contain<span class="Delimiter">(</span>string expected<span class="Delimiter">)</span> <span class="Delimiter">{</span> vector<string> tmp = split<span class="Delimiter">(</span>expected<span class="Delimiter">,</span> <span class="Constant">": "</span><span class="Delimiter">);</span> <span class="Identifier">return</span> trace_doesnt_contain<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">),</span> tmp<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">));</span> <span class="Delimiter">}</span> @@ -332,9 +331,9 @@ START_TRACING_UNTIL_END_OF_SCOPE vector<string> split<span class="Delimiter">(</span>string s<span class="Delimiter">,</span> string delim<span class="Delimiter">)</span> <span class="Delimiter">{</span> vector<string> result<span class="Delimiter">;</span> - <span class="Normal">size_t</span> begin=<span class="Constant">0</span><span class="Delimiter">,</span> end=s<span class="Delimiter">.</span>find<span class="Delimiter">(</span>delim<span class="Delimiter">);</span> - <span class="Normal">while</span> <span class="Delimiter">(</span><span class="Constant">true</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>end == string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span> + size_t begin=<span class="Constant">0</span><span class="Delimiter">,</span> end=s<span class="Delimiter">.</span>find<span class="Delimiter">(</span>delim<span class="Delimiter">);</span> + while <span class="Delimiter">(</span><span class="Constant">true</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>end == string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span> result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>string<span class="Delimiter">(</span>s<span class="Delimiter">,</span> begin<span class="Delimiter">,</span> string::npos<span class="Delimiter">));</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -345,14 +344,14 @@ vector<string> split<span class="Delimiter">(</span>string s<span class="D <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> -string trim<span class="Delimiter">(</span><span class="Normal">const</span> string& s<span class="Delimiter">)</span> <span class="Delimiter">{</span> +string trim<span class="Delimiter">(</span>const string& s<span class="Delimiter">)</span> <span class="Delimiter">{</span> string::const_iterator first = s<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>first != s<span class="Delimiter">.</span>end<span class="Delimiter">()</span> && isspace<span class="Delimiter">(</span>*first<span class="Delimiter">))</span> + while <span class="Delimiter">(</span>first != s<span class="Delimiter">.</span>end<span class="Delimiter">()</span> && isspace<span class="Delimiter">(</span>*first<span class="Delimiter">))</span> ++first<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>first == s<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">""</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>first == s<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">""</span><span class="Delimiter">;</span> string::const_iterator last = --s<span class="Delimiter">.</span>end<span class="Delimiter">();</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>last != s<span class="Delimiter">.</span>begin<span class="Delimiter">()</span> && isspace<span class="Delimiter">(</span>*last<span class="Delimiter">))</span> + while <span class="Delimiter">(</span>last != s<span class="Delimiter">.</span>begin<span class="Delimiter">()</span> && isspace<span class="Delimiter">(</span>*last<span class="Delimiter">))</span> --last<span class="Delimiter">;</span> ++last<span class="Delimiter">;</span> <span class="Identifier">return</span> string<span class="Delimiter">(</span>first<span class="Delimiter">,</span> last<span class="Delimiter">);</span> @@ -360,30 +359,30 @@ string trim<span class="Delimiter">(</span><span class="Normal">const</span> str <span class="Delimiter">:(before "End Includes")</span> <span class="PreProc">#include</span><span class="Constant"><vector></span> -<span class="Normal">using</span> std::vector<span class="Delimiter">;</span> +using std::vector<span class="Delimiter">;</span> <span class="PreProc">#include</span><span class="Constant"><list></span> -<span class="Normal">using</span> std::list<span class="Delimiter">;</span> +using std::list<span class="Delimiter">;</span> <span class="PreProc">#include</span><span class="Constant"><map></span> -<span class="Normal">using</span> std::map<span class="Delimiter">;</span> +using std::map<span class="Delimiter">;</span> <span class="PreProc">#include</span><span class="Constant"><set></span> -<span class="Normal">using</span> std::set<span class="Delimiter">;</span> +using std::set<span class="Delimiter">;</span> <span class="PreProc">#include</span><span class="Constant"><algorithm></span> <span class="PreProc">#include</span><span class="Constant"><iostream></span> -<span class="Normal">using</span> std::istream<span class="Delimiter">;</span> -<span class="Normal">using</span> std::ostream<span class="Delimiter">;</span> -<span class="Normal">using</span> std::cin<span class="Delimiter">;</span> -<span class="Normal">using</span> std::cout<span class="Delimiter">;</span> -<span class="Normal">using</span> std::cerr<span class="Delimiter">;</span> +using std::istream<span class="Delimiter">;</span> +using std::ostream<span class="Delimiter">;</span> +using std::cin<span class="Delimiter">;</span> +using std::cout<span class="Delimiter">;</span> +using std::cerr<span class="Delimiter">;</span> <span class="PreProc">#include</span><span class="Constant"><iomanip></span> <span class="PreProc">#include</span><span class="Constant"><sstream></span> -<span class="Normal">using</span> std::istringstream<span class="Delimiter">;</span> -<span class="Normal">using</span> std::ostringstream<span class="Delimiter">;</span> +using std::istringstream<span class="Delimiter">;</span> +using std::ostringstream<span class="Delimiter">;</span> <span class="PreProc">#include</span><span class="Constant"><fstream></span> -<span class="Normal">using</span> std::ifstream<span class="Delimiter">;</span> -<span class="Normal">using</span> std::ofstream<span class="Delimiter">;</span> +using std::ifstream<span class="Delimiter">;</span> +using std::ofstream<span class="Delimiter">;</span> <span class="PreProc">#include</span><span class="Constant">"termbox/termbox.h"</span> @@ -394,18 +393,18 @@ string trim<span class="Delimiter">(</span><span class="Normal">const</span> str <span class="Comment">//:</span> <span class="Comment">//: Mu 'applications' will be able to use depths 1-99 as they like.</span> <span class="Comment">//: Depth 100 will be for scheduling (more on that later).</span> -<span class="Normal">const</span> <span class="Normal">int</span> Scheduling_depth = <span class="Constant">100</span><span class="Delimiter">;</span> +const int Scheduling_depth = <span class="Constant">100</span><span class="Delimiter">;</span> <span class="Comment">//: Primitive statements will occupy 101-9998</span> -<span class="Normal">const</span> <span class="Normal">int</span> Initial_callstack_depth = <span class="Constant">101</span><span class="Delimiter">;</span> -<span class="Normal">const</span> <span class="Normal">int</span> Max_callstack_depth = <span class="Constant">9998</span><span class="Delimiter">;</span> +const int Initial_callstack_depth = <span class="Constant">101</span><span class="Delimiter">;</span> +const int Max_callstack_depth = <span class="Constant">9998</span><span class="Delimiter">;</span> <span class="Comment">//: (ignore this until the call layer)</span> <span class="Delimiter">:(before "End Globals")</span> -<span class="Normal">int</span> Callstack_depth = <span class="Constant">0</span><span class="Delimiter">;</span> +int Callstack_depth = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End Setup")</span> Callstack_depth = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Comment">//: Finally, details of primitive mu statements will occupy depth 9999 (more on that later as well)</span> <span class="Delimiter">:(before "End Globals")</span> -<span class="Normal">const</span> <span class="Normal">int</span> Primitive_recipe_depth = <span class="Constant">9999</span><span class="Delimiter">;</span> +const int Primitive_recipe_depth = <span class="Constant">9999</span><span class="Delimiter">;</span> <span class="Comment">//:</span> <span class="Comment">//: This framework should help us hide some details at each level, mixing</span> <span class="Comment">//: static ideas like layers with the dynamic notion of call-stack depth.</span> diff --git a/html/003trace.test.cc.html b/html/003trace.test.cc.html index 11f5060e..9c0a7982 100644 --- a/html/003trace.test.cc.html +++ b/html/003trace.test.cc.html @@ -13,9 +13,8 @@ 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; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.Constant { color: #00a0a0; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } --> @@ -29,60 +28,60 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } </head> <body> <pre id='vimCodeElement'> -<span class="Normal">void</span> test_trace_check_compares<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void test_trace_check_compares<span class="Delimiter">()</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">"test layer"</span><span class="Delimiter">)</span> << <span class="Constant">"foo"</span> << end<span class="Delimiter">();</span> CHECK_TRACE_CONTENTS<span class="Delimiter">(</span><span class="Constant">"test layer: foo"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> test_trace_check_ignores_other_layers<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void test_trace_check_ignores_other_layers<span class="Delimiter">()</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">)</span> << <span class="Constant">"foo"</span> << end<span class="Delimiter">();</span> trace<span class="Delimiter">(</span><span class="Constant">"test layer 2"</span><span class="Delimiter">)</span> << <span class="Constant">"bar"</span> << end<span class="Delimiter">();</span> CHECK_TRACE_CONTENTS<span class="Delimiter">(</span><span class="Constant">"test layer 1: foo"</span><span class="Delimiter">);</span> CHECK_TRACE_DOESNT_CONTAIN<span class="Delimiter">(</span><span class="Constant">"test layer 2: foo"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> test_trace_check_ignores_other_lines<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void test_trace_check_ignores_other_lines<span class="Delimiter">()</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">)</span> << <span class="Constant">"foo"</span> << end<span class="Delimiter">();</span> trace<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">)</span> << <span class="Constant">"bar"</span> << end<span class="Delimiter">();</span> CHECK_TRACE_CONTENTS<span class="Delimiter">(</span><span class="Constant">"test layer 1: foo"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> test_trace_check_ignores_other_lines2<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void test_trace_check_ignores_other_lines2<span class="Delimiter">()</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">)</span> << <span class="Constant">"foo"</span> << end<span class="Delimiter">();</span> trace<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">)</span> << <span class="Constant">"bar"</span> << end<span class="Delimiter">();</span> CHECK_TRACE_CONTENTS<span class="Delimiter">(</span><span class="Constant">"test layer 1: bar"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> test_trace_ignores_trailing_whitespace<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void test_trace_ignores_trailing_whitespace<span class="Delimiter">()</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">)</span> << <span class="Constant">"foo</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> CHECK_TRACE_CONTENTS<span class="Delimiter">(</span><span class="Constant">"test layer 1: foo"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> test_trace_ignores_trailing_whitespace2<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void test_trace_ignores_trailing_whitespace2<span class="Delimiter">()</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">)</span> << <span class="Constant">"foo "</span> << end<span class="Delimiter">();</span> CHECK_TRACE_CONTENTS<span class="Delimiter">(</span><span class="Constant">"test layer 1: foo"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> test_trace_orders_across_layers<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void test_trace_orders_across_layers<span class="Delimiter">()</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">)</span> << <span class="Constant">"foo"</span> << end<span class="Delimiter">();</span> trace<span class="Delimiter">(</span><span class="Constant">"test layer 2"</span><span class="Delimiter">)</span> << <span class="Constant">"bar"</span> << end<span class="Delimiter">();</span> trace<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">)</span> << <span class="Constant">"qux"</span> << end<span class="Delimiter">();</span> CHECK_TRACE_CONTENTS<span class="Delimiter">(</span><span class="Constant">"test layer 1: foo^Dtest layer 2: bar^Dtest layer 1: qux^D"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> test_trace_supports_count<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void test_trace_supports_count<span class="Delimiter">()</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">)</span> << <span class="Constant">"foo"</span> << end<span class="Delimiter">();</span> trace<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">)</span> << <span class="Constant">"foo"</span> << end<span class="Delimiter">();</span> CHECK_EQ<span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">,</span> <span class="Constant">"foo"</span><span class="Delimiter">),</span> <span class="Constant">2</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> test_trace_supports_count2<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void test_trace_supports_count2<span class="Delimiter">()</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">)</span> << <span class="Constant">"foo"</span> << end<span class="Delimiter">();</span> trace<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">)</span> << <span class="Constant">"bar"</span> << end<span class="Delimiter">();</span> CHECK_EQ<span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">),</span> <span class="Constant">2</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> test_trace_count_ignores_trailing_whitespace<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void test_trace_count_ignores_trailing_whitespace<span class="Delimiter">()</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">)</span> << <span class="Constant">"foo</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> CHECK<span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">,</span> <span class="Constant">"foo"</span><span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> @@ -100,26 +99,26 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment">// can't check trace because trace methods call 'split'</span> -<span class="Normal">void</span> test_split_returns_at_least_one_elem<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void test_split_returns_at_least_one_elem<span class="Delimiter">()</span> <span class="Delimiter">{</span> vector<string> result = split<span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">,</span> <span class="Constant">","</span><span class="Delimiter">);</span> CHECK_EQ<span class="Delimiter">(</span>result<span class="Delimiter">.</span>size<span class="Delimiter">(),</span> <span class="Constant">1</span><span class="Delimiter">);</span> CHECK_EQ<span class="Delimiter">(</span>result<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">),</span> <span class="Constant">""</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> test_split_returns_entire_input_when_no_delim<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void test_split_returns_entire_input_when_no_delim<span class="Delimiter">()</span> <span class="Delimiter">{</span> vector<string> result = split<span class="Delimiter">(</span><span class="Constant">"abc"</span><span class="Delimiter">,</span> <span class="Constant">","</span><span class="Delimiter">);</span> CHECK_EQ<span class="Delimiter">(</span>result<span class="Delimiter">.</span>size<span class="Delimiter">(),</span> <span class="Constant">1</span><span class="Delimiter">);</span> CHECK_EQ<span class="Delimiter">(</span>result<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">),</span> <span class="Constant">"abc"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> test_split_works<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void test_split_works<span class="Delimiter">()</span> <span class="Delimiter">{</span> vector<string> result = split<span class="Delimiter">(</span><span class="Constant">"abc,def"</span><span class="Delimiter">,</span> <span class="Constant">","</span><span class="Delimiter">);</span> CHECK_EQ<span class="Delimiter">(</span>result<span class="Delimiter">.</span>size<span class="Delimiter">(),</span> <span class="Constant">2</span><span class="Delimiter">);</span> CHECK_EQ<span class="Delimiter">(</span>result<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">),</span> <span class="Constant">"abc"</span><span class="Delimiter">);</span> CHECK_EQ<span class="Delimiter">(</span>result<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">),</span> <span class="Constant">"def"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> test_split_works2<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void test_split_works2<span class="Delimiter">()</span> <span class="Delimiter">{</span> vector<string> result = split<span class="Delimiter">(</span><span class="Constant">"abc,def,ghi"</span><span class="Delimiter">,</span> <span class="Constant">","</span><span class="Delimiter">);</span> CHECK_EQ<span class="Delimiter">(</span>result<span class="Delimiter">.</span>size<span class="Delimiter">(),</span> <span class="Constant">3</span><span class="Delimiter">);</span> CHECK_EQ<span class="Delimiter">(</span>result<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">),</span> <span class="Constant">"abc"</span><span class="Delimiter">);</span> @@ -127,7 +126,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } CHECK_EQ<span class="Delimiter">(</span>result<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">),</span> <span class="Constant">"ghi"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> test_split_handles_multichar_delim<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void test_split_handles_multichar_delim<span class="Delimiter">()</span> <span class="Delimiter">{</span> vector<string> result = split<span class="Delimiter">(</span><span class="Constant">"abc,,def,,ghi"</span><span class="Delimiter">,</span> <span class="Constant">",,"</span><span class="Delimiter">);</span> CHECK_EQ<span class="Delimiter">(</span>result<span class="Delimiter">.</span>size<span class="Delimiter">(),</span> <span class="Constant">3</span><span class="Delimiter">);</span> CHECK_EQ<span class="Delimiter">(</span>result<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">),</span> <span class="Constant">"abc"</span><span class="Delimiter">);</span> @@ -135,7 +134,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } CHECK_EQ<span class="Delimiter">(</span>result<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">),</span> <span class="Constant">"ghi"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> test_trim<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void test_trim<span class="Delimiter">()</span> <span class="Delimiter">{</span> CHECK_EQ<span class="Delimiter">(</span>trim<span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">),</span> <span class="Constant">""</span><span class="Delimiter">);</span> CHECK_EQ<span class="Delimiter">(</span>trim<span class="Delimiter">(</span><span class="Constant">" "</span><span class="Delimiter">),</span> <span class="Constant">""</span><span class="Delimiter">);</span> CHECK_EQ<span class="Delimiter">(</span>trim<span class="Delimiter">(</span><span class="Constant">" "</span><span class="Delimiter">),</span> <span class="Constant">""</span><span class="Delimiter">);</span> diff --git a/html/010vm.cc.html b/html/010vm.cc.html index 48374903..45e698f0 100644 --- a/html/010vm.cc.html +++ b/html/010vm.cc.html @@ -13,15 +13,14 @@ 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; } -.SalientComment { color: #00ffff; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } +.Identifier { color: #804000; } .PreProc { color: #c000c0; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } +.SalientComment { color: #00ffff; } .CommentedCode { color: #6c6c6c; } -.Identifier { color: #804000; } +.Constant { color: #00a0a0; } --> </style> @@ -46,12 +45,12 @@ recipe_ordinal Next_recipe_ordinal = <span class="Constant">1</span><span class= <span class="Comment">//: adding two phone numbers is meaningless. Here each recipe does something</span> <span class="Comment">//: incommensurable with any other recipe.</span> <span class="Delimiter">:(after "Types")</span> -<span class="Normal">typedef</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> recipe_ordinal<span class="Delimiter">;</span> +typedef long long int recipe_ordinal<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Types")</span> <span class="Comment">// Recipes are lists of instructions. To perform or 'run' a recipe, the</span> <span class="Comment">// computer runs its instructions.</span> -<span class="Normal">struct</span> recipe <span class="Delimiter">{</span> +struct recipe <span class="Delimiter">{</span> string name<span class="Delimiter">;</span> vector<instruction> steps<span class="Delimiter">;</span> <span class="Comment">// End recipe Fields</span> @@ -63,8 +62,8 @@ recipe_ordinal Next_recipe_ordinal = <span class="Constant">1</span><span class= <span class="Comment">// or just a single 'label' starting with a non-alphanumeric character</span> <span class="Comment">// +label</span> <span class="Comment">// Labels don't do anything, they're just waypoints.</span> -<span class="Normal">struct</span> instruction <span class="Delimiter">{</span> - <span class="Normal">bool</span> is_label<span class="Delimiter">;</span> +struct instruction <span class="Delimiter">{</span> + bool is_label<span class="Delimiter">;</span> string label<span class="Delimiter">;</span> <span class="Comment">// only if is_label</span> string name<span class="Delimiter">;</span> <span class="Comment">// only if !is_label</span> recipe_ordinal operation<span class="Delimiter">;</span> <span class="Comment">// Recipe_ordinal[name]</span> @@ -72,8 +71,8 @@ recipe_ordinal Next_recipe_ordinal = <span class="Constant">1</span><span class= vector<reagent> products<span class="Delimiter">;</span> <span class="Comment">// only if !is_label</span> <span class="Comment">// End instruction Fields</span> instruction<span class="Delimiter">();</span> - <span class="Normal">void</span> clear<span class="Delimiter">();</span> - string to_string<span class="Delimiter">()</span> <span class="Normal">const</span><span class="Delimiter">;</span> + void clear<span class="Delimiter">();</span> + string to_string<span class="Delimiter">()</span> const<span class="Delimiter">;</span> <span class="Delimiter">};</span> <span class="Delimiter">:(before "struct instruction")</span> @@ -81,27 +80,27 @@ recipe_ordinal Next_recipe_ordinal = <span class="Constant">1</span><span class= <span class="Comment">// either to numbers or to locations in memory along with 'type' tags telling</span> <span class="Comment">// us how to interpret them. They also can contain arbitrary other lists of</span> <span class="Comment">// properties besides types, but we're getting ahead of ourselves.</span> -<span class="Normal">struct</span> reagent <span class="Delimiter">{</span> +struct reagent <span class="Delimiter">{</span> string original_string<span class="Delimiter">;</span> vector<pair<string<span class="Delimiter">,</span> vector<string> > > properties<span class="Delimiter">;</span> string name<span class="Delimiter">;</span> - <span class="Normal">double</span> value<span class="Delimiter">;</span> - <span class="Normal">bool</span> initialized<span class="Delimiter">;</span> + double value<span class="Delimiter">;</span> + bool initialized<span class="Delimiter">;</span> vector<type_ordinal> types<span class="Delimiter">;</span> reagent<span class="Delimiter">(</span>string s<span class="Delimiter">);</span> reagent<span class="Delimiter">();</span> - <span class="Normal">void</span> set_value<span class="Delimiter">(</span><span class="Normal">double</span> v<span class="Delimiter">)</span> <span class="Delimiter">{</span> value = v<span class="Delimiter">;</span> initialized = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - string to_string<span class="Delimiter">()</span> <span class="Normal">const</span><span class="Delimiter">;</span> + void set_value<span class="Delimiter">(</span>double v<span class="Delimiter">)</span> <span class="Delimiter">{</span> value = v<span class="Delimiter">;</span> initialized = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> + string to_string<span class="Delimiter">()</span> const<span class="Delimiter">;</span> <span class="Delimiter">};</span> <span class="Delimiter">:(before "struct reagent")</span> -<span class="Normal">struct</span> property <span class="Delimiter">{</span> +struct property <span class="Delimiter">{</span> vector<string> values<span class="Delimiter">;</span> <span class="Delimiter">};</span> <span class="Delimiter">:(before "End Globals")</span> <span class="Comment">// Locations refer to a common 'memory'. Each location can store a number.</span> -map<<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span><span class="Delimiter">,</span> <span class="Normal">double</span>> Memory<span class="Delimiter">;</span> +map<long long int<span class="Delimiter">,</span> double> Memory<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Setup")</span> Memory<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> @@ -114,13 +113,13 @@ Memory<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> <span class="Comment">// Unlike most computers today, mu stores types in a single big table, shared</span> <span class="Comment">// by all the mu programs on the computer. This is useful in providing a</span> <span class="Comment">// seamless experience to help understand arbitrary mu programs.</span> -<span class="Normal">typedef</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> type_ordinal<span class="Delimiter">;</span> +typedef long long int type_ordinal<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Globals")</span> map<string<span class="Delimiter">,</span> type_ordinal> Type_ordinal<span class="Delimiter">;</span> map<type_ordinal<span class="Delimiter">,</span> type_info> Type<span class="Delimiter">;</span> type_ordinal Next_type_ordinal = <span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> setup_types<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void setup_types<span class="Delimiter">()</span> <span class="Delimiter">{</span> Type<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> Type_ordinal<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> Type_ordinal[<span class="Constant">"literal"</span>] = <span class="Constant">0</span><span class="Delimiter">;</span> Next_type_ordinal = <span class="Constant">1</span><span class="Delimiter">;</span> @@ -154,23 +153,23 @@ setup_types<span class="Delimiter">();</span> <span class="Comment">// container, but if bank accounts may be either for individuals or groups,</span> <span class="Comment">// with different properties for each, that may require an exclusive container</span> <span class="Comment">// whose variants are individual-account and joint-account containers.</span> -<span class="Normal">enum</span> kind_of_type <span class="Delimiter">{</span> +enum kind_of_type <span class="Delimiter">{</span> primitive<span class="Delimiter">,</span> container<span class="Delimiter">,</span> exclusive_container <span class="Delimiter">};</span> -<span class="Normal">struct</span> type_info <span class="Delimiter">{</span> +struct type_info <span class="Delimiter">{</span> string name<span class="Delimiter">;</span> kind_of_type kind<span class="Delimiter">;</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> size<span class="Delimiter">;</span> <span class="Comment">// only if type is not primitive; primitives and addresses have size 1 (except arrays are dynamic)</span> + long long int size<span class="Delimiter">;</span> <span class="Comment">// only if type is not primitive; primitives and addresses have size 1 (except arrays are dynamic)</span> vector<vector<type_ordinal> > elements<span class="Delimiter">;</span> vector<string> element_names<span class="Delimiter">;</span> <span class="Comment">// End type_info Fields</span> type_info<span class="Delimiter">()</span> :kind<span class="Delimiter">(</span>primitive<span class="Delimiter">),</span> size<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{}</span> <span class="Delimiter">};</span> -<span class="Normal">enum</span> primitive_recipes <span class="Delimiter">{</span> +enum primitive_recipes <span class="Delimiter">{</span> IDLE = <span class="Constant">0</span><span class="Delimiter">,</span> COPY<span class="Delimiter">,</span> <span class="Comment">// End Primitive Recipe Declarations</span> @@ -181,7 +180,7 @@ setup_types<span class="Delimiter">();</span> <span class="Comment">//: to know how to do *something* out of the box. For the following</span> <span class="Comment">//: recipes there are only codes, no entries in the book, because mu just knows</span> <span class="Comment">//: what to do for them.</span> -<span class="Normal">void</span> setup_recipes<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void setup_recipes<span class="Delimiter">()</span> <span class="Delimiter">{</span> Recipe<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> Recipe_ordinal<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> Recipe_ordinal[<span class="Constant">"idle"</span>] = IDLE<span class="Delimiter">;</span> <span class="Comment">// Primitive Recipe Numbers</span> @@ -196,6 +195,7 @@ setup_types<span class="Delimiter">();</span> setup_recipes<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> +Recipe_ordinal[<span class="Constant">"main"</span>] = Next_recipe_ordinal++<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> @@ -210,7 +210,7 @@ Next_recipe_ordinal = <span class="Constant">1000</span><span class="Delimiter"> instruction::instruction<span class="Delimiter">()</span> :is_label<span class="Delimiter">(</span><span class="Constant">false</span><span class="Delimiter">),</span> operation<span class="Delimiter">(</span>IDLE<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// End instruction Constructor</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> instruction::clear<span class="Delimiter">()</span> <span class="Delimiter">{</span> is_label=<span class="Constant">false</span><span class="Delimiter">;</span> label<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> operation=IDLE<span class="Delimiter">;</span> ingredients<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> products<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> <span class="Delimiter">}</span> +void instruction::clear<span class="Delimiter">()</span> <span class="Delimiter">{</span> is_label=<span class="Constant">false</span><span class="Delimiter">;</span> label<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> operation=IDLE<span class="Delimiter">;</span> ingredients<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> products<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Comment">// Reagents have the form <name>:<type>:<type>:.../<property>/<property>/...</span> reagent::reagent<span class="Delimiter">(</span>string s<span class="Delimiter">)</span> :original_string<span class="Delimiter">(</span>s<span class="Delimiter">),</span> value<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">),</span> initialized<span class="Delimiter">(</span><span class="Constant">false</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -218,30 +218,32 @@ reagent::reagent<span class="Delimiter">(</span>string s<span class="Delimiter"> istringstream in<span class="Delimiter">(</span>s<span class="Delimiter">);</span> in >> std::noskipws<span class="Delimiter">;</span> <span class="Comment">// properties</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> istringstream row<span class="Delimiter">(</span>slurp_until<span class="Delimiter">(</span>in<span class="Delimiter">,</span> <span class="Constant">'/'</span><span class="Delimiter">));</span> row >> std::noskipws<span class="Delimiter">;</span> string name = slurp_until<span class="Delimiter">(</span>row<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">);</span> vector<string> values<span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>!row<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> + while <span class="Delimiter">(</span>!row<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> values<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>slurp_until<span class="Delimiter">(</span>row<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">));</span> properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> vector<string> ><span class="Delimiter">(</span>name<span class="Delimiter">,</span> values<span class="Delimiter">));</span> <span class="Delimiter">}</span> <span class="Comment">// structures for the first row of properties</span> name = properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>first<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <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>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> string type = properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">.</span>find<span class="Delimiter">(</span>type<span class="Delimiter">)</span> == Type_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">.</span>find<span class="Delimiter">(</span>type<span class="Delimiter">)</span> == Type_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">()</span> + <span class="Comment">// types can contain integers, like for array sizes</span> + && !is_integer<span class="Delimiter">(</span>type<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << type << " is " << Next_type_ordinal << '\n'; //? 1</span> Type_ordinal[type] = Next_type_ordinal++<span class="Delimiter">;</span> <span class="Delimiter">}</span> types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>Type_ordinal[type]<span class="Delimiter">);</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>name<span class="Delimiter">)</span> && types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>name<span class="Delimiter">)</span> && types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">"literal"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>name == <span class="Constant">"_"</span> && types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>name == <span class="Constant">"_"</span> && types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">"dummy"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> @@ -255,19 +257,19 @@ reagent::reagent<span class="Delimiter">()</span> :value<span class="Delimiter"> properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> vector<string> ><span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">,</span> vector<string><span class="Delimiter">()));</span> <span class="Delimiter">}</span> -string reagent::to_string<span class="Delimiter">()</span> <span class="Normal">const</span> <span class="Delimiter">{</span> +string reagent::to_string<span class="Delimiter">()</span> const <span class="Delimiter">{</span> ostringstream out<span class="Delimiter">;</span> out << <span class="Constant">"{name: </span><span class="cSpecial">\"</span><span class="Constant">"</span> << name << <span class="Constant">"</span><span class="cSpecial">\"</span><span class="Constant">"</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!properties<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!properties<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> out << <span class="Constant">", properties: ["</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>properties<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <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>properties<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> out << <span class="Constant">"</span><span class="cSpecial">\"</span><span class="Constant">"</span> << properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>first << <span class="Constant">"</span><span class="cSpecial">\"</span><span class="Constant">: "</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>j > <span class="Constant">0</span><span class="Delimiter">)</span> out << <span class="Constant">':'</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>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>j > <span class="Constant">0</span><span class="Delimiter">)</span> out << <span class="Constant">':'</span><span class="Delimiter">;</span> out << <span class="Constant">"</span><span class="cSpecial">\"</span><span class="Constant">"</span> << properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)</span> << <span class="Constant">"</span><span class="cSpecial">\"</span><span class="Constant">"</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>i < SIZE<span class="Delimiter">(</span>properties<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">)</span> out << <span class="Constant">", "</span><span class="Delimiter">;</span> - <span class="Normal">else</span> out << <span class="Constant">"]"</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>i < SIZE<span class="Delimiter">(</span>properties<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">)</span> out << <span class="Constant">", "</span><span class="Delimiter">;</span> + else out << <span class="Constant">"]"</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> out << <span class="Constant">"}"</span><span class="Delimiter">;</span> @@ -275,27 +277,27 @@ string reagent::to_string<span class="Delimiter">()</span> <span class="Normal"> <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span> <span class="Delimiter">}</span> -string instruction::to_string<span class="Delimiter">()</span> <span class="Normal">const</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_label<span class="Delimiter">)</span> <span class="Identifier">return</span> label<span class="Delimiter">;</span> +string instruction::to_string<span class="Delimiter">()</span> const <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>is_label<span class="Delimiter">)</span> <span class="Identifier">return</span> label<span class="Delimiter">;</span> ostringstream out<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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="Normal">if</span> <span class="Delimiter">(</span>i > <span class="Constant">0</span><span class="Delimiter">)</span> out << <span class="Constant">", "</span><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>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>i > <span class="Constant">0</span><span class="Delimiter">)</span> out << <span class="Constant">", "</span><span class="Delimiter">;</span> out << products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string<span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> out << <span class="Constant">" <- "</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> out << <span class="Constant">" <- "</span><span class="Delimiter">;</span> out << name << <span class="Constant">' '</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> - <span class="Normal">if</span> <span class="Delimiter">(</span>i > <span class="Constant">0</span><span class="Delimiter">)</span> out << <span class="Constant">", "</span><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>i > <span class="Constant">0</span><span class="Delimiter">)</span> out << <span class="Constant">", "</span><span class="Delimiter">;</span> out << ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span> <span class="Delimiter">}</span> -string slurp_until<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> <span class="Normal">char</span> delim<span class="Delimiter">)</span> <span class="Delimiter">{</span> +string slurp_until<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> char delim<span class="Delimiter">)</span> <span class="Delimiter">{</span> ostringstream out<span class="Delimiter">;</span> - <span class="Normal">char</span> c<span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>in >> c<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>c == delim<span class="Delimiter">)</span> <span class="Delimiter">{</span> + char c<span class="Delimiter">;</span> + while <span class="Delimiter">(</span>in >> c<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>c == delim<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// drop the delim</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -304,29 +306,29 @@ string slurp_until<span class="Delimiter">(</span>istream& in<span class="De <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span> <span class="Delimiter">}</span> -<span class="Normal">bool</span> has_property<span class="Delimiter">(</span>reagent x<span class="Delimiter">,</span> string name<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Comment">/*</span><span class="Comment">skip name:type</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>first == name<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> +bool has_property<span class="Delimiter">(</span>reagent x<span class="Delimiter">,</span> string name<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int i = <span class="Comment">/*</span><span class="Comment">skip name:type</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>first == name<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -vector<string> property<span class="Delimiter">(</span><span class="Normal">const</span> reagent& r<span class="Delimiter">,</span> <span class="Normal">const</span> string& name<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> p = <span class="Comment">/*</span><span class="Comment">skip name:type</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> p != SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>properties<span class="Delimiter">);</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>p<span class="Delimiter">).</span>first == name<span class="Delimiter">)</span> +vector<string> property<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">,</span> const string& name<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int p = <span class="Comment">/*</span><span class="Comment">skip name:type</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> p != SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>properties<span class="Delimiter">);</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>p<span class="Delimiter">).</span>first == name<span class="Delimiter">)</span> <span class="Identifier">return</span> r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>p<span class="Delimiter">).</span>second<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Identifier">return</span> vector<string><span class="Delimiter">();</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> dump_memory<span class="Delimiter">()</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>map<<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span><span class="Delimiter">,</span> <span class="Normal">double</span>>::iterator p = Memory<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Memory<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void dump_memory<span class="Delimiter">()</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>map<long long int<span class="Delimiter">,</span> double>::iterator p = Memory<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Memory<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> cout << p<span class="Delimiter">-></span>first << <span class="Constant">": "</span> << p<span class="Delimiter">-></span>second << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Includes")</span> <span class="PreProc">#include</span><span class="Constant"><utility></span> -<span class="Normal">using</span> std::pair<span class="Delimiter">;</span> +using std::pair<span class="Delimiter">;</span> </pre> </body> </html> diff --git a/html/011load.cc.html b/html/011load.cc.html index 07977936..f6d9ea85 100644 --- a/html/011load.cc.html +++ b/html/011load.cc.html @@ -13,15 +13,14 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.Constant { color: #00a0a0; } -.cSpecial { color: #008000; } .CommentedCode { color: #6c6c6c; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.cSpecial { color: #008000; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } +.traceContains { color: #008000; } --> </style> @@ -54,34 +53,34 @@ vector<recipe_ordinal> load<span class="Delimiter">(</span>string form<spa vector<recipe_ordinal> load<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> in >> std::noskipws<span class="Delimiter">;</span> vector<recipe_ordinal> result<span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << "===\n"; //? 1</span> skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span> string command = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Comment">// Command Handlers</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>command == <span class="Constant">"recipe"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>command == <span class="Constant">"recipe"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> string recipe_name = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span> -<span class="CommentedCode">//? cerr << "recipe: " << recipe_name << '\n'; //? 1</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>recipe_name<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> +<span class="CommentedCode">//? cerr << "recipe: " << recipe_name << '\n'; //? 2</span> + if <span class="Delimiter">(</span>recipe_name<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> raise << <span class="Constant">"empty recipe name</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">.</span>find<span class="Delimiter">(</span>recipe_name<span class="Delimiter">)</span> == Recipe_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">.</span>find<span class="Delimiter">(</span>recipe_name<span class="Delimiter">)</span> == Recipe_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> Recipe_ordinal[recipe_name] = Next_recipe_ordinal++<span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>warn_on_redefine<span class="Delimiter">(</span>recipe_name<span class="Delimiter">)</span> + if <span class="Delimiter">(</span>warn_on_redefine<span class="Delimiter">(</span>recipe_name<span class="Delimiter">)</span> && Recipe<span class="Delimiter">.</span>find<span class="Delimiter">(</span>Recipe_ordinal[recipe_name]<span class="Delimiter">)</span> != Recipe<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> raise << <span class="Constant">"redefining recipe "</span> << Recipe[Recipe_ordinal[recipe_name]]<span class="Delimiter">.</span>name << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Comment">// todo: save user-defined recipes to mu's memory</span> Recipe[Recipe_ordinal[recipe_name]] = slurp_recipe<span class="Delimiter">(</span>in<span class="Delimiter">);</span> -<span class="CommentedCode">//? cerr << Recipe_ordinal[recipe_name] << ": " << recipe_name << '\n'; //? 1</span> +<span class="CommentedCode">//? cerr << Recipe_ordinal[recipe_name] << ": " << recipe_name << '\n'; //? 2</span> Recipe[Recipe_ordinal[recipe_name]]<span class="Delimiter">.</span>name = recipe_name<span class="Delimiter">;</span> <span class="Comment">// track added recipes because we may need to undo them in tests; see below</span> recently_added_recipes<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>Recipe_ordinal[recipe_name]<span class="Delimiter">);</span> result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>Recipe_ordinal[recipe_name]<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Comment">// End Command Handlers</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> + else <span class="Delimiter">{</span> raise << <span class="Constant">"unknown top-level command: "</span> << command << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> @@ -92,91 +91,111 @@ vector<recipe_ordinal> load<span class="Delimiter">(</span>istream& in recipe slurp_recipe<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> recipe result<span class="Delimiter">;</span> skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">()</span> != <span class="Constant">'['</span><span class="Delimiter">)</span> + if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">()</span> != <span class="Constant">'['</span><span class="Delimiter">)</span> raise << <span class="Constant">"recipe body must begin with '['</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span> instruction curr<span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>next_instruction<span class="Delimiter">(</span>in<span class="Delimiter">,</span> &curr<span class="Delimiter">))</span> <span class="Delimiter">{</span> + while <span class="Delimiter">(</span>next_instruction<span class="Delimiter">(</span>in<span class="Delimiter">,</span> &curr<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Comment">// End Rewrite Instruction(curr)</span> -<span class="CommentedCode">//? cerr << "instruction: " << curr.to_string() << '\n'; //? 2</span> +<span class="CommentedCode">//? cerr << "instruction: " << curr.to_string() << '\n'; //? 3</span> result<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>curr<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">bool</span> next_instruction<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> instruction* curr<span class="Delimiter">)</span> <span class="Delimiter">{</span> +bool next_instruction<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> instruction* curr<span class="Delimiter">)</span> <span class="Delimiter">{</span> in >> std::noskipws<span class="Delimiter">;</span> curr<span class="Delimiter">-></span>clear<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + raise << <span class="Constant">"0: unbalanced '[' for recipe</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> <span class="CommentedCode">//? show_rest_of_stream(in); //? 1</span> - skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span> + if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + raise << <span class="Constant">"1: unbalanced '[' for recipe</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> <span class="CommentedCode">//? show_rest_of_stream(in); //? 1</span> - skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span> + if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + raise << <span class="Constant">"2: unbalanced '[' for recipe</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> vector<string> words<span class="Delimiter">;</span> <span class="CommentedCode">//? show_rest_of_stream(in); //? 1</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + while <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span> && !in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span> + if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + raise << <span class="Constant">"3: unbalanced '[' for recipe</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> <span class="CommentedCode">//? show_rest_of_stream(in); //? 1</span> - string word = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> -<span class="CommentedCode">//? cerr << "AAA: " << word << '\n'; //? 1</span> + string word = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span> words<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>word<span class="Delimiter">);</span> - skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Delimiter">}</span> - skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - + skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="CommentedCode">//? if (SIZE(words) == 1) cout << words.at(0) << ' ' << SIZE(words.at(0)) << '\n'; //? 1</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>words<span class="Delimiter">)</span> == <span class="Constant">1</span> && words<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">"]"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> -<span class="CommentedCode">//? cout << "AAA\n"; //? 1</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>words<span class="Delimiter">)</span> == <span class="Constant">1</span> && words<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">"]"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Comment">// end of recipe</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>words<span class="Delimiter">)</span> == <span class="Constant">1</span> && !isalnum<span class="Delimiter">(</span>words<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> && words<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="Constant">'$'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>words<span class="Delimiter">)</span> == <span class="Constant">1</span> && !isalnum<span class="Delimiter">(</span>words<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> && words<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="Constant">'$'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> curr<span class="Delimiter">-></span>is_label = <span class="Constant">true</span><span class="Delimiter">;</span> curr<span class="Delimiter">-></span>label = words<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> trace<span class="Delimiter">(</span><span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">"label: "</span> << curr<span class="Delimiter">-></span>label << end<span class="Delimiter">();</span> - <span class="Identifier">return</span> !in<span class="Delimiter">.</span>eof<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + raise << <span class="Constant">"7: unbalanced '[' for recipe</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> vector<string>::iterator p = words<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>find<span class="Delimiter">(</span>words<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> words<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> <span class="Constant">"<-"</span><span class="Delimiter">)</span> != words<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(;</span> *p != <span class="Constant">"<-"</span><span class="Delimiter">;</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>*p == <span class="Constant">","</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>find<span class="Delimiter">(</span>words<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> words<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> <span class="Constant">"<-"</span><span class="Delimiter">)</span> != words<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(;</span> *p != <span class="Constant">"<-"</span><span class="Delimiter">;</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>*p == <span class="Constant">","</span><span class="Delimiter">)</span> <span class="Identifier">continue</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>*p<span class="Delimiter">));</span> <span class="CommentedCode">//? cerr << "product: " << curr->products.back().to_string() << '\n'; //? 1</span> <span class="Delimiter">}</span> ++p<span class="Delimiter">;</span> <span class="Comment">// skip <-</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>p == words<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>p == words<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> raise << <span class="Constant">"instruction prematurely ended with '<-'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">()</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> curr<span class="Delimiter">-></span>name = *p<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">.</span>find<span class="Delimiter">(</span>*p<span class="Delimiter">)</span> == Recipe_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">.</span>find<span class="Delimiter">(</span>*p<span class="Delimiter">)</span> == Recipe_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> Recipe_ordinal[*p] = Next_recipe_ordinal++<span class="Delimiter">;</span> <span class="CommentedCode">//? cout << "AAA: " << *p << " is now " << Recipe_ordinal[*p] << '\n'; //? 1</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Recipe_ordinal[*p] == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Recipe_ordinal[*p] == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << <span class="Constant">"Recipe "</span> << *p << <span class="Constant">" has number 0, which is reserved for IDLE.</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">()</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> curr<span class="Delimiter">-></span>operation = Recipe_ordinal[*p]<span class="Delimiter">;</span> ++p<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(;</span> p != words<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>*p == <span class="Constant">","</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + for <span class="Delimiter">(;</span> p != words<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>*p == <span class="Constant">","</span><span class="Delimiter">)</span> <span class="Identifier">continue</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>*p<span class="Delimiter">));</span> <span class="CommentedCode">//? cerr << "ingredient: " << curr->ingredients.back().to_string() << '\n'; //? 1</span> <span class="Delimiter">}</span> trace<span class="Delimiter">(</span><span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">"instruction: "</span> << curr<span class="Delimiter">-></span>name << end<span class="Delimiter">();</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>vector<reagent>::iterator p = curr<span class="Delimiter">-></span>ingredients<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != curr<span class="Delimiter">-></span>ingredients<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>vector<reagent>::iterator p = curr<span class="Delimiter">-></span>ingredients<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != curr<span class="Delimiter">-></span>ingredients<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">" ingredient: "</span> << p<span class="Delimiter">-></span>to_string<span class="Delimiter">()</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>vector<reagent>::iterator p = curr<span class="Delimiter">-></span>products<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != curr<span class="Delimiter">-></span>products<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>vector<reagent>::iterator p = curr<span class="Delimiter">-></span>products<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != curr<span class="Delimiter">-></span>products<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">" product: "</span> << p<span class="Delimiter">-></span>to_string<span class="Delimiter">()</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> - <span class="Identifier">return</span> !in<span class="Delimiter">.</span>eof<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + raise << <span class="Constant">"9: unbalanced '[' for recipe</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> string next_word<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -190,17 +209,17 @@ string next_word<span class="Delimiter">(</span>istream& in<span class="Deli <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> slurp_word<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> ostream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void slurp_word<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> ostream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cout << "AAA slurp_word\n"; //? 1</span> - <span class="Normal">char</span> c<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">','</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + char c<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">','</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> in >> c<span class="Delimiter">;</span> out << c<span class="Delimiter">;</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>in >> c<span class="Delimiter">)</span> <span class="Delimiter">{</span> + while <span class="Delimiter">(</span>in >> c<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cout << c << '\n'; //? 1</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>isspace<span class="Delimiter">(</span>c<span class="Delimiter">)</span> || c == <span class="Constant">','</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>isspace<span class="Delimiter">(</span>c<span class="Delimiter">)</span> || c == <span class="Constant">','</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> in<span class="Delimiter">.</span>putback<span class="Delimiter">(</span>c<span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -208,30 +227,30 @@ string next_word<span class="Delimiter">(</span>istream& in<span class="Deli <span class="Delimiter">}</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> skip_whitespace<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>isspace<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">())</span> && in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +void skip_whitespace<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> + while <span class="Delimiter">(</span>isspace<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">())</span> && in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> in<span class="Delimiter">.</span>get<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> skip_whitespace_and_comments<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">while</span> <span class="Delimiter">(</span><span class="Constant">true</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>isspace<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()))</span> in<span class="Delimiter">.</span>get<span class="Delimiter">();</span> - <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'#'</span><span class="Delimiter">)</span> skip_comment<span class="Delimiter">(</span>in<span class="Delimiter">);</span> - <span class="Normal">else</span> <span class="Identifier">break</span><span class="Delimiter">;</span> +void skip_whitespace_and_comments<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> + while <span class="Delimiter">(</span><span class="Constant">true</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>isspace<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()))</span> in<span class="Delimiter">.</span>get<span class="Delimiter">();</span> + else if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'#'</span><span class="Delimiter">)</span> skip_comment<span class="Delimiter">(</span>in<span class="Delimiter">);</span> + else <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> skip_comment<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'#'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +void skip_comment<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'#'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> in<span class="Delimiter">.</span>get<span class="Delimiter">();</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> in<span class="Delimiter">.</span>get<span class="Delimiter">();</span> + while <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> in<span class="Delimiter">.</span>get<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> skip_comma<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void skip_comma<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">','</span><span class="Delimiter">)</span> in<span class="Delimiter">.</span>get<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">','</span><span class="Delimiter">)</span> in<span class="Delimiter">.</span>get<span class="Delimiter">();</span> skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Delimiter">}</span> @@ -239,24 +258,24 @@ string next_word<span class="Delimiter">(</span>istream& in<span class="Deli <span class="Comment">//: step on their own toes. But there'll be many occasions later where</span> <span class="Comment">//: we'll want to disable the warnings.</span> <span class="Delimiter">:(before "End Globals")</span> -<span class="Normal">bool</span> Disable_redefine_warnings = <span class="Constant">false</span><span class="Delimiter">;</span> +bool Disable_redefine_warnings = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End Setup")</span> Disable_redefine_warnings = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">:(code)</span> -<span class="Normal">bool</span> warn_on_redefine<span class="Delimiter">(</span><span class="Normal">const</span> string& recipe_name<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Disable_redefine_warnings<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> +bool warn_on_redefine<span class="Delimiter">(</span>const string& recipe_name<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Disable_redefine_warnings<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</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="Comment">// for debugging</span> <span class="Delimiter">:(before "End Globals")</span> -<span class="Normal">bool</span> Show_rest_of_stream = <span class="Constant">false</span><span class="Delimiter">;</span> +bool Show_rest_of_stream = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> show_rest_of_stream<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Show_rest_of_stream<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> +void show_rest_of_stream<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!Show_rest_of_stream<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> cerr << <span class="Constant">'^'</span><span class="Delimiter">;</span> - <span class="Normal">char</span> c<span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>in >> c<span class="Delimiter">)</span> <span class="Delimiter">{</span> + char c<span class="Delimiter">;</span> + while <span class="Delimiter">(</span>in >> c<span class="Delimiter">)</span> <span class="Delimiter">{</span> cerr << c<span class="Delimiter">;</span> <span class="Delimiter">}</span> cerr << <span class="Constant">"$</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span> @@ -266,10 +285,12 @@ Disable_redefine_warnings = <span class="Constant">false</span><span class="Deli <span class="Comment">//: Have tests clean up any recipes they added.</span> <span class="Delimiter">:(before "End Globals")</span> vector<recipe_ordinal> recently_added_recipes<span class="Delimiter">;</span> +long long int Reserved_for_tests = <span class="Constant">1000</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End Setup")</span> -<span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>recently_added_recipes<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <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>recently_added_recipes<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cout << "AAA clearing " << Recipe[recently_added_recipes.at(i)].name << '\n'; //? 2</span> - Recipe_ordinal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>Recipe[recently_added_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span>]<span class="Delimiter">.</span>name<span class="Delimiter">);</span> + if <span class="Delimiter">(</span>recently_added_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> >= Reserved_for_tests<span class="Delimiter">)</span> <span class="Comment">// don't renumber existing recipes, like 'interactive'</span> + Recipe_ordinal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>Recipe[recently_added_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span>]<span class="Delimiter">.</span>name<span class="Delimiter">);</span> Recipe<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>recently_added_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> <span class="Delimiter">}</span> <span class="Comment">// Clear Other State For recently_added_recipes</span> @@ -295,7 +316,7 @@ recipe main [ <span class="traceContains">+parse: ingredient: {name: "23", properties: ["23": "literal"]}</span> <span class="traceContains">+parse: product: {name: "1", properties: ["1": "number"]}</span> -<span class="Delimiter">:(scenario parse_comment_amongst_instruction2)</span> +<span class="Delimiter">:(scenario parse_comment_amongst_instruction_2)</span> recipe main [ <span class="Comment"># comment</span> <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">23</span> @@ -305,7 +326,7 @@ recipe main [ <span class="traceContains">+parse: ingredient: {name: "23", properties: ["23": "literal"]}</span> <span class="traceContains">+parse: product: {name: "1", properties: ["1": "number"]}</span> -<span class="Delimiter">:(scenario parse_comment_amongst_instruction3)</span> +<span class="Delimiter">:(scenario parse_comment_amongst_instruction_3)</span> recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">23</span> <span class="Comment"># comment</span> diff --git a/html/012transform.cc.html b/html/012transform.cc.html index 21163e04..acd35f6c 100644 --- a/html/012transform.cc.html +++ b/html/012transform.cc.html @@ -13,12 +13,11 @@ 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; } +.Identifier { color: #804000; } .Constant { color: #00a0a0; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .CommentedCode { color: #6c6c6c; } -.Identifier { color: #804000; } --> </style> @@ -36,23 +35,23 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment">//: deconstructed alternative to conventional compilers.</span> <span class="Delimiter">:(before "End recipe Fields")</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> transformed_until<span class="Delimiter">;</span> +long long int transformed_until<span class="Delimiter">;</span> recipe<span class="Delimiter">()</span> :transformed_until<span class="Delimiter">(</span>-<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{}</span> <span class="Delimiter">:(before "End Types")</span> -<span class="Normal">typedef</span> <span class="Normal">void</span> <span class="Delimiter">(</span>*transform_fn<span class="Delimiter">)(</span>recipe_ordinal<span class="Delimiter">);</span> +typedef void <span class="Delimiter">(</span>*transform_fn<span class="Delimiter">)(</span>recipe_ordinal<span class="Delimiter">);</span> <span class="Delimiter">:(before "End Globals")</span> vector<transform_fn> Transform<span class="Delimiter">;</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> transform_all<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void transform_all<span class="Delimiter">()</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << "AAA transform_all\n"; //? 2</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> t = <span class="Constant">0</span><span class="Delimiter">;</span> t < SIZE<span class="Delimiter">(</span>Transform<span class="Delimiter">);</span> ++t<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>map<recipe_ordinal<span class="Delimiter">,</span> recipe>::iterator p = Recipe<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Recipe<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int t = <span class="Constant">0</span><span class="Delimiter">;</span> t < SIZE<span class="Delimiter">(</span>Transform<span class="Delimiter">);</span> ++t<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>map<recipe_ordinal<span class="Delimiter">,</span> recipe>::iterator p = Recipe<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Recipe<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> recipe& r = p<span class="Delimiter">-></span>second<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">.</span>transformed_until != t-<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>transformed_until != t-<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">(</span>*Transform<span class="Delimiter">.</span>at<span class="Delimiter">(</span>t<span class="Delimiter">))(</span><span class="Comment">/*</span><span class="Comment">recipe_ordinal</span><span class="Comment">*/</span>p<span class="Delimiter">-></span>first<span class="Delimiter">);</span> r<span class="Delimiter">.</span>transformed_until = t<span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -60,27 +59,27 @@ vector<transform_fn> Transform<span class="Delimiter">;</span> parse_int_reagents<span class="Delimiter">();</span> <span class="Comment">// do this after all other transforms have run</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> parse_int_reagents<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void parse_int_reagents<span class="Delimiter">()</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cout << "parse_int_reagents\n"; //? 1</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>map<recipe_ordinal<span class="Delimiter">,</span> recipe>::iterator p = Recipe<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Recipe<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>map<recipe_ordinal<span class="Delimiter">,</span> recipe>::iterator p = Recipe<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Recipe<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> recipe& r = p<span class="Delimiter">-></span>second<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> index = <span class="Constant">0</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + for <span class="Delimiter">(</span>long long int index = <span class="Constant">0</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> instruction& inst = r<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <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>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> populate_value<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> <span class="Delimiter">}</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <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>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> populate_value<span class="Delimiter">(</span>inst<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="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> populate_value<span class="Delimiter">(</span>reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">.</span>initialized<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> +void populate_value<span class="Delimiter">(</span>reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>initialized<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// End Reagent-parsing Exceptions</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!is_integer<span class="Delimiter">(</span>r<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!is_integer<span class="Delimiter">(</span>r<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> r<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>to_integer<span class="Delimiter">(</span>r<span class="Delimiter">.</span>name<span class="Delimiter">));</span> <span class="Delimiter">}</span> </pre> diff --git a/html/013literal_string.cc.html b/html/013literal_string.cc.html index 07837f40..735e67e0 100644 --- a/html/013literal_string.cc.html +++ b/html/013literal_string.cc.html @@ -13,15 +13,14 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.Constant { color: #00a0a0; } +.Identifier { color: #804000; } .cSpecial { color: #008000; } -.CommentedCode { color: #6c6c6c; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } -.Identifier { color: #804000; } +.CommentedCode { color: #6c6c6c; } +.Constant { color: #00a0a0; } +.traceContains { color: #008000; } --> </style> @@ -57,7 +56,7 @@ recipe main [ Type_ordinal[<span class="Constant">"literal-string"</span>] = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">:(after "string next_word(istream& in)")</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> string result = slurp_quoted<span class="Delimiter">(</span>in<span class="Delimiter">);</span> skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span> skip_comment<span class="Delimiter">(</span>in<span class="Delimiter">);</span> @@ -68,26 +67,26 @@ Type_ordinal[<span class="Constant">"literal-string"</span>] = <span c <span class="Delimiter">:(code)</span> string slurp_quoted<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> ostringstream out<span class="Delimiter">;</span> - assert<span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">());</span> assert<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'['</span><span class="Delimiter">);</span> out << <span class="Normal">static_cast</span><<span class="Normal">char</span>><span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">());</span> <span class="Comment">// slurp the '['</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>code_string<span class="Delimiter">(</span>in<span class="Delimiter">,</span> out<span class="Delimiter">))</span> + assert<span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">());</span> assert<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'['</span><span class="Delimiter">);</span> out << static_cast<char><span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">());</span> <span class="Comment">// slurp the '['</span> + if <span class="Delimiter">(</span>code_string<span class="Delimiter">(</span>in<span class="Delimiter">,</span> out<span class="Delimiter">))</span> slurp_quoted_comment_aware<span class="Delimiter">(</span>in<span class="Delimiter">,</span> out<span class="Delimiter">);</span> - <span class="Normal">else</span> + else slurp_quoted_comment_oblivious<span class="Delimiter">(</span>in<span class="Delimiter">,</span> out<span class="Delimiter">);</span> <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Comment">// A string is a code string if it contains a newline before any non-whitespace</span> <span class="Comment">// todo: support comments before the newline. But that gets messy.</span> -<span class="Normal">bool</span> code_string<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> ostringstream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> - <span class="Normal">char</span> c = in<span class="Delimiter">.</span>get<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!isspace<span class="Delimiter">(</span>c<span class="Delimiter">))</span> <span class="Delimiter">{</span> +bool code_string<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> ostringstream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span> + while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + char c = in<span class="Delimiter">.</span>get<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>!isspace<span class="Delimiter">(</span>c<span class="Delimiter">))</span> <span class="Delimiter">{</span> in<span class="Delimiter">.</span>putback<span class="Delimiter">(</span>c<span class="Delimiter">);</span> <span class="CommentedCode">//? cerr << "code_string: " << out.str() << '\n'; //? 1</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> out << c<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>c == <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>c == <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << "code_string: " << out.str() << '\n'; //? 1</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -97,59 +96,59 @@ string slurp_quoted<span class="Delimiter">(</span>istream& in<span class="D <span class="Comment">// Read a regular string. Regular strings can only contain other regular</span> <span class="Comment">// strings.</span> -<span class="Normal">void</span> slurp_quoted_comment_oblivious<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> ostringstream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void slurp_quoted_comment_oblivious<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> ostringstream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << "comment oblivious\n"; //? 1</span> - <span class="Normal">int</span> brace_depth = <span class="Constant">1</span><span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> - <span class="Normal">char</span> c = in<span class="Delimiter">.</span>get<span class="Delimiter">();</span> + int brace_depth = <span class="Constant">1</span><span class="Delimiter">;</span> + while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + char c = in<span class="Delimiter">.</span>get<span class="Delimiter">();</span> <span class="CommentedCode">//? cerr << '%' << (int)c << ' ' << brace_depth << ": " << out.str() << "%$\n"; //? 1</span> <span class="CommentedCode">//? cout << (int)c << ": " << brace_depth << '\n'; //? 2</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>c == <span class="cSpecial">'\\'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - out << <span class="Normal">static_cast</span><<span class="Normal">char</span>><span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">());</span> + if <span class="Delimiter">(</span>c == <span class="cSpecial">'\\'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + out << static_cast<char><span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">());</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> out << c<span class="Delimiter">;</span> <span class="CommentedCode">//? cout << out.str() << "$\n"; //? 1</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>c == <span class="Constant">'['</span><span class="Delimiter">)</span> ++brace_depth<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>c == <span class="Constant">']'</span><span class="Delimiter">)</span> --brace_depth<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>brace_depth == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>c == <span class="Constant">'['</span><span class="Delimiter">)</span> ++brace_depth<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>c == <span class="Constant">']'</span><span class="Delimiter">)</span> --brace_depth<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>brace_depth == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">()</span> && brace_depth > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">()</span> && brace_depth > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << <span class="Constant">"unbalanced '['</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> out<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Comment">// Read a code string. Code strings can contain either code or regular strings.</span> -<span class="Normal">void</span> slurp_quoted_comment_aware<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> ostringstream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void slurp_quoted_comment_aware<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> ostringstream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << "comment aware\n"; //? 1</span> - <span class="Normal">char</span> c<span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>in >> c<span class="Delimiter">)</span> <span class="Delimiter">{</span> + char c<span class="Delimiter">;</span> + while <span class="Delimiter">(</span>in >> c<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << '^' << (int)c << ": " << out.str() << "$\n"; //? 1</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>c == <span class="cSpecial">'\\'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - out << <span class="Normal">static_cast</span><<span class="Normal">char</span>><span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">());</span> + if <span class="Delimiter">(</span>c == <span class="cSpecial">'\\'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + out << static_cast<char><span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">());</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>c == <span class="Constant">'#'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>c == <span class="Constant">'#'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> out << c<span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">()</span> && in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> out << <span class="Normal">static_cast</span><<span class="Normal">char</span>><span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">());</span> + while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">()</span> && in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> out << static_cast<char><span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">());</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>c == <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>c == <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> in<span class="Delimiter">.</span>putback<span class="Delimiter">(</span>c<span class="Delimiter">);</span> <span class="Comment">// recurse</span> out << slurp_quoted<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> out << c<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>c == <span class="Constant">']'</span><span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>c == <span class="Constant">']'</span><span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> raise << <span class="Constant">"unbalanced '['</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> out<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">:(after "Parsing reagent(string s)")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>s<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +if <span class="Delimiter">(</span>s<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>*s<span class="Delimiter">.</span>rbegin<span class="Delimiter">()</span> == <span class="Constant">']'</span><span class="Delimiter">);</span> <span class="Comment">// delete [] delimiters</span> s<span class="Delimiter">.</span>erase<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> @@ -167,24 +166,24 @@ string slurp_quoted<span class="Delimiter">(</span>istream& in<span class="D <span class="Comment">//: b) Escape newlines in the string to make it more friendly to trace().</span> <span class="Delimiter">:(after "string reagent::to_string()")</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal_string<span class="Delimiter">(</span>*<span class="Normal">this</span><span class="Delimiter">))</span> + if <span class="Delimiter">(</span>is_literal_string<span class="Delimiter">(</span>*this<span class="Delimiter">))</span> <span class="Identifier">return</span> emit_literal_string<span class="Delimiter">(</span>name<span class="Delimiter">);</span> <span class="Delimiter">:(code)</span> -<span class="Normal">bool</span> is_literal_string<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> +bool is_literal_string<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> !x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">"literal-string"</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> string emit_literal_string<span class="Delimiter">(</span>string name<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">size_t</span> pos = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>pos != string::npos<span class="Delimiter">)</span> + size_t pos = <span class="Constant">0</span><span class="Delimiter">;</span> + while <span class="Delimiter">(</span>pos != string::npos<span class="Delimiter">)</span> pos = replace<span class="Delimiter">(</span>name<span class="Delimiter">,</span> <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">,</span> <span class="Constant">"</span><span class="cSpecial">\\</span><span class="Constant">n"</span><span class="Delimiter">,</span> pos<span class="Delimiter">);</span> <span class="Identifier">return</span> <span class="Constant">"{name: </span><span class="cSpecial">\"</span><span class="Constant">"</span>+name+<span class="Constant">"</span><span class="cSpecial">\"</span><span class="Constant">, properties: [_: </span><span class="cSpecial">\"</span><span class="Constant">literal-string</span><span class="cSpecial">\"</span><span class="Constant">]}"</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">size_t</span> replace<span class="Delimiter">(</span>string& str<span class="Delimiter">,</span> <span class="Normal">const</span> string& from<span class="Delimiter">,</span> <span class="Normal">const</span> string& to<span class="Delimiter">,</span> <span class="Normal">size_t</span> n<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">size_t</span> result = str<span class="Delimiter">.</span>find<span class="Delimiter">(</span>from<span class="Delimiter">,</span> n<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>result != string::npos<span class="Delimiter">)</span> +size_t replace<span class="Delimiter">(</span>string& str<span class="Delimiter">,</span> const string& from<span class="Delimiter">,</span> const string& to<span class="Delimiter">,</span> size_t n<span class="Delimiter">)</span> <span class="Delimiter">{</span> + size_t result = str<span class="Delimiter">.</span>find<span class="Delimiter">(</span>from<span class="Delimiter">,</span> n<span class="Delimiter">);</span> + if <span class="Delimiter">(</span>result != string::npos<span class="Delimiter">)</span> str<span class="Delimiter">.</span>replace<span class="Delimiter">(</span>result<span class="Delimiter">,</span> from<span class="Delimiter">.</span>length<span class="Delimiter">(),</span> to<span class="Delimiter">);</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> diff --git a/html/014literal_noninteger.cc.html b/html/014literal_noninteger.cc.html index 8ea14042..eb054c75 100644 --- a/html/014literal_noninteger.cc.html +++ b/html/014literal_noninteger.cc.html @@ -13,14 +13,13 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } +.traceContains { color: #008000; } --> </style> @@ -42,7 +41,7 @@ recipe main [ <span class="traceContains">+parse: ingredient: {name: "3.14159", properties: ["3.14159": "literal-number"]}</span> <span class="Delimiter">:(after "Parsing reagent(string s)")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>is_noninteger<span class="Delimiter">(</span>s<span class="Delimiter">))</span> <span class="Delimiter">{</span> +if <span class="Delimiter">(</span>is_noninteger<span class="Delimiter">(</span>s<span class="Delimiter">))</span> <span class="Delimiter">{</span> name = s<span class="Delimiter">;</span> types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> vector<string> ><span class="Delimiter">(</span>name<span class="Delimiter">,</span> vector<string><span class="Delimiter">()));</span> @@ -52,15 +51,15 @@ recipe main [ <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -<span class="Normal">bool</span> is_noninteger<span class="Delimiter">(</span><span class="Normal">const</span> string& s<span class="Delimiter">)</span> <span class="Delimiter">{</span> +bool is_noninteger<span class="Delimiter">(</span>const string& s<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> s<span class="Delimiter">.</span>find_first_not_of<span class="Delimiter">(</span><span class="Constant">"0123456789-."</span><span class="Delimiter">)</span> == string::npos && s<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">'.'</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">double</span> to_double<span class="Delimiter">(</span>string n<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">char</span>* end = <span class="Constant">NULL</span><span class="Delimiter">;</span> +double to_double<span class="Delimiter">(</span>string n<span class="Delimiter">)</span> <span class="Delimiter">{</span> + char* end = <span class="Constant">NULL</span><span class="Delimiter">;</span> <span class="Comment">// safe because string.c_str() is guaranteed to be null-terminated</span> - <span class="Normal">double</span> result = strtod<span class="Delimiter">(</span>n<span class="Delimiter">.</span>c_str<span class="Delimiter">(),</span> &end<span class="Delimiter">);</span> + double result = strtod<span class="Delimiter">(</span>n<span class="Delimiter">.</span>c_str<span class="Delimiter">(),</span> &end<span class="Delimiter">);</span> assert<span class="Delimiter">(</span>*end == <span class="cSpecial">'\0'</span><span class="Delimiter">);</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> diff --git a/html/020run.cc.html b/html/020run.cc.html index 4a59bcf6..a6e9548f 100644 --- a/html/020run.cc.html +++ b/html/020run.cc.html @@ -13,17 +13,16 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } .SalientComment { color: #00ffff; } -.Constant { color: #00a0a0; } -.cSpecial { color: #008000; } +.Identifier { color: #804000; } .traceAbsent { color: #c00000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.cSpecial { color: #008000; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } -.Identifier { color: #804000; } .CommentedCode { color: #6c6c6c; } +.Constant { color: #00a0a0; } +.traceContains { color: #008000; } --> </style> @@ -72,113 +71,157 @@ recipe main [ <span class="Delimiter">:(before "End Types")</span> <span class="Comment">// Book-keeping while running a recipe.</span> <span class="Comment">//: Later layers will change this.</span> -<span class="Normal">struct</span> routine <span class="Delimiter">{</span> +struct routine <span class="Delimiter">{</span> recipe_ordinal running_recipe<span class="Delimiter">;</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> running_step_index<span class="Delimiter">;</span> + long long int running_step_index<span class="Delimiter">;</span> routine<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> :running_recipe<span class="Delimiter">(</span>r<span class="Delimiter">),</span> running_step_index<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{}</span> - <span class="Normal">bool</span> completed<span class="Delimiter">()</span> <span class="Normal">const</span><span class="Delimiter">;</span> + bool completed<span class="Delimiter">()</span> const<span class="Delimiter">;</span> <span class="Delimiter">};</span> <span class="Delimiter">:(before "End Globals")</span> routine* Current_routine = <span class="Constant">NULL</span><span class="Delimiter">;</span> +map<string<span class="Delimiter">,</span> long long int> Instructions_running<span class="Delimiter">;</span> +map<string<span class="Delimiter">,</span> long long int> Locations_read<span class="Delimiter">;</span> +map<string<span class="Delimiter">,</span> long long int> Locations_read_by_instruction<span class="Delimiter">;</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> run<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void run<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> routine rr<span class="Delimiter">(</span>r<span class="Delimiter">);</span> Current_routine = &rr<span class="Delimiter">;</span> run_current_routine<span class="Delimiter">();</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> run_current_routine<span class="Delimiter">()</span> +void run_current_routine<span class="Delimiter">()</span> <span class="Delimiter">{</span> <span class="Comment">// curly on a separate line, because later layers will modify header</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>!Current_routine<span class="Delimiter">-></span>completed<span class="Delimiter">())</span> <span class="Comment">// later layers will modify condition</span> + while <span class="Delimiter">(</span>!Current_routine<span class="Delimiter">-></span>completed<span class="Delimiter">())</span> <span class="Comment">// later layers will modify condition</span> <span class="Delimiter">{</span> <span class="Comment">// Running One Instruction</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>is_label<span class="Delimiter">)</span> <span class="Delimiter">{</span> ++current_step_index<span class="Delimiter">();</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> +<span class="CommentedCode">//? Instructions_running[current_recipe_name()]++; //? 1</span> + if <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>is_label<span class="Delimiter">)</span> <span class="Delimiter">{</span> ++current_step_index<span class="Delimiter">();</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> trace<span class="Delimiter">(</span>Initial_callstack_depth+Callstack_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << end<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Memory[<span class="Constant">0</span>] != <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Memory[<span class="Constant">0</span>] != <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << <span class="Constant">"something wrote to location 0; this should never happen</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> Memory[<span class="Constant">0</span>] = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">// Read all ingredients from memory.</span> <span class="Comment">// Each ingredient loads a vector of values rather than a single value; mu</span> <span class="Comment">// permits operating on reagents spanning multiple locations.</span> - vector<vector<<span class="Normal">double</span>> > ingredients<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>read_memory<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> + vector<vector<double> > ingredients<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>should_copy_ingredients<span class="Delimiter">())</span> <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>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>read_memory<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="CommentedCode">//? Locations_read[current_recipe_name()] += SIZE(ingredients.back()); //? 1</span> +<span class="CommentedCode">//? Locations_read_by_instruction[current_instruction().name] += SIZE(ingredients.back()); //? 1</span> + <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Comment">// Instructions below will write to 'products'.</span> - vector<vector<<span class="Normal">double</span>> > products<span class="Delimiter">;</span> - <span class="Normal">switch</span> <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>operation<span class="Delimiter">)</span> <span class="Delimiter">{</span> + vector<vector<double> > products<span class="Delimiter">;</span> + switch <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>operation<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// Primitive Recipe Implementations</span> - <span class="Normal">case</span> COPY: <span class="Delimiter">{</span> + case COPY: <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> != SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">))</span> <span class="Delimiter">{</span> + raise << <span class="Constant">"ingredients and products should match in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <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_mu_array<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> && is_mu_array<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> <span class="Delimiter">{</span> + raise << <span class="Constant">"can't copy "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="Constant">" to array "</span> << current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span> + <span class="Delimiter">}</span> + if <span class="Delimiter">(</span>is_mu_array<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> && !is_mu_array<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> <span class="Delimiter">{</span> + raise << <span class="Constant">"can't copy array "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="Constant">" to "</span> << current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Delimiter">}</span> copy<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> ingredients<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> inserter<span class="Delimiter">(</span>products<span class="Delimiter">,</span> products<span class="Delimiter">.</span>begin<span class="Delimiter">()));</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">// End Primitive Recipe Implementations</span> - <span class="Normal">default</span>: <span class="Delimiter">{</span> + default: <span class="Delimiter">{</span> cout << <span class="Constant">"not a primitive op: "</span> << current_instruction<span class="Delimiter">().</span>operation << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> <span class="Delimiter">{</span> + finish_instruction: + 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> <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> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> + else <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> <span class="Delimiter">}</span> <span class="Comment">// End of Instruction</span> ++current_step_index<span class="Delimiter">();</span> <span class="Delimiter">}</span> - <span class="Normal">stop_running_current_routine</span>:<span class="Delimiter">;</span> + stop_running_current_routine:<span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +bool should_copy_ingredients<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Comment">// End should_copy_ingredients Special-cases</span> + <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">//: Some helpers.</span> <span class="Comment">//: We'll need to override these later as we change the definition of routine.</span> <span class="Comment">//: Important that they return referrences into the routine.</span> -<span class="Normal">inline</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>& current_step_index<span class="Delimiter">()</span> <span class="Delimiter">{</span> +inline long long int& current_step_index<span class="Delimiter">()</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> Current_routine<span class="Delimiter">-></span>running_step_index<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">inline</span> <span class="Normal">const</span> string& current_recipe_name<span class="Delimiter">()</span> <span class="Delimiter">{</span> +inline const string& current_recipe_name<span class="Delimiter">()</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> Recipe[Current_routine<span class="Delimiter">-></span>running_recipe]<span class="Delimiter">.</span>name<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">inline</span> <span class="Normal">const</span> instruction& current_instruction<span class="Delimiter">()</span> <span class="Delimiter">{</span> +inline const instruction& current_instruction<span class="Delimiter">()</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> Recipe[Current_routine<span class="Delimiter">-></span>running_recipe]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>running_step_index<span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">inline</span> <span class="Normal">bool</span> routine::completed<span class="Delimiter">()</span> <span class="Normal">const</span> <span class="Delimiter">{</span> +inline bool routine::completed<span class="Delimiter">()</span> const <span class="Delimiter">{</span> <span class="Identifier">return</span> running_step_index >= SIZE<span class="Delimiter">(</span>Recipe[running_recipe]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Commandline Parsing")</span> <span class="Comment">// Loading Commandline Files</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>argc > <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">1</span><span class="Delimiter">;</span> i < argc<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> +if <span class="Delimiter">(</span>argc > <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>int i = <span class="Constant">1</span><span class="Delimiter">;</span> i < argc<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> load_permanently<span class="Delimiter">(</span>argv[i]<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Main")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>!Run_tests<span class="Delimiter">)</span> <span class="Delimiter">{</span> +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"; //? 2</span> <span class="CommentedCode">//? START_TRACING_UNTIL_END_OF_SCOPE; //? 2</span> <span class="CommentedCode">//? Trace_stream->collect_layer.insert("app"); //? 1</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> - <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">)</span> run<span class="Delimiter">(</span>r<span class="Delimiter">);</span> +<span class="CommentedCode">//? atexit(dump_profile); //? 1</span> + if <span class="Delimiter">(</span>r<span class="Delimiter">)</span> run<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="CommentedCode">//? dump_memory(); //? 1</span> teardown<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> cleanup_main<span class="Delimiter">()</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Trace_file<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span> - ofstream fout<span class="Delimiter">(</span>Trace_file<span class="Delimiter">.</span>c_str<span class="Delimiter">());</span> +void dump_profile<span class="Delimiter">()</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> long long int>::iterator p = Instructions_running<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Instructions_running<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + cerr << p<span class="Delimiter">-></span>first << <span class="Constant">": "</span> << p<span class="Delimiter">-></span>second << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + cerr << <span class="Constant">"== locations read</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span> + for <span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> long long int>::iterator p = Locations_read<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Locations_read<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + cerr << p<span class="Delimiter">-></span>first << <span class="Constant">": "</span> << p<span class="Delimiter">-></span>second << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + cerr << <span class="Constant">"== locations read by instruction</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span> + for <span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> long long int>::iterator p = Locations_read_by_instruction<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Locations_read_by_instruction<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + cerr << p<span class="Delimiter">-></span>first << <span class="Constant">": "</span> << p<span class="Delimiter">-></span>second << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> +<span class="Delimiter">}</span> + +<span class="Delimiter">:(code)</span> +void cleanup_main<span class="Delimiter">()</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!Trace_file<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span> + ofstream fout<span class="Delimiter">((</span>Trace_dir+Trace_file<span class="Delimiter">).</span>c_str<span class="Delimiter">());</span> fout << Trace_stream<span class="Delimiter">-></span>readable_contents<span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">);</span> fout<span class="Delimiter">.</span>close<span class="Delimiter">();</span> <span class="Delimiter">}</span> @@ -187,10 +230,10 @@ routine* Current_routine = <span class="Constant">NULL</span><span class="Delimi atexit<span class="Delimiter">(</span>cleanup_main<span class="Delimiter">);</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> load_permanently<span class="Delimiter">(</span>string filename<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void load_permanently<span class="Delimiter">(</span>string filename<span class="Delimiter">)</span> <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> - <span class="Normal">if</span> <span class="Delimiter">(</span>!fin<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!fin<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << <span class="Constant">"no such file "</span> << filename << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -209,74 +252,78 @@ load_permanently<span class="Delimiter">(</span><span class="Constant">"cor <span class="Delimiter">:(code)</span> <span class="Comment">// helper for tests</span> -<span class="Normal">void</span> run<span class="Delimiter">(</span>string form<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void run<span class="Delimiter">(</span>string form<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << form << '\n'; //? 1</span> vector<recipe_ordinal> tmp = load<span class="Delimiter">(</span>form<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> transform_all<span class="Delimiter">();</span> run<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>front<span class="Delimiter">());</span> <span class="Delimiter">}</span> <span class="SalientComment">//:: Reading from memory, writing to memory.</span> -vector<<span class="Normal">double</span>> read_memory<span class="Delimiter">(</span>reagent x<span class="Delimiter">)</span> <span class="Delimiter">{</span> +vector<double> read_memory<span class="Delimiter">(</span>reagent x<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cout << "read_memory: " << x.to_string() << '\n'; //? 2</span> - vector<<span class="Normal">double</span>> result<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Delimiter">{</span> + vector<double> result<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Delimiter">{</span> result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>x<span class="Delimiter">.</span>value<span class="Delimiter">);</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> base = x<span class="Delimiter">.</span>value<span class="Delimiter">;</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> size = size_of<span class="Delimiter">(</span>x<span class="Delimiter">);</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> offset = <span class="Constant">0</span><span class="Delimiter">;</span> offset < size<span class="Delimiter">;</span> ++offset<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">double</span> val = Memory[base+offset]<span class="Delimiter">;</span> + long long int base = x<span class="Delimiter">.</span>value<span class="Delimiter">;</span> + long long int size = size_of<span class="Delimiter">(</span>x<span class="Delimiter">);</span> + for <span class="Delimiter">(</span>long long int offset = <span class="Constant">0</span><span class="Delimiter">;</span> offset < size<span class="Delimiter">;</span> ++offset<span class="Delimiter">)</span> <span class="Delimiter">{</span> + double val = Memory[base+offset]<span class="Delimiter">;</span> trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"mem"</span><span class="Delimiter">)</span> << <span class="Constant">"location "</span> << base+offset << <span class="Constant">" is "</span> << val << end<span class="Delimiter">();</span> result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>val<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> write_memory<span class="Delimiter">(</span>reagent x<span class="Delimiter">,</span> vector<<span class="Normal">double</span>> data<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_dummy<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> base = x<span class="Delimiter">.</span>value<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>size_mismatch<span class="Delimiter">(</span>x<span class="Delimiter">,</span> data<span class="Delimiter">))</span> <span class="Delimiter">{</span> +void write_memory<span class="Delimiter">(</span>reagent x<span class="Delimiter">,</span> vector<double> data<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>is_dummy<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + long long int base = x<span class="Delimiter">.</span>value<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>size_mismatch<span class="Delimiter">(</span>x<span class="Delimiter">,</span> data<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": size mismatch in storing to "</span> << x<span class="Delimiter">.</span>original_string << <span class="Constant">" at '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> offset = <span class="Constant">0</span><span class="Delimiter">;</span> offset < SIZE<span class="Delimiter">(</span>data<span class="Delimiter">);</span> ++offset<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int offset = <span class="Constant">0</span><span class="Delimiter">;</span> offset < SIZE<span class="Delimiter">(</span>data<span class="Delimiter">);</span> ++offset<span class="Delimiter">)</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"mem"</span><span class="Delimiter">)</span> << <span class="Constant">"storing "</span> << data<span class="Delimiter">.</span>at<span class="Delimiter">(</span>offset<span class="Delimiter">)</span> << <span class="Constant">" in location "</span> << base+offset << end<span class="Delimiter">();</span> Memory[base+offset] = data<span class="Delimiter">.</span>at<span class="Delimiter">(</span>offset<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> size_of<span class="Delimiter">(</span><span class="Normal">const</span> reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span> +long long int size_of<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Comment">// End size_of(reagent) Cases</span> <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> size_of<span class="Delimiter">(</span><span class="Normal">const</span> vector<type_ordinal>& types<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span> +long long int size_of<span class="Delimiter">(</span>const vector<type_ordinal>& types<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Comment">// End size_of(types) Cases</span> <span class="Identifier">return</span> <span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">bool</span> size_mismatch<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">,</span> <span class="Normal">const</span> vector<<span class="Normal">double</span>>& data<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> +bool size_mismatch<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">,</span> const vector<double>& data<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Comment">// End size_mismatch(x) Cases</span> <span class="CommentedCode">//? if (size_of(x) != SIZE(data)) cerr << size_of(x) << " vs " << SIZE(data) << '\n'; //? 2</span> <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>x<span class="Delimiter">)</span> != SIZE<span class="Delimiter">(</span>data<span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">bool</span> is_dummy<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> +bool is_dummy<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> x<span class="Delimiter">.</span>name == <span class="Constant">"_"</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">bool</span> is_literal<span class="Delimiter">(</span><span class="Normal">const</span> reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> +bool is_literal<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">)</span> == <span class="Constant">1</span> && r<span class="Delimiter">.</span>types<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> <span class="Delimiter">}</span> +bool is_mu_array<span class="Delimiter">(</span>reagent r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Identifier">return</span> !r<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && r<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">"array"</span>]<span class="Delimiter">;</span> +<span class="Delimiter">}</span> + <span class="Delimiter">:(scenario run_label)</span> recipe main [ +foo @@ -298,6 +345,54 @@ recipe main [ <span class="Constant">0</span><span class="Special"> <- </span>copy <span class="Constant">34</span> ] <span class="traceAbsent">-mem: storing 34 in location 0</span> + +<span class="Delimiter">:(scenario copy_checks_reagent_count)</span> +<span class="Special">% Hide_warnings = true;</span> +recipe main [ + <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">35</span> +] +<span class="traceContains">+warn: ingredients and products should match in '1:number <- copy 34, 35'</span> + +<span class="Delimiter">:(scenario write_scalar_to_array_disallowed)</span> +<span class="Special">% Hide_warnings = true;</span> +recipe main [ + <span class="Constant">1</span>:array:number<span class="Special"> <- </span>copy <span class="Constant">34</span> +] +<span class="traceContains">+warn: can't copy 34 to array 1:array:number</span> + +<span class="Delimiter">:(scenario write_scalar_to_array_disallowed_2)</span> +<span class="Special">% Hide_warnings = true;</span> +recipe main [ + <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:array:number<span class="Special"> <- </span>copy <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">35</span> +] +<span class="traceContains">+warn: can't copy 35 to array 2:array:number</span> + +<span class="Comment">//: mu is robust to various combinations of commas and spaces. You just have</span> +<span class="Comment">//: to put spaces around the '<-'.</span> + +<span class="Delimiter">:(scenario comma_without_space)</span> +recipe main [ + <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">2</span><span class="Delimiter">,</span><span class="Constant">2</span> +] +<span class="traceContains">+mem: storing 2 in location 1</span> + +<span class="Delimiter">:(scenario space_without_comma)</span> +recipe main [ + <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">2</span> <span class="Constant">2</span> +] +<span class="traceContains">+mem: storing 2 in location 1</span> + +<span class="Delimiter">:(scenario comma_before_space)</span> +recipe main [ + <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">2</span><span class="Delimiter">,</span> <span class="Constant">2</span> +] +<span class="traceContains">+mem: storing 2 in location 1</span> + +<span class="Delimiter">:(scenario comma_after_space)</span> +recipe main [ + <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">2</span> <span class="Delimiter">,</span><span class="Constant">2</span> +] +<span class="traceContains">+mem: storing 2 in location 1</span> </pre> </body> </html> diff --git a/html/021arithmetic.cc.html b/html/021arithmetic.cc.html index 69118dc4..af5099f4 100644 --- a/html/021arithmetic.cc.html +++ b/html/021arithmetic.cc.html @@ -13,15 +13,14 @@ 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; } +.Identifier { color: #804000; } .traceContains { color: #008000; } -.Constant { color: #00a0a0; } -.Special { color: #ff6060; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } +.Special { color: #ff6060; } .CommentedCode { color: #6c6c6c; } -.Identifier { color: #804000; } -.cSpecial { color: #008000; } +.Constant { color: #00a0a0; } --> </style> @@ -40,11 +39,14 @@ ADD<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"add"</span>] = ADD<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> ADD: <span class="Delimiter">{</span> - <span class="Normal">double</span> result = <span class="Constant">0</span><span class="Delimiter">;</span> +case ADD: <span class="Delimiter">{</span> + double result = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="CommentedCode">//? if (!tb_is_active()) cerr << ingredients.at(1).at(0) << '\n'; //? 1</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> - assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'add' requires number ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span> + <span class="Delimiter">}</span> result += ingredients<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="Delimiter">}</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> @@ -77,15 +79,21 @@ SUBTRACT<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"subtract"</span>] = SUBTRACT<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> SUBTRACT: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> +case SUBTRACT: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'subtract' has no ingredients</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</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">0</span><span class="Delimiter">)));</span> - <span class="Normal">double</span> result = 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="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">1</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> - assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'subtract' requires number ingredients, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span> + <span class="Delimiter">}</span> + double result = 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> + for <span class="Delimiter">(</span>long long int i = <span class="Constant">1</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>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'subtract' requires number ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span> + <span class="Delimiter">}</span> result -= ingredients<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="Delimiter">}</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> @@ -118,10 +126,13 @@ MULTIPLY<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"multiply"</span>] = MULTIPLY<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> MULTIPLY: <span class="Delimiter">{</span> - <span class="Normal">double</span> result = <span class="Constant">1</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> - assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)));</span> +case MULTIPLY: <span class="Delimiter">{</span> + double result = <span class="Constant">1</span><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>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'multiply' requires number ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span> + <span class="Delimiter">}</span> result *= ingredients<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="Delimiter">}</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> @@ -154,15 +165,21 @@ DIVIDE<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"divide"</span>] = DIVIDE<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> DIVIDE: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> +case DIVIDE: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'divide' has no ingredients</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</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">0</span><span class="Delimiter">)));</span> - <span class="Normal">double</span> result = 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="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">1</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> - assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'divide' requires number ingredients, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span> + <span class="Delimiter">}</span> + double result = 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> + for <span class="Delimiter">(</span>long long int i = <span class="Constant">1</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>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'divide' requires number ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span> + <span class="Delimiter">}</span> result /= ingredients<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="Delimiter">}</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> @@ -197,14 +214,18 @@ DIVIDE_WITH_REMAINDER<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"divide-with-remainder"</span>] = DIVIDE_WITH_REMAINDER<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> DIVIDE_WITH_REMAINDER: <span class="Delimiter">{</span> +case DIVIDE_WITH_REMAINDER: <span class="Delimiter">{</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'divide-with-remainder' requires exactly two ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'divide-with-remainder' requires exactly two ingredients, but got '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> quotient = 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> / 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> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> remainder = <span class="Normal">static_cast</span><<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>><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="Normal">static_cast</span><<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>><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> + 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> || !scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'divide-with-remainder' requires number ingredients, but got '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span> + <span class="Delimiter">}</span> + long long int quotient = 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> / 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> + long long int remainder = static_cast<long long int><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> % static_cast<long long int><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> <span class="Comment">// very large integers will lose precision</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>quotient<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>remainder<span class="Delimiter">);</span> @@ -235,10 +256,10 @@ recipe main [ <span class="traceContains">+mem: storing 2.5 in location 1</span> <span class="Delimiter">:(code)</span> -<span class="Normal">inline</span> <span class="Normal">bool</span> scalar<span class="Delimiter">(</span><span class="Normal">const</span> vector<<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>>& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> +inline bool scalar<span class="Delimiter">(</span>const vector<long long int>& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> SIZE<span class="Delimiter">(</span>x<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">inline</span> <span class="Normal">bool</span> scalar<span class="Delimiter">(</span><span class="Normal">const</span> vector<<span class="Normal">double</span>>& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> +inline bool scalar<span class="Delimiter">(</span>const vector<double>& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> SIZE<span class="Delimiter">(</span>x<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> </pre> diff --git a/html/022boolean.cc.html b/html/022boolean.cc.html index 4d3c3c80..f1c0b5b2 100644 --- a/html/022boolean.cc.html +++ b/html/022boolean.cc.html @@ -13,13 +13,13 @@ 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; } .traceContains { color: #008000; } -.Constant { color: #00a0a0; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } --> </style> @@ -38,10 +38,13 @@ AND<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"and"</span>] = AND<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> AND: <span class="Delimiter">{</span> - <span class="Normal">bool</span> result = <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> - assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)));</span> +case AND: <span class="Delimiter">{</span> + bool result = <span class="Constant">true</span><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>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'and' requires boolean ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span> + <span class="Delimiter">}</span> result = result && ingredients<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="Delimiter">}</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> @@ -53,25 +56,25 @@ Recipe_ordinal[<span class="Constant">"and"</span>] = AND<span class=" recipe main [ <span class="Constant">1</span>:boolean<span class="Special"> <- </span>copy <span class="Constant">1</span> <span class="Constant">2</span>:boolean<span class="Special"> <- </span>copy <span class="Constant">0</span> - <span class="Constant">3</span>:boolean<span class="Special"> <- </span><span class="Normal">and</span> <span class="Constant">1</span>:boolean<span class="Delimiter">,</span> <span class="Constant">2</span>:boolean + <span class="Constant">3</span>:boolean<span class="Special"> <- </span>and <span class="Constant">1</span>:boolean<span class="Delimiter">,</span> <span class="Constant">2</span>:boolean ] <span class="traceContains">+mem: storing 0 in location 3</span> -<span class="Delimiter">:(scenario and2)</span> +<span class="Delimiter">:(scenario and_2)</span> recipe main [ - <span class="Constant">1</span>:boolean<span class="Special"> <- </span><span class="Normal">and</span> <span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">1</span> + <span class="Constant">1</span>:boolean<span class="Special"> <- </span>and <span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">1</span> ] <span class="traceContains">+mem: storing 1 in location 1</span> <span class="Delimiter">:(scenario and_multiple)</span> recipe main [ - <span class="Constant">1</span>:boolean<span class="Special"> <- </span><span class="Normal">and</span> <span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">0</span> + <span class="Constant">1</span>:boolean<span class="Special"> <- </span>and <span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">0</span> ] <span class="traceContains">+mem: storing 0 in location 1</span> -<span class="Delimiter">:(scenario and_multiple2)</span> +<span class="Delimiter">:(scenario and_multiple_2)</span> recipe main [ - <span class="Constant">1</span>:boolean<span class="Special"> <- </span><span class="Normal">and</span> <span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">1</span> + <span class="Constant">1</span>:boolean<span class="Special"> <- </span>and <span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">1</span> ] <span class="traceContains">+mem: storing 1 in location 1</span> @@ -80,10 +83,13 @@ OR<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"or"</span>] = OR<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> OR: <span class="Delimiter">{</span> - <span class="Normal">bool</span> result = <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> - assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)));</span> +case OR: <span class="Delimiter">{</span> + bool result = <span class="Constant">false</span><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>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'or' requires boolean ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span> + <span class="Delimiter">}</span> result = result || ingredients<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="Delimiter">}</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> @@ -95,25 +101,25 @@ Recipe_ordinal[<span class="Constant">"or"</span>] = OR<span class="De recipe main [ <span class="Constant">1</span>:boolean<span class="Special"> <- </span>copy <span class="Constant">1</span> <span class="Constant">2</span>:boolean<span class="Special"> <- </span>copy <span class="Constant">0</span> - <span class="Constant">3</span>:boolean<span class="Special"> <- </span><span class="Normal">or</span> <span class="Constant">1</span>:boolean<span class="Delimiter">,</span> <span class="Constant">2</span>:boolean + <span class="Constant">3</span>:boolean<span class="Special"> <- </span>or <span class="Constant">1</span>:boolean<span class="Delimiter">,</span> <span class="Constant">2</span>:boolean ] <span class="traceContains">+mem: storing 1 in location 3</span> -<span class="Delimiter">:(scenario or2)</span> +<span class="Delimiter">:(scenario or_2)</span> recipe main [ - <span class="Constant">1</span>:boolean<span class="Special"> <- </span><span class="Normal">or</span> <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">0</span> + <span class="Constant">1</span>:boolean<span class="Special"> <- </span>or <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">0</span> ] <span class="traceContains">+mem: storing 0 in location 1</span> <span class="Delimiter">:(scenario or_multiple)</span> recipe main [ - <span class="Constant">1</span>:boolean<span class="Special"> <- </span><span class="Normal">and</span> <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">0</span> + <span class="Constant">1</span>:boolean<span class="Special"> <- </span>and <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">0</span> ] <span class="traceContains">+mem: storing 0 in location 1</span> -<span class="Delimiter">:(scenario or_multiple2)</span> +<span class="Delimiter">:(scenario or_multiple_2)</span> recipe main [ - <span class="Constant">1</span>:boolean<span class="Special"> <- </span><span class="Normal">or</span> <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">1</span> + <span class="Constant">1</span>:boolean<span class="Special"> <- </span>or <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">1</span> ] <span class="traceContains">+mem: storing 1 in location 1</span> @@ -122,10 +128,13 @@ NOT<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"not"</span>] = NOT<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> NOT: <span class="Delimiter">{</span> +case NOT: <span class="Delimiter">{</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">));</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> - assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'not' requires boolean ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span> + <span class="Delimiter">}</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>!ingredients<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="Delimiter">}</span> <span class="Identifier">break</span><span class="Delimiter">;</span> @@ -134,13 +143,13 @@ Recipe_ordinal[<span class="Constant">"not"</span>] = NOT<span class=" <span class="Delimiter">:(scenario not)</span> recipe main [ <span class="Constant">1</span>:boolean<span class="Special"> <- </span>copy <span class="Constant">1</span> - <span class="Constant">2</span>:boolean<span class="Special"> <- </span><span class="Normal">not</span> <span class="Constant">1</span>:boolean + <span class="Constant">2</span>:boolean<span class="Special"> <- </span>not <span class="Constant">1</span>:boolean ] <span class="traceContains">+mem: storing 0 in location 2</span> <span class="Delimiter">:(scenario not_multiple)</span> recipe main [ - <span class="Constant">1</span>:boolean<span class="Delimiter">,</span> <span class="Constant">2</span>:boolean<span class="Delimiter">,</span> <span class="Constant">3</span>:boolean<span class="Special"> <- </span><span class="Normal">not</span> <span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">1</span> + <span class="Constant">1</span>:boolean<span class="Delimiter">,</span> <span class="Constant">2</span>:boolean<span class="Delimiter">,</span> <span class="Constant">3</span>:boolean<span class="Special"> <- </span>not <span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">1</span> ] <span class="traceContains">+mem: storing 0 in location 1</span> <span class="traceContains">+mem: storing 1 in location 2</span> diff --git a/html/023jump.cc.html b/html/023jump.cc.html index 29b0ed48..63248241 100644 --- a/html/023jump.cc.html +++ b/html/023jump.cc.html @@ -13,16 +13,15 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } .traceAbsent { color: #c00000; } -.Constant { color: #00a0a0; } +.Identifier { color: #804000; } .cSpecial { color: #008000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } -.Special { color: #ff6060; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } +.Special { color: #ff6060; } .CommentedCode { color: #6c6c6c; } -.Identifier { color: #804000; } +.Constant { color: #00a0a0; } +.traceContains { color: #008000; } --> </style> @@ -51,12 +50,12 @@ JUMP<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"jump"</span>] = JUMP<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> JUMP: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case JUMP: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'jump' requires exactly one ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> + 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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'jump' should be a label or offset, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -86,21 +85,21 @@ JUMP_IF<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"jump-if"</span>] = JUMP_IF<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> JUMP_IF: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case JUMP_IF: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'jump-if' requires exactly two ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> + 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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'jump-if' requires a boolean for its first ingredient, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> <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> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'jump-if' requires a label or offset for its second ingredient, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> assert<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>initialized<span class="Delimiter">);</span> - <span class="Normal">if</span> <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="Delimiter">{</span> + if <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="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">"jump-if fell through"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -111,7 +110,7 @@ Recipe_ordinal[<span class="Constant">"jump-if"</span>] = JUMP_IF<span <span class="Delimiter">:(scenario jump_if)</span> recipe main [ - jump-<span class="Normal">if</span> <span class="Constant">999</span><span class="Delimiter">,</span> <span class="Constant">1</span>:offset + jump-if <span class="Constant">999</span><span class="Delimiter">,</span> <span class="Constant">1</span>:offset <span class="Constant">123</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span> ] <span class="traceContains">+run: jump-if 999, 1:offset</span> @@ -121,7 +120,7 @@ recipe main [ <span class="Delimiter">:(scenario jump_if_fallthrough)</span> recipe main [ - jump-<span class="Normal">if</span> <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">1</span>:offset + jump-if <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">1</span>:offset <span class="Constant">123</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span> ] <span class="traceContains">+run: jump-if 0, 1:offset</span> @@ -134,21 +133,21 @@ JUMP_UNLESS<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"jump-unless"</span>] = JUMP_UNLESS<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> JUMP_UNLESS: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case JUMP_UNLESS: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'jump-unless' requires exactly two ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> + 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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'jump-unless' requires a boolean for its first ingredient, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> <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> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'jump-unless' requires a label or offset for its second ingredient, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> assert<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>initialized<span class="Delimiter">);</span> - <span class="Normal">if</span> <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="Delimiter">{</span> + if <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="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">"jump-unless fell through"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> diff --git a/html/024compare.cc.html b/html/024compare.cc.html index 6e1b5af7..1fb7c4a5 100644 --- a/html/024compare.cc.html +++ b/html/024compare.cc.html @@ -13,14 +13,13 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.traceContains { color: #008000; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } --> </style> @@ -39,15 +38,15 @@ EQUAL<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"equal"</span>] = EQUAL<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> EQUAL: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> <= <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case EQUAL: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> <= <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'equal' needs at least two ingredients to compare in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - vector<<span class="Normal">double</span>>& exemplar = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> - <span class="Normal">bool</span> result = <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">1</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> - <span class="Normal">if</span> <span class="Delimiter">(</span>!equal<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>begin<span class="Delimiter">(),</span> ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>end<span class="Delimiter">(),</span> exemplar<span class="Delimiter">.</span>begin<span class="Delimiter">()))</span> <span class="Delimiter">{</span> + vector<double>& exemplar = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> + bool result = <span class="Constant">true</span><span class="Delimiter">;</span> + for <span class="Delimiter">(</span>long long int i = <span class="Constant">1</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>!equal<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>begin<span class="Delimiter">(),</span> ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>end<span class="Delimiter">(),</span> exemplar<span class="Delimiter">.</span>begin<span class="Delimiter">()))</span> <span class="Delimiter">{</span> result = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -67,7 +66,7 @@ recipe main [ <span class="traceContains">+mem: location 2 is 33</span> <span class="traceContains">+mem: storing 0 in location 3</span> -<span class="Delimiter">:(scenario equal2)</span> +<span class="Delimiter">:(scenario equal_2)</span> recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> @@ -83,7 +82,7 @@ recipe main [ ] <span class="traceContains">+mem: storing 1 in location 1</span> -<span class="Delimiter">:(scenario equal_multiple2)</span> +<span class="Delimiter">:(scenario equal_multiple_2)</span> recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>equal <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">35</span> ] @@ -94,24 +93,24 @@ GREATER_THAN<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"greater-than"</span>] = GREATER_THAN<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> GREATER_THAN: <span class="Delimiter">{</span> - <span class="Normal">bool</span> result = <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> <= <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case GREATER_THAN: <span class="Delimiter">{</span> + bool result = <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> <= <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'greater-than' needs at least two ingredients to compare in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> - <span class="Normal">if</span> <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <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>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'greater-than' can only compare numbers; got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">goto</span> finish_greater_than<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Comment">/**/</span><span class="Constant">1</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> - <span class="Normal">if</span> <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i-<span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> <= ingredients<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="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int i = <span class="Comment">/**/</span><span class="Constant">1</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>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i-<span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> <= ingredients<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="Delimiter">{</span> result = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> - <span class="Normal">finish_greater_than</span>: + finish_greater_than: 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> @@ -125,7 +124,7 @@ recipe main [ ] <span class="traceContains">+mem: storing 1 in location 3</span> -<span class="Delimiter">:(scenario greater_than2)</span> +<span class="Delimiter">:(scenario greater_than_2)</span> recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> @@ -139,7 +138,7 @@ recipe main [ ] <span class="traceContains">+mem: storing 1 in location 1</span> -<span class="Delimiter">:(scenario greater_than_multiple2)</span> +<span class="Delimiter">:(scenario greater_than_multiple_2)</span> recipe main [ <span class="Constant">1</span>:boolean<span class="Special"> <- </span>greater-than <span class="Constant">36</span><span class="Delimiter">,</span> <span class="Constant">35</span><span class="Delimiter">,</span> <span class="Constant">35</span> ] @@ -150,24 +149,24 @@ LESSER_THAN<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"lesser-than"</span>] = LESSER_THAN<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> LESSER_THAN: <span class="Delimiter">{</span> - <span class="Normal">bool</span> result = <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> <= <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case LESSER_THAN: <span class="Delimiter">{</span> + bool result = <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> <= <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'lesser-than' needs at least two ingredients to compare in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> - <span class="Normal">if</span> <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <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>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'lesser-than' can only compare numbers; got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">goto</span> finish_lesser_than<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Comment">/**/</span><span class="Constant">1</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> - <span class="Normal">if</span> <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i-<span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> >= ingredients<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="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int i = <span class="Comment">/**/</span><span class="Constant">1</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>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i-<span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> >= ingredients<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="Delimiter">{</span> result = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> - <span class="Normal">finish_lesser_than</span>: + finish_lesser_than: 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> @@ -181,7 +180,7 @@ recipe main [ ] <span class="traceContains">+mem: storing 1 in location 3</span> -<span class="Delimiter">:(scenario lesser_than2)</span> +<span class="Delimiter">:(scenario lesser_than_2)</span> recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">33</span> @@ -195,7 +194,7 @@ recipe main [ ] <span class="traceContains">+mem: storing 1 in location 1</span> -<span class="Delimiter">:(scenario lesser_than_multiple2)</span> +<span class="Delimiter">:(scenario lesser_than_multiple_2)</span> recipe main [ <span class="Constant">1</span>:boolean<span class="Special"> <- </span>lesser-than <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">35</span><span class="Delimiter">,</span> <span class="Constant">35</span> ] @@ -206,24 +205,24 @@ GREATER_OR_EQUAL<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"greater-or-equal"</span>] = GREATER_OR_EQUAL<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> GREATER_OR_EQUAL: <span class="Delimiter">{</span> - <span class="Normal">bool</span> result = <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> <= <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case GREATER_OR_EQUAL: <span class="Delimiter">{</span> + bool result = <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> <= <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'greater-or-equal' needs at least two ingredients to compare in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> - <span class="Normal">if</span> <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <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>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'greater-or-equal' can only compare numbers; got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">goto</span> finish_greater_or_equal<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Comment">/**/</span><span class="Constant">1</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> - <span class="Normal">if</span> <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i-<span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> < ingredients<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="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int i = <span class="Comment">/**/</span><span class="Constant">1</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>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i-<span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> < ingredients<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="Delimiter">{</span> result = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> - <span class="Normal">finish_greater_or_equal</span>: + finish_greater_or_equal: 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> @@ -233,35 +232,35 @@ Recipe_ordinal[<span class="Constant">"greater-or-equal"</span>] = GRE recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">33</span> - <span class="Constant">3</span>:boolean<span class="Special"> <- </span>greater-<span class="Normal">or</span>-equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number + <span class="Constant">3</span>:boolean<span class="Special"> <- </span>greater-or-equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number ] <span class="traceContains">+mem: storing 1 in location 3</span> -<span class="Delimiter">:(scenario greater_or_equal2)</span> +<span class="Delimiter">:(scenario greater_or_equal_2)</span> recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> - <span class="Constant">3</span>:boolean<span class="Special"> <- </span>greater-<span class="Normal">or</span>-equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number + <span class="Constant">3</span>:boolean<span class="Special"> <- </span>greater-or-equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number ] <span class="traceContains">+mem: storing 1 in location 3</span> -<span class="Delimiter">:(scenario greater_or_equal3)</span> +<span class="Delimiter">:(scenario greater_or_equal_3)</span> recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span> - <span class="Constant">3</span>:boolean<span class="Special"> <- </span>greater-<span class="Normal">or</span>-equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number + <span class="Constant">3</span>:boolean<span class="Special"> <- </span>greater-or-equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number ] <span class="traceContains">+mem: storing 0 in location 3</span> <span class="Delimiter">:(scenario greater_or_equal_multiple)</span> recipe main [ - <span class="Constant">1</span>:boolean<span class="Special"> <- </span>greater-<span class="Normal">or</span>-equal <span class="Constant">36</span><span class="Delimiter">,</span> <span class="Constant">35</span><span class="Delimiter">,</span> <span class="Constant">35</span> + <span class="Constant">1</span>:boolean<span class="Special"> <- </span>greater-or-equal <span class="Constant">36</span><span class="Delimiter">,</span> <span class="Constant">35</span><span class="Delimiter">,</span> <span class="Constant">35</span> ] <span class="traceContains">+mem: storing 1 in location 1</span> -<span class="Delimiter">:(scenario greater_or_equal_multiple2)</span> +<span class="Delimiter">:(scenario greater_or_equal_multiple_2)</span> recipe main [ - <span class="Constant">1</span>:boolean<span class="Special"> <- </span>greater-<span class="Normal">or</span>-equal <span class="Constant">36</span><span class="Delimiter">,</span> <span class="Constant">35</span><span class="Delimiter">,</span> <span class="Constant">36</span> + <span class="Constant">1</span>:boolean<span class="Special"> <- </span>greater-or-equal <span class="Constant">36</span><span class="Delimiter">,</span> <span class="Constant">35</span><span class="Delimiter">,</span> <span class="Constant">36</span> ] <span class="traceContains">+mem: storing 0 in location 1</span> @@ -270,24 +269,24 @@ LESSER_OR_EQUAL<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"lesser-or-equal"</span>] = LESSER_OR_EQUAL<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> LESSER_OR_EQUAL: <span class="Delimiter">{</span> - <span class="Normal">bool</span> result = <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> <= <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case LESSER_OR_EQUAL: <span class="Delimiter">{</span> + bool result = <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> <= <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'lesser-or-equal' needs at least two ingredients to compare in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> - <span class="Normal">if</span> <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <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>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'lesser-or-equal' can only compare numbers; got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">goto</span> finish_lesser_or_equal<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Comment">/**/</span><span class="Constant">1</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> - <span class="Normal">if</span> <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i-<span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> > ingredients<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="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int i = <span class="Comment">/**/</span><span class="Constant">1</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>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i-<span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> > ingredients<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="Delimiter">{</span> result = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> - <span class="Normal">finish_lesser_or_equal</span>: + finish_lesser_or_equal: 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> @@ -297,35 +296,35 @@ Recipe_ordinal[<span class="Constant">"lesser-or-equal"</span>] = LESS recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">32</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">33</span> - <span class="Constant">3</span>:boolean<span class="Special"> <- </span>lesser-<span class="Normal">or</span>-equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number + <span class="Constant">3</span>:boolean<span class="Special"> <- </span>lesser-or-equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number ] <span class="traceContains">+mem: storing 1 in location 3</span> -<span class="Delimiter">:(scenario lesser_or_equal2)</span> +<span class="Delimiter">:(scenario lesser_or_equal_2)</span> recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">33</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">33</span> - <span class="Constant">3</span>:boolean<span class="Special"> <- </span>lesser-<span class="Normal">or</span>-equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number + <span class="Constant">3</span>:boolean<span class="Special"> <- </span>lesser-or-equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number ] <span class="traceContains">+mem: storing 1 in location 3</span> -<span class="Delimiter">:(scenario lesser_or_equal3)</span> +<span class="Delimiter">:(scenario lesser_or_equal_3)</span> recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">33</span> - <span class="Constant">3</span>:boolean<span class="Special"> <- </span>lesser-<span class="Normal">or</span>-equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number + <span class="Constant">3</span>:boolean<span class="Special"> <- </span>lesser-or-equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number ] <span class="traceContains">+mem: storing 0 in location 3</span> <span class="Delimiter">:(scenario lesser_or_equal_multiple)</span> recipe main [ - <span class="Constant">1</span>:boolean<span class="Special"> <- </span>lesser-<span class="Normal">or</span>-equal <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">35</span><span class="Delimiter">,</span> <span class="Constant">35</span> + <span class="Constant">1</span>:boolean<span class="Special"> <- </span>lesser-or-equal <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">35</span><span class="Delimiter">,</span> <span class="Constant">35</span> ] <span class="traceContains">+mem: storing 1 in location 1</span> -<span class="Delimiter">:(scenario lesser_or_equal_multiple2)</span> +<span class="Delimiter">:(scenario lesser_or_equal_multiple_2)</span> recipe main [ - <span class="Constant">1</span>:boolean<span class="Special"> <- </span>lesser-<span class="Normal">or</span>-equal <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">35</span><span class="Delimiter">,</span> <span class="Constant">34</span> + <span class="Constant">1</span>:boolean<span class="Special"> <- </span>lesser-or-equal <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">35</span><span class="Delimiter">,</span> <span class="Constant">34</span> ] <span class="traceContains">+mem: storing 0 in location 1</span> </pre> diff --git a/html/029tools.cc.html b/html/029tools.cc.html index c25d25d4..9db3f206 100644 --- a/html/029tools.cc.html +++ b/html/029tools.cc.html @@ -13,16 +13,15 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.SalientComment { color: #00ffff; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } +.SalientComment { color: #00ffff; } .Special { color: #ff6060; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.CommentedCode { color: #6c6c6c; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } -.CommentedCode { color: #6c6c6c; } +.traceContains { color: #008000; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } --> </style> @@ -38,7 +37,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">:(scenario trace)</span> recipe main [ - trace [foo]<span class="Delimiter">,</span> [<span class="Normal">this</span> is a trace in mu] + trace <span class="Constant">1</span><span class="Delimiter">,</span> [foo]<span class="Delimiter">,</span> [this is a trace in mu] ] <span class="traceContains">+foo: this is a trace in mu</span> @@ -47,32 +46,82 @@ TRACE<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"trace"</span>] = TRACE<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> TRACE: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> == <span class="Constant">2</span><span class="Delimiter">)</span> <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">0</span><span class="Delimiter">)));</span> - string label = 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> - 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> - string message = 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>name<span class="Delimiter">;</span> - trace<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">,</span> label<span class="Delimiter">)</span> << message << end<span class="Delimiter">();</span> +case TRACE: <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">3</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'trace' takes three or more ingredients rather than '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'trace' should be a number (depth), but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + long long int depth = 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>!is_literal_string<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> <span class="Delimiter">{</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": second ingredient of 'trace' should be a literal string (label), but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">)</span> <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">0</span><span class="Delimiter">)));</span> - string message = 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="CommentedCode">//? cerr << "tracing " << message << '\n'; //? 1</span> - trace<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">"app"</span><span class="Delimiter">)</span> << message << end<span class="Delimiter">();</span> + string label = 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>name<span class="Delimiter">;</span> + ostringstream out<span class="Delimiter">;</span> + for <span class="Delimiter">(</span>long long int i = <span class="Constant">2</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + out << print_mu<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> ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> - raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'trace' takes one or two ingredients rather than '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + trace<span class="Delimiter">(</span>depth<span class="Delimiter">,</span> label<span class="Delimiter">)</span> << out<span class="Delimiter">.</span>str<span class="Delimiter">()</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +<span class="Comment">//: a smarter but more limited version of 'trace'</span> + +<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> +STASH<span class="Delimiter">,</span> +<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> +Recipe_ordinal[<span class="Constant">"stash"</span>] = STASH<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> +case STASH: <span class="Delimiter">{</span> + ostringstream out<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>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + out << print_mu<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> ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> <span class="Delimiter">}</span> + trace<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">"app"</span><span class="Delimiter">)</span> << out<span class="Delimiter">.</span>str<span class="Delimiter">()</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> +<span class="Delimiter">:(scenario stash_literal_string)</span> +recipe main [ + stash [foo] +] +<span class="traceContains">+app: foo</span> + +<span class="Delimiter">:(scenario stash_literal_number)</span> +recipe main [ + stash [foo: ]<span class="Delimiter">,</span> <span class="Constant">4</span> +] +<span class="traceContains">+app: foo: 4</span> + +<span class="Delimiter">:(scenario stash_number)</span> +recipe main [ + <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> + stash [foo: ]<span class="Delimiter">,</span> <span class="Constant">1</span>:number +] +<span class="traceContains">+app: foo: 34</span> + +<span class="Delimiter">:(code)</span> +string print_mu<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">,</span> const vector<double>& data<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>r<span class="Delimiter">))</span> + <span class="Identifier">return</span> r<span class="Delimiter">.</span>name<span class="Delimiter">;</span> + <span class="Comment">// End print Special-cases(reagent r, data)</span> + ostringstream out<span class="Delimiter">;</span> + for <span class="Delimiter">(</span>long long i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>data<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + out << data<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> << <span class="Constant">' '</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span> +<span class="Delimiter">}</span> + <span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> HIDE_WARNINGS<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"hide-warnings"</span>] = HIDE_WARNINGS<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> HIDE_WARNINGS: <span class="Delimiter">{</span> +case HIDE_WARNINGS: <span class="Delimiter">{</span> Hide_warnings = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -82,7 +131,7 @@ SHOW_WARNINGS<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"show-warnings"</span>] = SHOW_WARNINGS<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> SHOW_WARNINGS: <span class="Delimiter">{</span> +case SHOW_WARNINGS: <span class="Delimiter">{</span> Hide_warnings = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -92,10 +141,10 @@ _START_TRACING<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"$start-tracing"</span>] = _START_TRACING<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> _START_TRACING: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> +case _START_TRACING: <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> Trace_stream<span class="Delimiter">-></span>dump_layer = <span class="Constant">"all"</span><span class="Delimiter">;</span> - <span class="Normal">else</span> + else Trace_stream<span class="Delimiter">-></span>dump_layer = 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="CommentedCode">//? cout << Trace_stream << ": " << Trace_stream->dump_layer << '\n'; //? 1</span> <span class="Identifier">break</span><span class="Delimiter">;</span> @@ -106,7 +155,7 @@ _STOP_TRACING<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"$stop-tracing"</span>] = _STOP_TRACING<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> _STOP_TRACING: <span class="Delimiter">{</span> +case _STOP_TRACING: <span class="Delimiter">{</span> Trace_stream<span class="Delimiter">-></span>dump_layer = <span class="Constant">""</span><span class="Delimiter">;</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -116,9 +165,9 @@ _CLOSE_TRACE<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"$close-trace"</span>] = _CLOSE_TRACE<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> _CLOSE_TRACE: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">delete</span> Trace_stream<span class="Delimiter">;</span> +case _CLOSE_TRACE: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Trace_stream<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="Identifier">break</span><span class="Delimiter">;</span> @@ -129,11 +178,11 @@ _DUMP_TRACE<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"$dump-trace"</span>] = _DUMP_TRACE<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> _DUMP_TRACE: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> +case _DUMP_TRACE: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> DUMP<span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> + else <span class="Delimiter">{</span> DUMP<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>name<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Identifier">break</span><span class="Delimiter">;</span> @@ -144,7 +193,7 @@ _CLEAR_TRACE<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"$clear-trace"</span>] = _CLEAR_TRACE<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> _CLEAR_TRACE: <span class="Delimiter">{</span> +case _CLEAR_TRACE: <span class="Delimiter">{</span> CLEAR_TRACE<span class="Delimiter">;</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -154,7 +203,7 @@ Recipe_ordinal[<span class="Constant">"$clear-trace"</span>] = _CLEAR_ <span class="Delimiter">:(scenario assert)</span> <span class="Special">% Hide_warnings = true; // '%' lines insert arbitrary C code into tests before calling 'run' with the lines below. Must be immediately after :(scenario) line.</span> recipe main [ - assert <span class="Constant">0</span><span class="Delimiter">,</span> [<span class="Normal">this</span> is an assert in mu] + assert <span class="Constant">0</span><span class="Delimiter">,</span> [this is an assert in mu] ] <span class="traceContains">+warn: this is an assert in mu</span> @@ -163,20 +212,20 @@ ASSERT<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"assert"</span>] = ASSERT<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> ASSERT: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case ASSERT: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'assert' takes exactly two ingredients rather than '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> + 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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'assert' requires a boolean for its first ingredient, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> <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> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'assert' requires a literal string for its second ingredient, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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="Delimiter">{</span> + if <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="Delimiter">{</span> raise << 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>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Identifier">break</span><span class="Delimiter">;</span> @@ -189,19 +238,19 @@ _PRINT<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"$print"</span>] = _PRINT<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> _PRINT: <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> - <span class="Normal">if</span> <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> +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 << end<span class="Delimiter">();</span> - <span class="Normal">if</span> <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> + 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> - <span class="Normal">else</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> - <span class="Normal">else</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> + 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> 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> << ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)</span> << end<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>j > <span class="Constant">0</span><span class="Delimiter">)</span> cout << <span class="Constant">" "</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>j > <span class="Constant">0</span><span class="Delimiter">)</span> cout << <span class="Constant">" "</span><span class="Delimiter">;</span> cout << ingredients<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="Delimiter">}</span> <span class="Delimiter">}</span> @@ -214,7 +263,7 @@ _EXIT<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"$exit"</span>] = _EXIT<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> _EXIT: <span class="Delimiter">{</span> +case _EXIT: <span class="Delimiter">{</span> exit<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -224,12 +273,12 @@ _SYSTEM<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"$system"</span>] = _SYSTEM<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> _SYSTEM: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> +case _SYSTEM: <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> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": '$system' requires exactly one ingredient, but got none</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">int</span> status = system<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>name<span class="Delimiter">.</span>c_str<span class="Delimiter">());</span> + int status = system<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>name<span class="Delimiter">.</span>c_str<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>status<span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> @@ -242,7 +291,7 @@ _DUMP_MEMORY<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"$dump-memory"</span>] = _DUMP_MEMORY<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> _DUMP_MEMORY: <span class="Delimiter">{</span> +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> diff --git a/html/030container.cc.html b/html/030container.cc.html index 42f162ab..827e6f74 100644 --- a/html/030container.cc.html +++ b/html/030container.cc.html @@ -13,17 +13,16 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } .SalientComment { color: #00ffff; } -.Constant { color: #00a0a0; } -.cSpecial { color: #008000; } .traceAbsent { color: #c00000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.CommentedCode { color: #6c6c6c; } +.cSpecial { color: #008000; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } -.CommentedCode { color: #6c6c6c; } +.Constant { color: #00a0a0; } +.traceContains { color: #008000; } --> </style> @@ -63,6 +62,14 @@ recipe main [ <span class="traceContains">+mem: storing 34 in location 3</span> <span class="traceContains">+mem: storing 35 in location 4</span> +<span class="Comment">//: trying to copy to a differently-sized destination will fail</span> +<span class="Delimiter">:(scenario copy_checks_size)</span> +<span class="Special">% Hide_warnings = true;</span> +recipe main [ + <span class="Constant">2</span>:point<span class="Special"> <- </span>copy <span class="Constant">1</span>:number +] +<span class="traceContains">+warn: main: size mismatch in storing to 2:point at '2:point <- copy 1:number'</span> + <span class="Delimiter">:(before "End Mu Types Initialization")</span> <span class="Comment">// A more complex container, containing another container as one of its</span> <span class="Comment">// elements.</span> @@ -101,7 +108,7 @@ recipe main [ ] <span class="traceContains">+mem: storing 1 in location 7</span> -<span class="Delimiter">:(scenario compare_multiple_locations2)</span> +<span class="Delimiter">:(scenario compare_multiple_locations_2)</span> recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> <span class="Comment"># first</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span> @@ -115,12 +122,12 @@ recipe main [ <span class="Delimiter">:(before "End size_of(types) Cases")</span> type_info t = Type[types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>]<span class="Delimiter">;</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>t<span class="Delimiter">.</span>kind == container<span class="Delimiter">)</span> <span class="Delimiter">{</span> +if <span class="Delimiter">(</span>t<span class="Delimiter">.</span>kind == container<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// size of a container is the sum of the sizes of its elements</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> result = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>t<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + long long int result = <span class="Constant">0</span><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>t<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// todo: strengthen assertion to disallow mutual type recursion</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == t<span class="Delimiter">.</span>elements<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="Delimiter">{</span> + if <span class="Delimiter">(</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == t<span class="Delimiter">.</span>elements<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="Delimiter">{</span> raise << <span class="Constant">"container "</span> << t<span class="Delimiter">.</span>name << <span class="Constant">" can't include itself as a member</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -129,6 +136,15 @@ type_info t = Type[types<span class="Delimiter">.</span>at<span class="Delimiter <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> +<span class="Delimiter">:(scenario stash_container)</span> +recipe main [ + <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> <span class="Comment"># first</span> + <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span> + <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">36</span> + stash [foo: ]<span class="Delimiter">,</span> <span class="Constant">1</span>:point-number/<span class="Special">raw</span> +] +<span class="traceContains">+app: foo: 34 35 36</span> + <span class="SalientComment">//:: To access elements of a container, use 'get'</span> <span class="Delimiter">:(scenario get)</span> recipe main [ @@ -143,34 +159,34 @@ GET<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"get"</span>] = GET<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> GET: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case GET: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'get' expects exactly 2 ingredients in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> reagent base = 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="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>base_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + long long int base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>base_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": tried to access location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - type_ordinal base_type = base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Type[base_type]<span class="Delimiter">.</span>kind != container<span class="Delimiter">)</span> <span class="Delimiter">{</span> - raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'get' should be a container, but got "</span> << base<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> || Type[base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>]<span class="Delimiter">.</span>kind != container<span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'get' should be a container, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> <span class="Delimiter">{</span> + type_ordinal base_type = base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</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><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": second ingredient of 'get' should have type 'offset', but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</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> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> src = base_address<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> + 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> + 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 << end<span class="Delimiter">();</span> - <span class="Normal">if</span> <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> + 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> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -212,7 +228,7 @@ recipe main [ ] <span class="traceContains">+warn: main: invalid offset 2 for point-number</span> -<span class="Delimiter">:(scenario get_out_of_bounds2)</span> +<span class="Delimiter">:(scenario get_out_of_bounds_2)</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> @@ -227,30 +243,30 @@ GET_ADDRESS<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"get-address"</span>] = GET_ADDRESS<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> GET_ADDRESS: <span class="Delimiter">{</span> +case GET_ADDRESS: <span class="Delimiter">{</span> reagent base = 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="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>base_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + long long int base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>base_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": tried to access location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - type_ordinal base_type = base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Type[base_type]<span class="Delimiter">.</span>kind != container<span class="Delimiter">)</span> <span class="Delimiter">{</span> - raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'get-address' should be a container, but got "</span> << base<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> || Type[base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>]<span class="Delimiter">.</span>kind != container<span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'get-address' should be a container, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> <span class="Delimiter">{</span> + type_ordinal base_type = base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</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><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": second ingredient of 'get-address' should have type 'offset', but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</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> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> - <span class="Normal">if</span> <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> + 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> + 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> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> result = base_address<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> + 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> <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> << result << end<span class="Delimiter">();</span> @@ -269,7 +285,7 @@ recipe main [ ] <span class="traceContains">+warn: invalid offset 2 for point-number</span> -<span class="Delimiter">:(scenario get_address_out_of_bounds2)</span> +<span class="Delimiter">:(scenario get_address_out_of_bounds_2)</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> @@ -284,8 +300,8 @@ recipe main [ <span class="Delimiter">:(scenarios load)</span> <span class="Delimiter">:(scenario container)</span> container foo [ - <span class="Normal">x</span>:number - <span class="Normal">y</span>:number + x:number + y:number ] <span class="traceContains">+parse: reading container foo</span> <span class="traceContains">+parse: element name: x</span> @@ -295,13 +311,13 @@ container foo [ <span class="Delimiter">:(scenario container_use_before_definition)</span> container foo [ - <span class="Normal">x</span>:number - <span class="Normal">y</span>:bar + x:number + y:bar ] container bar [ - <span class="Normal">x</span>:number - <span class="Normal">y</span>:number + x:number + y:number ] <span class="traceContains">+parse: reading container foo</span> <span class="traceContains">+parse: type number: 1000</span> @@ -313,19 +329,19 @@ container bar [ <span class="traceContains">+parse: type number: 1001</span> <span class="Delimiter">:(before "End Command Handlers")</span> -<span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>command == <span class="Constant">"container"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +else if <span class="Delimiter">(</span>command == <span class="Constant">"container"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> insert_container<span class="Delimiter">(</span>command<span class="Delimiter">,</span> container<span class="Delimiter">,</span> in<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> insert_container<span class="Delimiter">(</span><span class="Normal">const</span> string& command<span class="Delimiter">,</span> kind_of_type kind<span class="Delimiter">,</span> istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void insert_container<span class="Delimiter">(</span>const string& command<span class="Delimiter">,</span> kind_of_type kind<span class="Delimiter">,</span> istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span> string name = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span> trace<span class="Delimiter">(</span><span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">"reading "</span> << command << <span class="Constant">' '</span> << name << end<span class="Delimiter">();</span> <span class="CommentedCode">//? cout << name << '\n'; //? 2</span> <span class="CommentedCode">//? if (Type_ordinal.find(name) != Type_ordinal.end()) //? 1</span> <span class="CommentedCode">//? cerr << Type_ordinal[name] << '\n'; //? 1</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">.</span>find<span class="Delimiter">(</span>name<span class="Delimiter">)</span> == Type_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">()</span> + if <span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">.</span>find<span class="Delimiter">(</span>name<span class="Delimiter">)</span> == Type_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">()</span> || Type_ordinal[name] == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> Type_ordinal[name] = Next_type_ordinal++<span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -335,17 +351,19 @@ container bar [ recently_added_types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>Type_ordinal[name]<span class="Delimiter">);</span> t<span class="Delimiter">.</span>name = name<span class="Delimiter">;</span> t<span class="Delimiter">.</span>kind = kind<span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span> string element = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>element == <span class="Constant">"]"</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>element == <span class="Constant">"]"</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> istringstream inner<span class="Delimiter">(</span>element<span class="Delimiter">);</span> t<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>slurp_until<span class="Delimiter">(</span>inner<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">));</span> trace<span class="Delimiter">(</span><span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">" element name: "</span> << t<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>back<span class="Delimiter">()</span> << end<span class="Delimiter">();</span> vector<type_ordinal> types<span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>!inner<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + while <span class="Delimiter">(</span>!inner<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> string type_name = slurp_until<span class="Delimiter">(</span>inner<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">.</span>find<span class="Delimiter">(</span>type_name<span class="Delimiter">)</span> == Type_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">.</span>find<span class="Delimiter">(</span>type_name<span class="Delimiter">)</span> == Type_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">()</span> + <span class="Comment">// types can contain integers, like for array sizes</span> + && !is_integer<span class="Delimiter">(</span>type_name<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << type_name << " is " << Next_type_ordinal << '\n'; //? 1</span> Type_ordinal[type_name] = Next_type_ordinal++<span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -361,11 +379,11 @@ container bar [ <span class="Delimiter">:(scenarios run)</span> <span class="Delimiter">:(scenario container_define_twice)</span> container foo [ - <span class="Normal">x</span>:number + x:number ] container foo [ - <span class="Normal">y</span>:number + y:number ] recipe main [ @@ -383,7 +401,7 @@ vector<type_ordinal> recently_added_types<span class="Delimiter">;</span> <span class="Delimiter">:(before "End load_permanently")</span> <span class="Comment">//: for non-tests</span> recently_added_types<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> <span class="Delimiter">:(before "End Setup")</span> <span class="Comment">//: for tests</span> -<span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>recently_added_types<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <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>recently_added_types<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cout << "erasing " << Type[recently_added_types.at(i)].name << '\n'; //? 1</span> Type_ordinal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>Type[recently_added_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span>]<span class="Delimiter">.</span>name<span class="Delimiter">);</span> Type<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>recently_added_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> @@ -392,14 +410,14 @@ recently_added_types<span class="Delimiter">.</span>clear<span class="Delimiter" <span class="Comment">// delete recent type references</span> <span class="Comment">// can't rely on recently_added_types to cleanup Type_ordinal, because of deliberately misbehaving tests with references to undefined types</span> map<string<span class="Delimiter">,</span> type_ordinal>::iterator p = Type_ordinal<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> -<span class="Normal">while</span><span class="Delimiter">(</span>p != Type_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> +while<span class="Delimiter">(</span>p != Type_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> <span class="Comment">// save current item</span> string name = p<span class="Delimiter">-></span>first<span class="Delimiter">;</span> type_ordinal t = p<span class="Delimiter">-></span>second<span class="Delimiter">;</span> <span class="Comment">// increment iterator</span> ++p<span class="Delimiter">;</span> <span class="Comment">// now delete current item if necessary</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>t >= <span class="Constant">1000</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>t >= <span class="Constant">1000</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << "AAA " << name << " " << t << '\n'; //? 1</span> Type_ordinal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>name<span class="Delimiter">);</span> <span class="Delimiter">}</span> @@ -431,7 +449,7 @@ recipe main [ ] container bar [ - <span class="Normal">x</span>:number + x:number ] <span class="traceAbsent">-warn: unknown type: bar</span> $warn: <span class="Constant">0</span> @@ -440,22 +458,22 @@ $warn: <span class="Constant">0</span> Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_invalid_types<span class="Delimiter">);</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> check_invalid_types<span class="Delimiter">(</span><span class="Normal">const</span> recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> index = <span class="Constant">0</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">const</span> instruction& inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void check_invalid_types<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int index = <span class="Constant">0</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++index<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>index<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>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> check_invalid_types<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> <span class="Delimiter">}</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <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>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> check_invalid_types<span class="Delimiter">(</span>inst<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="Delimiter">}</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> check_invalid_types<span class="Delimiter">(</span><span class="Normal">const</span> reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Type<span class="Delimiter">.</span>find<span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> == Type<span class="Delimiter">.</span>end<span class="Delimiter">())</span> +void check_invalid_types<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">)</span> <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>r<span class="Delimiter">.</span>types<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>Type<span class="Delimiter">.</span>find<span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> == Type<span class="Delimiter">.</span>end<span class="Delimiter">())</span> raise << <span class="Constant">"unknown type: "</span> << r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> @@ -463,16 +481,16 @@ $warn: <span class="Constant">0</span> <span class="Delimiter">:(scenario container_unknown_field)</span> <span class="Special">% Hide_warnings = true;</span> container foo [ - <span class="Normal">x</span>:number - <span class="Normal">y</span>:bar + x:number + y:bar ] <span class="traceContains">+warn: unknown type for field y in foo</span> <span class="Delimiter">:(scenario read_container_with_bracket_in_comment)</span> container foo [ - <span class="Normal">x</span>:number + x:number <span class="Comment"># ']' in comment</span> - <span class="Normal">y</span>:number + y:number ] <span class="traceContains">+parse: reading container foo</span> <span class="traceContains">+parse: element name: x</span> @@ -484,14 +502,14 @@ container foo [ check_container_field_types<span class="Delimiter">();</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> check_container_field_types<span class="Delimiter">()</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>map<type_ordinal<span class="Delimiter">,</span> type_info>::iterator p = Type<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Type<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">const</span> type_info& info = p<span class="Delimiter">-></span>second<span class="Delimiter">;</span> +void check_container_field_types<span class="Delimiter">()</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>map<type_ordinal<span class="Delimiter">,</span> type_info>::iterator p = Type<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Type<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + const type_info& info = p<span class="Delimiter">-></span>second<span class="Delimiter">;</span> <span class="CommentedCode">//? cerr << "checking " << p->first << '\n'; //? 1</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<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="Normal">if</span> <span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<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">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Type<span class="Delimiter">.</span>find<span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span>j<span class="Delimiter">))</span> == Type<span class="Delimiter">.</span>end<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>info<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++i<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>info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<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">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>Type<span class="Delimiter">.</span>find<span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span>j<span class="Delimiter">))</span> == Type<span class="Delimiter">.</span>end<span class="Delimiter">())</span> raise << <span class="Constant">"unknown type for field "</span> << info<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> << <span class="Constant">" in "</span> << info<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> @@ -505,18 +523,18 @@ MERGE<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"merge"</span>] = MERGE<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> MERGE: <span class="Delimiter">{</span> +case MERGE: <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="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> + 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> + 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> 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>ingredients<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="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(scenario merge)</span> container foo [ - <span class="Normal">x</span>:number - <span class="Normal">y</span>:number + x:number + y:number ] recipe main [ @@ -528,9 +546,9 @@ recipe main [ <span class="SalientComment">//:: helpers</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> skip_bracket<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> string message<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void skip_bracket<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> string message<span class="Delimiter">)</span> <span class="Delimiter">{</span> skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">()</span> != <span class="Constant">'['</span><span class="Delimiter">)</span> + if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">()</span> != <span class="Constant">'['</span><span class="Delimiter">)</span> raise << message << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> </pre> diff --git a/html/031address.cc.html b/html/031address.cc.html index 47f238c8..38ea84f7 100644 --- a/html/031address.cc.html +++ b/html/031address.cc.html @@ -13,17 +13,16 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } +.SalientComment { color: #00ffff; } .traceAbsent { color: #c00000; } -.Constant { color: #00a0a0; } -.cSpecial { color: #008000; } .CommentedCode { color: #6c6c6c; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.cSpecial { color: #008000; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } -.SalientComment { color: #00ffff; } +.Constant { color: #00a0a0; } +.traceContains { color: #008000; } --> </style> @@ -61,11 +60,14 @@ recipe main [ <span class="Delimiter">:(before "long long int base = x.value" following "void write_memory(reagent x, vector<double> data)")</span> x = canonize<span class="Delimiter">(</span>x<span class="Delimiter">);</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << <span class="Constant">"can't write to location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> +<span class="Delimiter">:(after "bool is_mu_array(reagent r)")</span> +r = canonize<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">//: writes to address 0 always loudly fail</span> <span class="Delimiter">:(scenario store_to_0_warns)</span> <span class="Special">% Hide_warnings = true;</span> @@ -78,25 +80,25 @@ recipe main [ <span class="Delimiter">:(code)</span> reagent canonize<span class="Delimiter">(</span>reagent x<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> x<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> x<span class="Delimiter">;</span> <span class="CommentedCode">//? cout << "canonize\n"; //? 1</span> reagent r = x<span class="Delimiter">;</span> <span class="CommentedCode">//? cout << x.to_string() << " => " << r.to_string() << '\n'; //? 1</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">"lookup"</span><span class="Delimiter">))</span> + while <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">"lookup"</span><span class="Delimiter">))</span> r = lookup_memory<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Identifier">return</span> r<span class="Delimiter">;</span> <span class="Delimiter">}</span> reagent lookup_memory<span class="Delimiter">(</span>reagent x<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cout << "lookup_memory: " << x.to_string() << "\n"; //? 2</span> - <span class="Normal">static</span> <span class="Normal">const</span> type_ordinal ADDRESS = Type_ordinal[<span class="Constant">"address"</span>]<span class="Delimiter">;</span> + static const type_ordinal ADDRESS = Type_ordinal[<span class="Constant">"address"</span>]<span class="Delimiter">;</span> reagent result<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> != ADDRESS<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> || x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> != ADDRESS<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": tried to /lookup "</span> << x<span class="Delimiter">.</span>original_string << <span class="Constant">" but it isn't an address</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">// compute value</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": tried to /lookup 0</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -107,14 +109,14 @@ reagent lookup_memory<span class="Delimiter">(</span>reagent x<span class="Delim copy<span class="Delimiter">(</span>++x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> inserter<span class="Delimiter">(</span>result<span class="Delimiter">.</span>types<span class="Delimiter">,</span> result<span class="Delimiter">.</span>types<span class="Delimiter">.</span>begin<span class="Delimiter">()));</span> <span class="Comment">// drop-one 'lookup'</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> len = SIZE<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">);</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>i = <span class="Constant">0</span><span class="Delimiter">;</span> i < len<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>first == <span class="Constant">"lookup"</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> + long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> + long long int len = SIZE<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">);</span> + for <span class="Delimiter">(</span>i = <span class="Constant">0</span><span class="Delimiter">;</span> i < len<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>first == <span class="Constant">"lookup"</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> result<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> <span class="Delimiter">}</span> ++i<span class="Delimiter">;</span> <span class="Comment">// skip first lookup</span> - <span class="Normal">for</span> <span class="Delimiter">(;</span> i < len<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(;</span> i < len<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> result<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> <span class="Delimiter">}</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> @@ -167,11 +169,11 @@ recipe main [ <span class="Delimiter">:(before "End Parsing reagent")</span> <span class="Delimiter">{</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>!name<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && name<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">'*'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + while <span class="Delimiter">(</span>!name<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && name<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">'*'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> name<span class="Delimiter">.</span>erase<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> vector<string> ><span class="Delimiter">(</span><span class="Constant">"lookup"</span><span class="Delimiter">,</span> vector<string><span class="Delimiter">()));</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>name<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> + if <span class="Delimiter">(</span>name<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> raise << <span class="Constant">"illegal name "</span> << original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> @@ -182,7 +184,7 @@ _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> -<span class="Normal">case</span> _DUMP: <span class="Delimiter">{</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> @@ -191,18 +193,18 @@ Recipe_ordinal[<span class="Constant">"$dump"</span>] = _DUMP<span cla <span class="Comment">//: grab an address, and then dump its value at intervals</span> <span class="Comment">//: useful for tracking down memory corruption (writing to an out-of-bounds address)</span> <span class="Delimiter">:(before "End Globals")</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> foo = -<span class="Constant">1</span><span class="Delimiter">;</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> -<span class="Normal">case</span> _FOO: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <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> - <span class="Normal">else</span> cerr << <span class="cSpecial">'\n'</span><span class="Delimiter">;</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> - <span class="Normal">else</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> diff --git a/html/032array.cc.html b/html/032array.cc.html index 7332dd0c..08097e7b 100644 --- a/html/032array.cc.html +++ b/html/032array.cc.html @@ -13,15 +13,14 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } .SalientComment { color: #00ffff; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } +.traceContains { color: #008000; } --> </style> @@ -40,18 +39,67 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment">//: elements of a fixed size, so you can't create containers containing arrays.</span> <span class="Comment">//: Create containers containing addresses to arrays instead.</span> -<span class="Comment">//: Tests in this layer often explicitly setup memory before reading it as an</span> -<span class="Comment">//: array. Don't do this in general. I'm tagging exceptions with /raw to</span> -<span class="Comment">//: avoid warnings.</span> +<span class="Comment">//: You can create arrays using 'create-array'.</span> +<span class="Delimiter">:(scenario create_array)</span> +recipe main [ + <span class="Comment"># create an array occupying locations 1 (for the size) and 2-4 (for the elements)</span> + <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> <- </span>create-array +] +<span class="traceContains">+run: creating array of size 4</span> + +<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> +CREATE_ARRAY<span class="Delimiter">,</span> +<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> +Recipe_ordinal[<span class="Constant">"create-array"</span>] = CREATE_ARRAY<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> +case CREATE_ARRAY: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> + raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": 'create-array' needs one product and no ingredients but got '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + reagent product = canonize<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> + if <span class="Delimiter">(</span>!is_mu_array<span class="Delimiter">(</span>product<span class="Delimiter">))</span> <span class="Delimiter">{</span> + raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": 'create-array' cannot create non-array "</span> << product<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + long long int base_address = product<span class="Delimiter">.</span>value<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>product<span class="Delimiter">.</span>types<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": create array of what? "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Comment">// 'create-array' will need to check properties rather than types</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>product<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">)</span> <= <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": create array of what size? "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + if <span class="Delimiter">(</span>!is_integer<span class="Delimiter">(</span>product<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> + raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": 'create-array' product should specify size of array after its element type, but got "</span> << product<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + long long int array_size= to_integer<span class="Delimiter">(</span>product<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">));</span> + <span class="Comment">// initialize array size, so that size_of will work</span> + Memory[base_address] = array_size<span class="Delimiter">;</span> <span class="Comment">// in array elements</span> + long long int size = size_of<span class="Delimiter">(</span>product<span class="Delimiter">);</span> <span class="Comment">// in locations</span> + trace<span class="Delimiter">(</span><span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"creating array of size "</span> << size << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Comment">// initialize array</span> + for <span class="Delimiter">(</span>long long int i = <span class="Constant">1</span><span class="Delimiter">;</span> i <= size_of<span class="Delimiter">(</span>product<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + Memory[base_address+i] = <span class="Constant">0</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Comment">// dummy product; doesn't actually do anything</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>array_size<span class="Delimiter">);</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> + <span class="Delimiter">:(scenario copy_array)</span> <span class="Comment"># Arrays can be copied around with a single instruction just like numbers,</span> <span class="Comment"># no matter how large they are.</span> recipe main [ - <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">3</span> <span class="Comment"># length</span> + <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> <- </span>create-array <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span> - <span class="Constant">5</span>:array:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:array:number/<span class="Special">raw</span> <span class="Comment"># unsafe</span> + <span class="Constant">5</span>:array:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:array:number:<span class="Constant">3</span> ] <span class="traceContains">+mem: storing 3 in location 5</span> <span class="traceContains">+mem: storing 14 in location 6</span> @@ -60,11 +108,11 @@ recipe main [ <span class="Delimiter">:(scenario copy_array_indirect)</span> recipe main [ - <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">3</span> <span class="Comment"># length</span> + <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> <- </span>create-array <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span> - <span class="Constant">5</span>:address:array:number<span class="Special"> <- </span>copy <span class="Constant">1</span> + <span class="Constant">5</span>:address:array:number<span class="Special"> <- </span>copy <span class="Constant">1</span> <span class="Comment"># unsafe</span> <span class="Constant">6</span>:array:number<span class="Special"> <- </span>copy *<span class="Constant">5</span>:address:array:number ] <span class="traceContains">+mem: storing 3 in location 6</span> @@ -72,39 +120,49 @@ recipe main [ <span class="traceContains">+mem: storing 15 in location 8</span> <span class="traceContains">+mem: storing 16 in location 9</span> +<span class="Delimiter">:(scenario stash_array)</span> +recipe main [ + <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> <- </span>create-array + <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span> + <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span> + <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span> + stash [foo: ]<span class="Delimiter">,</span> <span class="Constant">1</span>:array:number:<span class="Constant">3</span> +] +<span class="traceContains">+app: foo: 3 14 15 16</span> + <span class="Comment">//: disable the size mismatch check since the destination array need not be initialized</span> <span class="Delimiter">:(before "End size_mismatch(x) Cases")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>x<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">"array"</span>]<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> +if <span class="Delimiter">(</span>x<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">"array"</span>]<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End size_of(reagent) Cases")</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>r<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">"array"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": '"</span> << r<span class="Delimiter">.</span>original_string << <span class="Constant">"' is an array of what?</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> - <span class="Identifier">return</span> <span class="Constant">1</span><span class="Delimiter">;</span> - <span class="Delimiter">}</span> - <span class="Comment">// skip the 'array' type to get at the element type</span> - <span class="Identifier">return</span> <span class="Constant">1</span> + Memory[r<span class="Delimiter">.</span>value]*size_of<span class="Delimiter">(</span>array_element<span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">));</span> +if <span class="Delimiter">(</span>r<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">"array"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": '"</span> << r<span class="Delimiter">.</span>original_string << <span class="Constant">"' is an array of what?</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">return</span> <span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> + <span class="Comment">// skip the 'array' type to get at the element type</span> + <span class="Identifier">return</span> <span class="Constant">1</span> + Memory[r<span class="Delimiter">.</span>value]*size_of<span class="Delimiter">(</span>array_element<span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">));</span> +<span class="Delimiter">}</span> <span class="SalientComment">//:: To access elements of an array, use 'index'</span> <span class="Delimiter">:(scenario index)</span> recipe main [ - <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">3</span> <span class="Comment"># length</span> + <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> <- </span>create-array <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span> - <span class="Constant">5</span>:number<span class="Special"> <- </span>index <span class="Constant">1</span>:array:number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">0</span> <span class="Comment"># unsafe</span> + <span class="Constant">5</span>:number<span class="Special"> <- </span>index <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">0</span> ] <span class="traceContains">+mem: storing 14 in location 5</span> <span class="Delimiter">:(scenario index_direct_offset)</span> recipe main [ - <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">3</span> <span class="Comment"># length</span> + <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> <- </span>create-array <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span> <span class="Constant">5</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> - <span class="Constant">6</span>:number<span class="Special"> <- </span>index <span class="Constant">1</span>:array:number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">5</span>:number <span class="Comment"># unsafe</span> + <span class="Constant">6</span>:number<span class="Special"> <- </span>index <span class="Constant">1</span>:array:number<span class="Delimiter">,</span> <span class="Constant">5</span>:number ] <span class="traceContains">+mem: storing 14 in location 6</span> @@ -113,29 +171,29 @@ INDEX<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"index"</span>] = INDEX<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> INDEX: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case INDEX: <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">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'index' expects exactly 2 ingredients in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> reagent base = 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> - <span class="Normal">if</span> <span class="Delimiter">(</span>base<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">"array"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!is_mu_array<span class="Delimiter">(</span>base<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": 'index' on a non-array "</span> << base<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>base_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + long long int base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>base_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": tried to access location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <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<<span class="Normal">double</span>> offset_val<span class="Delimiter">(</span>read_memory<span class="Delimiter">(</span>offset<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> - <span class="Normal">if</span> <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> + 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> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> + 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 << end<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 << end<span class="Delimiter">();</span> reagent tmp<span class="Delimiter">;</span> @@ -146,13 +204,13 @@ Recipe_ordinal[<span class="Constant">"index"</span>] = INDEX<span cla <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -vector<type_ordinal> array_element<span class="Delimiter">(</span><span class="Normal">const</span> vector<type_ordinal>& types<span class="Delimiter">)</span> <span class="Delimiter">{</span> +vector<type_ordinal> array_element<span class="Delimiter">(</span>const vector<type_ordinal>& types<span class="Delimiter">)</span> <span class="Delimiter">{</span> <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_indirect)</span> recipe main [ - <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">3</span> <span class="Comment"># length</span> + <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> <- </span>create-array <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span> @@ -164,7 +222,7 @@ recipe main [ <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> <span class="Comment"># 3 points</span> + <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> <- </span>create-array <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span> @@ -176,10 +234,10 @@ recipe main [ ] <span class="traceContains">+warn: main: invalid index 4</span> -<span class="Delimiter">:(scenario index_out_of_bounds2)</span> +<span class="Delimiter">:(scenario index_out_of_bounds_2)</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> <span class="Comment"># 3 points</span> + <span class="Constant">1</span>:array:point:<span class="Constant">3</span><span class="Special"> <- </span>create-array <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span> @@ -195,11 +253,11 @@ recipe main [ <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> <span class="Comment"># length</span> + <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> <- </span>create-array <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span> - <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> <span class="Comment"># unsafe</span> + <span class="Constant">5</span>:number<span class="Special"> <- </span>index-address <span class="Constant">1</span>:array:number<span class="Delimiter">,</span> <span class="Constant">0</span> ] <span class="traceContains">+mem: storing 2 in location 5</span> @@ -208,29 +266,29 @@ INDEX_ADDRESS<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"index-address"</span>] = INDEX_ADDRESS<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> INDEX_ADDRESS: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case INDEX_ADDRESS: <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">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'index-address' expects exactly 2 ingredients in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> reagent base = 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> - <span class="Normal">if</span> <span class="Delimiter">(</span>base<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">"array"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!is_mu_array<span class="Delimiter">(</span>base<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": 'index-address' on a non-array "</span> << base<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>base_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + long long int base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>base_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": tried to access location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <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<<span class="Normal">double</span>> offset_val<span class="Delimiter">(</span>read_memory<span class="Delimiter">(</span>offset<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> - <span class="Normal">if</span> <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> + 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> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> + 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> @@ -239,29 +297,29 @@ Recipe_ordinal[<span class="Constant">"index-address"</span>] = INDEX_ <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> <span class="Comment"># 3 points</span> + <span class="Constant">1</span>:array:point:<span class="Constant">3</span><span class="Special"> <- </span>create-array <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span> <span class="Constant">5</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span> <span class="Constant">6</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span> <span class="Constant">7</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span> - <span class="Constant">8</span>:address:array:point<span class="Special"> <- </span>copy <span class="Constant">1</span> + <span class="Constant">8</span>:address:array:point<span class="Special"> <- </span>copy <span class="Constant">1</span> <span class="Comment"># unsafe</span> index-address *<span class="Constant">8</span>:address:array:point<span class="Delimiter">,</span> <span class="Constant">4</span> <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="Delimiter">:(scenario index_address_out_of_bounds_2)</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> <span class="Comment"># 3 points</span> + <span class="Constant">1</span>:array:point:<span class="Constant">3</span><span class="Special"> <- </span>create-array <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span> <span class="Constant">5</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span> <span class="Constant">6</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span> <span class="Constant">7</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span> - <span class="Constant">8</span>:address:array:point<span class="Special"> <- </span>copy <span class="Constant">1</span> + <span class="Constant">8</span>:address:array:point<span class="Special"> <- </span>copy <span class="Constant">1</span> <span class="Comment"># unsafe</span> index-address *<span class="Constant">8</span>:address:array:point<span class="Delimiter">,</span> -<span class="Constant">1</span> ] <span class="traceContains">+warn: main: invalid index -1</span> @@ -270,11 +328,11 @@ recipe main [ <span class="Delimiter">:(scenario array_length)</span> recipe main [ - <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">3</span> <span class="Comment"># length</span> + <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> <- </span>create-array <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span> <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span> <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span> - <span class="Constant">5</span>:number<span class="Special"> <- </span>length <span class="Constant">1</span>:array:number/<span class="Special">raw</span> <span class="Comment"># unsafe</span> + <span class="Constant">5</span>:number<span class="Special"> <- </span>length <span class="Constant">1</span>:array:number:<span class="Constant">3</span> ] <span class="traceContains">+mem: storing 3 in location 5</span> @@ -283,17 +341,17 @@ LENGTH<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"length"</span>] = LENGTH<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> LENGTH: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case LENGTH: <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> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'length' expects exactly 2 ingredients in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> reagent x = 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> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<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">"array"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!is_mu_array<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise << <span class="Constant">"tried to calculate length of non-array "</span> << x<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": tried to access location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -301,6 +359,13 @@ Recipe_ordinal[<span class="Constant">"length"</span>] = LENGTH<span c 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>Memory[x<span class="Delimiter">.</span>value]<span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> + +<span class="Comment">//: optimization: none of the instructions in this layer use 'ingredients' so</span> +<span class="Comment">//: stop copying potentially huge arrays into it.</span> +<span class="Delimiter">:(before "End should_copy_ingredients Special-cases")</span> +recipe_ordinal r = current_instruction<span class="Delimiter">().</span>operation<span class="Delimiter">;</span> +if <span class="Delimiter">(</span>r == CREATE_ARRAY || r == INDEX || r == INDEX_ADDRESS || r == LENGTH<span class="Delimiter">)</span> + <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> </pre> </body> </html> diff --git a/html/033exclusive_container.cc.html b/html/033exclusive_container.cc.html index 798b38b5..b2a35106 100644 --- a/html/033exclusive_container.cc.html +++ b/html/033exclusive_container.cc.html @@ -13,15 +13,14 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.SalientComment { color: #00ffff; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.SalientComment { color: #00ffff; } +.traceContains { color: #008000; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } --> </style> @@ -65,20 +64,20 @@ recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span> <span class="Comment"># 'point' variant</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span> - <span class="Constant">4</span>:number-<span class="Normal">or</span>-point<span class="Special"> <- </span>copy <span class="Constant">1</span>:number-<span class="Normal">or</span>-point/<span class="Special">raw</span> <span class="Comment"># unsafe</span> + <span class="Constant">4</span>:number-or-point<span class="Special"> <- </span>copy <span class="Constant">1</span>:number-or-point/<span class="Special">raw</span> <span class="Comment"># unsafe</span> ] <span class="traceContains">+mem: storing 1 in location 4</span> <span class="traceContains">+mem: storing 34 in location 5</span> <span class="traceContains">+mem: storing 35 in location 6</span> <span class="Delimiter">:(before "End size_of(types) Cases")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>t<span class="Delimiter">.</span>kind == exclusive_container<span class="Delimiter">)</span> <span class="Delimiter">{</span> +if <span class="Delimiter">(</span>t<span class="Delimiter">.</span>kind == exclusive_container<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// size of an exclusive container is the size of its largest variant</span> <span class="Comment">// (So like containers, it can't contain arrays.)</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> result = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < t<span class="Delimiter">.</span>size<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> tmp = size_of<span class="Delimiter">(</span>t<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>tmp > result<span class="Delimiter">)</span> result = tmp<span class="Delimiter">;</span> + long long int result = <span class="Constant">0</span><span class="Delimiter">;</span> + for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < t<span class="Delimiter">.</span>size<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + long long int tmp = size_of<span class="Delimiter">(</span>t<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> + if <span class="Delimiter">(</span>tmp > result<span class="Delimiter">)</span> result = tmp<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">// ...+1 for its tag.</span> <span class="Identifier">return</span> result+<span class="Constant">1</span><span class="Delimiter">;</span> @@ -99,7 +98,7 @@ recipe main [ <span class="Constant">12</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span> <span class="Constant">13</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span> <span class="Constant">14</span>:number<span class="Special"> <- </span>copy <span class="Constant">36</span> - <span class="Constant">20</span>:address:point<span class="Special"> <- </span>maybe-convert <span class="Constant">12</span>:number-<span class="Normal">or</span>-point/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">1</span>:variant <span class="Comment"># unsafe</span> + <span class="Constant">20</span>:address:point<span class="Special"> <- </span>maybe-convert <span class="Constant">12</span>:number-or-point/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">1</span>:variant <span class="Comment"># unsafe</span> ] <span class="traceContains">+mem: storing 13 in location 20</span> @@ -108,7 +107,7 @@ recipe main [ <span class="Constant">12</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span> <span class="Constant">13</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span> <span class="Constant">14</span>:number<span class="Special"> <- </span>copy <span class="Constant">36</span> - <span class="Constant">20</span>:address:point<span class="Special"> <- </span>maybe-convert <span class="Constant">12</span>:number-<span class="Normal">or</span>-point/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">0</span>:variant <span class="Comment"># unsafe</span> + <span class="Constant">20</span>:address:point<span class="Special"> <- </span>maybe-convert <span class="Constant">12</span>:number-or-point/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">0</span>:variant <span class="Comment"># unsafe</span> ] <span class="traceContains">+mem: storing 0 in location 20</span> @@ -117,32 +116,31 @@ MAYBE_CONVERT<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"maybe-convert"</span>] = MAYBE_CONVERT<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> MAYBE_CONVERT: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case MAYBE_CONVERT: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'maybe-convert' expects exactly 2 ingredients in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> reagent base = 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> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>base_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + long long int base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>base_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": tried to access location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - type_ordinal base_type = base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Type[base_type]<span class="Delimiter">.</span>kind != exclusive_container<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> || Type[base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>]<span class="Delimiter">.</span>kind != exclusive_container<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'maybe-convert' should be an exclusive-container, but got "</span> << base<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> <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">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": second ingredient of 'maybe-convert' should have type 'variant', but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> tag = 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>value<span class="Delimiter">;</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> result<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>tag == <span class="Normal">static_cast</span><<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>><span class="Delimiter">(</span>Memory[base_address]<span class="Delimiter">))</span> <span class="Delimiter">{</span> + long long int tag = 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>value<span class="Delimiter">;</span> + long long int result<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>tag == static_cast<long long int><span class="Delimiter">(</span>Memory[base_address]<span class="Delimiter">))</span> <span class="Delimiter">{</span> result = base_address+<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> + else <span class="Delimiter">{</span> result = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> @@ -154,8 +152,8 @@ Recipe_ordinal[<span class="Constant">"maybe-convert"</span>] = MAYBE_ <span class="Delimiter">:(scenario exclusive_container)</span> exclusive-container foo [ - <span class="Normal">x</span>:number - <span class="Normal">y</span>:number + x:number + y:number ] <span class="traceContains">+parse: reading exclusive-container foo</span> <span class="traceContains">+parse: element name: x</span> @@ -164,15 +162,15 @@ exclusive-container foo [ <span class="traceContains">+parse: type: 1</span> <span class="Delimiter">:(before "End Command Handlers")</span> -<span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>command == <span class="Constant">"exclusive-container"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +else if <span class="Delimiter">(</span>command == <span class="Constant">"exclusive-container"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> insert_container<span class="Delimiter">(</span>command<span class="Delimiter">,</span> exclusive_container<span class="Delimiter">,</span> in<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="SalientComment">//:: To construct exclusive containers out of variant types, use 'merge'.</span> <span class="Delimiter">:(scenario lift_to_exclusive_container)</span> exclusive-container foo [ - <span class="Normal">x</span>:number - <span class="Normal">y</span>:number + x:number + y:number ] recipe main [ diff --git a/html/034call.cc.html b/html/034call.cc.html index 45f04cf7..dd892686 100644 --- a/html/034call.cc.html +++ b/html/034call.cc.html @@ -13,17 +13,16 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } +.PreProc { color: #c000c0; } .SalientComment { color: #00ffff; } -.Constant { color: #00a0a0; } +.CommentedCode { color: #6c6c6c; } .cSpecial { color: #008000; } -.PreProc { color: #c000c0; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } -.CommentedCode { color: #6c6c6c; } +.Constant { color: #00a0a0; } +.traceContains { color: #008000; } --> </style> @@ -70,9 +69,9 @@ recipe f [ <span class="Comment">// Everytime a recipe runs another, we interrupt it and start running the new</span> <span class="Comment">// recipe. When that finishes, we continue this one where we left off.</span> <span class="Comment">// This requires maintaining a 'stack' of interrupted recipes or 'calls'.</span> -<span class="Normal">struct</span> call <span class="Delimiter">{</span> +struct call <span class="Delimiter">{</span> recipe_ordinal running_recipe<span class="Delimiter">;</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> running_step_index<span class="Delimiter">;</span> + long long int running_step_index<span class="Delimiter">;</span> <span class="Comment">// End call Fields</span> call<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> running_recipe = r<span class="Delimiter">;</span> @@ -80,15 +79,15 @@ recipe f [ <span class="Comment">// End call Constructor</span> <span class="Delimiter">}</span> <span class="Delimiter">};</span> -<span class="Normal">typedef</span> list<call> call_stack<span class="Delimiter">;</span> +typedef list<call> call_stack<span class="Delimiter">;</span> <span class="Delimiter">:(replace{} "struct routine")</span> -<span class="Normal">struct</span> routine <span class="Delimiter">{</span> +struct routine <span class="Delimiter">{</span> call_stack calls<span class="Delimiter">;</span> <span class="Comment">// End routine Fields</span> routine<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">);</span> - <span class="Normal">bool</span> completed<span class="Delimiter">()</span> <span class="Normal">const</span><span class="Delimiter">;</span> - <span class="Normal">const</span> vector<instruction>& steps<span class="Delimiter">()</span> <span class="Normal">const</span><span class="Delimiter">;</span> + bool completed<span class="Delimiter">()</span> const<span class="Delimiter">;</span> + const vector<instruction>& steps<span class="Delimiter">()</span> const<span class="Delimiter">;</span> <span class="Delimiter">};</span> <span class="Delimiter">:(code)</span> routine::routine<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -99,32 +98,32 @@ routine::routine<span class="Delimiter">(</span>recipe_ordinal r<span class="Del <span class="SalientComment">//:: now update routine's helpers</span> <span class="Delimiter">:(replace{} "inline long long int& current_step_index()")</span> -<span class="Normal">inline</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>& current_step_index<span class="Delimiter">()</span> <span class="Delimiter">{</span> +inline long long int& current_step_index<span class="Delimiter">()</span> <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>!Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> <span class="Identifier">return</span> Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_step_index<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(replace{} "inline const string& current_recipe_name()")</span> -<span class="Normal">inline</span> <span class="Normal">const</span> string& current_recipe_name<span class="Delimiter">()</span> <span class="Delimiter">{</span> +inline const string& current_recipe_name<span class="Delimiter">()</span> <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>!Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> <span class="Identifier">return</span> Recipe[Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_recipe]<span class="Delimiter">.</span>name<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(replace{} "inline const instruction& current_instruction()")</span> -<span class="Normal">inline</span> <span class="Normal">const</span> instruction& current_instruction<span class="Delimiter">()</span> <span class="Delimiter">{</span> +inline const instruction& current_instruction<span class="Delimiter">()</span> <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>!Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> <span class="Identifier">return</span> Recipe[Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_recipe]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_step_index<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">:(replace{} "default:" following "End Primitive Recipe Implementations")</span> -<span class="Normal">default</span>: <span class="Delimiter">{</span> +default: <span class="Delimiter">{</span> <span class="Comment">// not a primitive; try to look up the book of recipes</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Recipe<span class="Delimiter">.</span>find<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>operation<span class="Delimiter">)</span> == Recipe<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Recipe<span class="Delimiter">.</span>find<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>operation<span class="Delimiter">)</span> == Recipe<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": undefined operation in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Comment">// stop running this instruction immediately</span> ++current_step_index<span class="Delimiter">();</span> <span class="Identifier">continue</span><span class="Delimiter">;</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>current_instruction<span class="Delimiter">().</span>operation<span class="Delimiter">));</span> - <span class="Normal">call_housekeeping</span>: + call_housekeeping: ++Callstack_depth<span class="Delimiter">;</span> assert<span class="Delimiter">(</span>Callstack_depth < <span class="Constant">9000</span><span class="Delimiter">);</span> <span class="Comment">// 9998-101 plus cushion</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Comment">// not done with caller; don't increment current_step_index()</span> @@ -140,18 +139,18 @@ recipe main [ <span class="Delimiter">:(scenario calling_undefined_recipe_handles_missing_result)</span> <span class="Special">% Hide_warnings = true;</span> recipe main [ - <span class="Normal">x</span>:number<span class="Special"> <- </span>foo + x:number<span class="Special"> <- </span>foo ] <span class="traceContains">+warn: main: undefined operation in 'x:number <- foo '</span> <span class="SalientComment">//:: finally, we need to fix the termination conditions for the run loop</span> <span class="Delimiter">:(replace{} "inline bool routine::completed() const")</span> -<span class="Normal">inline</span> <span class="Normal">bool</span> routine::completed<span class="Delimiter">()</span> <span class="Normal">const</span> <span class="Delimiter">{</span> +inline bool routine::completed<span class="Delimiter">()</span> const <span class="Delimiter">{</span> <span class="Identifier">return</span> calls<span class="Delimiter">.</span>empty<span class="Delimiter">();</span> <span class="Delimiter">}</span> -<span class="Normal">inline</span> <span class="Normal">const</span> vector<instruction>& routine::steps<span class="Delimiter">()</span> <span class="Normal">const</span> <span class="Delimiter">{</span> +inline const vector<instruction>& routine::steps<span class="Delimiter">()</span> const <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>!calls<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> <span class="Identifier">return</span> Recipe[calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_recipe]<span class="Delimiter">.</span>steps<span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -159,12 +158,12 @@ recipe main [ <span class="Delimiter">:(before "Running One Instruction")</span> <span class="Comment">// when we reach the end of one call, we may reach the end of the one below</span> <span class="Comment">// it, and the one below that, and so on</span> -<span class="Normal">while</span> <span class="Delimiter">(</span>current_step_index<span class="Delimiter">()</span> >= SIZE<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>steps<span class="Delimiter">()))</span> <span class="Delimiter">{</span> +while <span class="Delimiter">(</span>current_step_index<span class="Delimiter">()</span> >= SIZE<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>steps<span class="Delimiter">()))</span> <span class="Delimiter">{</span> <span class="Comment">// Falling Through End Of Recipe</span> --Callstack_depth<span class="Delimiter">;</span> <span class="CommentedCode">//? cerr << "reply " << SIZE(Current_routine->calls) << '\n'; //? 2</span> Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>pop_front<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// Complete Call Fallthrough</span> <span class="Comment">// todo: no products returned warning</span> ++current_step_index<span class="Delimiter">();</span> @@ -172,7 +171,7 @@ recipe main [ <span class="Delimiter">:(before "End Includes")</span> <span class="PreProc">#include </span><span class="Constant"><stack></span> -<span class="Normal">using</span> std::stack<span class="Delimiter">;</span> +using std::stack<span class="Delimiter">;</span> </pre> </body> </html> diff --git a/html/035call_ingredient.cc.html b/html/035call_ingredient.cc.html index c536c026..517cf646 100644 --- a/html/035call_ingredient.cc.html +++ b/html/035call_ingredient.cc.html @@ -13,14 +13,13 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } +.traceContains { color: #008000; } --> </style> @@ -55,13 +54,13 @@ recipe f [ <span class="traceContains">+mem: storing 0 in location 12</span> <span class="Delimiter">:(before "End call Fields")</span> -vector<vector<<span class="Normal">double</span>> > ingredient_atoms<span class="Delimiter">;</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> next_ingredient_to_process<span class="Delimiter">;</span> +vector<vector<double> > ingredient_atoms<span class="Delimiter">;</span> +long long int next_ingredient_to_process<span class="Delimiter">;</span> <span class="Delimiter">:(before "End call Constructor")</span> next_ingredient_to_process = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">:(after "call_housekeeping:")</span> -<span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> +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> Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> <span class="Delimiter">}</span> @@ -70,20 +69,20 @@ NEXT_INGREDIENT<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"next-ingredient"</span>] = NEXT_INGREDIENT<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> NEXT_INGREDIENT: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> +case NEXT_INGREDIENT: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'next-ingredient' didn't expect any ingredients in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> assert<span class="Delimiter">(</span>!Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>next_ingredient_to_process < SIZE<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">))</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>next_ingredient_to_process < SIZE<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">))</span> <span class="Delimiter">{</span> products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span> Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>at<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">));</span> assert<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>products<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">);</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">);</span> <span class="Comment">// push a new vector</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><span class="Constant">1</span><span class="Delimiter">);</span> ++Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> + else <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>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> <span class="Comment">// todo: will fail noisily if we try to read a compound value</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><span class="Constant">0</span><span class="Delimiter">);</span> @@ -111,7 +110,7 @@ REWIND_INGREDIENTS<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"rewind-ingredients"</span>] = REWIND_INGREDIENTS<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> REWIND_INGREDIENTS: <span class="Delimiter">{</span> +case REWIND_INGREDIENTS: <span class="Delimiter">{</span> Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>next_ingredient_to_process = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -132,17 +131,17 @@ INGREDIENT<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"ingredient"</span>] = INGREDIENT<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> INGREDIENT: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case INGREDIENT: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'ingredient' expects exactly one ingredient, but got '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> + 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> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'ingredient' expects a literal ingredient, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</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">0</span><span class="Delimiter">)));</span> - <span class="Normal">if</span> <span class="Delimiter">(</span><span class="Normal">static_cast</span><<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>><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> < SIZE<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">))</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>static_cast<long long int><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> < SIZE<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">))</span> <span class="Delimiter">{</span> Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>next_ingredient_to_process = 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> products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span> Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>at<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">));</span> @@ -150,8 +149,8 @@ Recipe_ordinal[<span class="Constant">"ingredient"</span>] = INGREDIEN 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><span class="Constant">1</span><span class="Delimiter">);</span> ++Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + else <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">1</span><span class="Delimiter">)</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>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> <span class="Comment">// todo: will fail noisily if we try to read a compound value</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><span class="Constant">0</span><span class="Delimiter">);</span> diff --git a/html/036call_reply.cc.html b/html/036call_reply.cc.html index d1056a3a..bdc9cb07 100644 --- a/html/036call_reply.cc.html +++ b/html/036call_reply.cc.html @@ -13,14 +13,13 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } +.traceContains { color: #008000; } --> </style> @@ -51,38 +50,38 @@ REPLY<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"reply"</span>] = REPLY<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> REPLY: <span class="Delimiter">{</span> +case REPLY: <span class="Delimiter">{</span> <span class="Comment">// Starting Reply</span> - <span class="Normal">const</span> instruction& reply_inst = current_instruction<span class="Delimiter">();</span> <span class="Comment">// save pointer into recipe before pop</span> - <span class="Normal">const</span> string& callee = current_recipe_name<span class="Delimiter">();</span> + const instruction& reply_inst = current_instruction<span class="Delimiter">();</span> <span class="Comment">// save pointer into recipe before pop</span> + const string& callee = current_recipe_name<span class="Delimiter">();</span> --Callstack_depth<span class="Delimiter">;</span> Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>pop_front<span class="Delimiter">();</span> <span class="Comment">// just in case 'main' returns a value, drop it for now</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">goto</span> stop_running_current_routine<span class="Delimiter">;</span> - <span class="Normal">const</span> instruction& caller_instruction = current_instruction<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">goto</span> stop_running_current_routine<span class="Delimiter">;</span> + const instruction& caller_instruction = current_instruction<span class="Delimiter">();</span> <span class="Comment">// make reply products available to caller</span> copy<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> ingredients<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> inserter<span class="Delimiter">(</span>products<span class="Delimiter">,</span> products<span class="Delimiter">.</span>begin<span class="Delimiter">()));</span> <span class="Comment">// check that any reply ingredients with /same-as-ingredient connect up</span> <span class="Comment">// the corresponding ingredient and product in the caller.</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">)</span> > SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">))</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">)</span> > SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">))</span> raise << <span class="Constant">"too few values replied from "</span> << callee << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <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>caller_instruction<span class="Delimiter">.</span>products<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">"result "</span> << i << <span class="Constant">" is "</span> << to_string<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> << end<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>reply_inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> <span class="Constant">"same-as-ingredient"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>reply_inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> <span class="Constant">"same-as-ingredient"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> vector<string> tmp = property<span class="Delimiter">(</span>reply_inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> <span class="Constant">"same-as-ingredient"</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>tmp<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>tmp<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'same-as-ingredient' metadata should take exactly one value in "</span> << reply_inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">goto</span> finish_reply<span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> ingredient_index = to_integer<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>ingredient_index >= SIZE<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>ingredients<span class="Delimiter">))</span> + long long int ingredient_index = to_integer<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> + if <span class="Delimiter">(</span>ingredient_index >= SIZE<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>ingredients<span class="Delimiter">))</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'same-as-ingredient' metadata overflows ingredients in: "</span> << caller_instruction<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!is_dummy<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> && caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>value != 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="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> << end<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>!is_dummy<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> && caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>value != 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="Delimiter">)</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'same-as-ingredient' product from call to "</span> << callee << <span class="Constant">" must be "</span> << caller_instruction<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>ingredient_index<span class="Delimiter">).</span>original_string << <span class="Constant">" rather than "</span> << caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Comment">// End Reply</span> - <span class="Normal">finish_reply</span>: + finish_reply: <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Comment">// continue to process rest of *caller* instruction</span> <span class="Delimiter">}</span> @@ -115,7 +114,7 @@ recipe test1 [ <span class="Constant">10</span>:address:number<span class="Special"> <- </span>next-ingredient reply <span class="Constant">10</span>:address:number/same-as-ingredient:<span class="Constant">0</span> ] -<span class="traceContains">+warn: main: 'same-as-ingredient' result 2 from call to test1 must be location 1</span> +<span class="traceContains">+warn: main: 'same-as-ingredient' product from call to test1 must be 1:number rather than 2:number</span> <span class="Delimiter">:(scenario reply_same_as_ingredient_dummy)</span> <span class="Special">% Hide_warnings = true;</span> @@ -130,16 +129,16 @@ recipe test1 [ $warn: <span class="Constant">0</span> <span class="Delimiter">:(code)</span> -string to_string<span class="Delimiter">(</span><span class="Normal">const</span> vector<<span class="Normal">double</span>>& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">"[]"</span><span class="Delimiter">;</span> +string to_string<span class="Delimiter">(</span>const vector<double>& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">"[]"</span><span class="Delimiter">;</span> ostringstream out<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>in<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>in<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> out << in<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span> <span class="Delimiter">}</span> out << <span class="Constant">"["</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>in<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>i > <span class="Constant">0</span><span class="Delimiter">)</span> out << <span class="Constant">", "</span><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>in<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>i > <span class="Constant">0</span><span class="Delimiter">)</span> out << <span class="Constant">", "</span><span class="Delimiter">;</span> out << in<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> <span class="Delimiter">}</span> out << <span class="Constant">"]"</span><span class="Delimiter">;</span> @@ -153,17 +152,17 @@ recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>test1 ] recipe test1 [ - reply-<span class="Normal">if</span> <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">34</span> + reply-if <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">34</span> reply <span class="Constant">35</span> ] <span class="traceContains">+mem: storing 35 in location 1</span> -<span class="Delimiter">:(scenario reply_if2)</span> +<span class="Delimiter">:(scenario reply_if_2)</span> recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>test1 ] recipe test1 [ - reply-<span class="Normal">if</span> <span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">34</span> + reply-if <span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">34</span> reply <span class="Constant">35</span> ] <span class="traceContains">+mem: storing 34 in location 1</span> @@ -174,8 +173,8 @@ recipe test1 [ <span class="Comment">// jump-unless a, 1:offset</span> <span class="Comment">// reply b, c, ...</span> <span class="Comment">// ```</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"reply-if"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> +if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"reply-if"</span><span class="Delimiter">)</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> <span class="Delimiter">{</span> curr<span class="Delimiter">.</span>operation = Recipe_ordinal[<span class="Constant">"jump-unless"</span>]<span class="Delimiter">;</span> curr<span class="Delimiter">.</span>name = <span class="Constant">"jump-unless"</span><span class="Delimiter">;</span> vector<reagent> results<span class="Delimiter">;</span> @@ -188,7 +187,7 @@ recipe test1 [ curr<span class="Delimiter">.</span>name = <span class="Constant">"reply"</span><span class="Delimiter">;</span> curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>swap<span class="Delimiter">(</span>results<span class="Delimiter">);</span> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> + else <span class="Delimiter">{</span> raise << <span class="Constant">"'reply-if' never yields any products</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> @@ -197,8 +196,8 @@ recipe test1 [ <span class="Comment">// jump-if a, 1:offset</span> <span class="Comment">// reply b, c, ...</span> <span class="Comment">// ```</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"reply-unless"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> +if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"reply-unless"</span><span class="Delimiter">)</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> <span class="Delimiter">{</span> curr<span class="Delimiter">.</span>operation = Recipe_ordinal[<span class="Constant">"jump-if"</span>]<span class="Delimiter">;</span> curr<span class="Delimiter">.</span>name = <span class="Constant">"jump-if"</span><span class="Delimiter">;</span> vector<reagent> results<span class="Delimiter">;</span> @@ -211,7 +210,7 @@ recipe test1 [ curr<span class="Delimiter">.</span>name = <span class="Constant">"reply"</span><span class="Delimiter">;</span> curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>swap<span class="Delimiter">(</span>results<span class="Delimiter">);</span> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> + else <span class="Delimiter">{</span> raise << <span class="Constant">"'reply-unless' never yields any products</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> diff --git a/html/037recipe.cc.html b/html/037recipe.cc.html index 667a99fa..838b0789 100644 --- a/html/037recipe.cc.html +++ b/html/037recipe.cc.html @@ -13,15 +13,14 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.Constant { color: #00a0a0; } +.Identifier { color: #804000; } .cSpecial { color: #008000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } -.CommentedCode { color: #6c6c6c; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } -.Identifier { color: #804000; } +.CommentedCode { color: #6c6c6c; } +.Constant { color: #00a0a0; } +.traceContains { color: #008000; } --> </style> @@ -67,7 +66,7 @@ type_ordinal recipe_ordinal = Type_ordinal[<span class="Constant">"recipe-o Type[recipe_ordinal]<span class="Delimiter">.</span>name = <span class="Constant">"recipe-ordinal"</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End Reagent-parsing Exceptions")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>!r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">"recipe"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +if <span class="Delimiter">(</span>!r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">"recipe"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> r<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>Recipe_ordinal[r<span class="Delimiter">.</span>name]<span class="Delimiter">);</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -77,13 +76,13 @@ CALL<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"call"</span>] = CALL<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> CALL: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> +case CALL: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'call' requires at least one ingredient (the recipe to call)</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">// Begin Call</span> - <span class="Normal">if</span> <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> + 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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'call' should be a recipe, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> diff --git a/html/038scheduler.cc.html b/html/038scheduler.cc.html index 9470ca3d..02c08935 100644 --- a/html/038scheduler.cc.html +++ b/html/038scheduler.cc.html @@ -13,17 +13,16 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } .SalientComment { color: #00ffff; } -.Constant { color: #00a0a0; } .traceAbsent { color: #c00000; } .CommentedCode { color: #6c6c6c; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.cSpecial { color: #008000; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } -.cSpecial { color: #008000; } +.Constant { color: #00a0a0; } +.traceContains { color: #008000; } --> </style> @@ -55,45 +54,45 @@ recipe f2 [ <span class="Comment">//: first, add a deadline to run(routine)</span> <span class="Comment">//: these changes are ugly and brittle; just close your nose and get through the next few lines</span> <span class="Delimiter">:(replace "void run_current_routine()")</span> -<span class="Normal">void</span> run_current_routine<span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> time_slice<span class="Delimiter">)</span> +void run_current_routine<span class="Delimiter">(</span>long long int time_slice<span class="Delimiter">)</span> <span class="Delimiter">:(replace "while (!Current_routine->completed())" following "void run_current_routine(long long int time_slice)")</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> ninstrs = <span class="Constant">0</span><span class="Delimiter">;</span> -<span class="Normal">while</span> <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>state == RUNNING && ninstrs < time_slice<span class="Delimiter">)</span> +long long int ninstrs = <span class="Constant">0</span><span class="Delimiter">;</span> +while <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>state == RUNNING && ninstrs < time_slice<span class="Delimiter">)</span> <span class="Delimiter">:(after "Running One Instruction")</span> ninstrs++<span class="Delimiter">;</span> <span class="Comment">//: now the rest of the scheduler is clean</span> <span class="Delimiter">:(before "struct routine")</span> -<span class="Normal">enum</span> routine_state <span class="Delimiter">{</span> +enum routine_state <span class="Delimiter">{</span> RUNNING<span class="Delimiter">,</span> COMPLETED<span class="Delimiter">,</span> <span class="Comment">// End routine States</span> <span class="Delimiter">};</span> <span class="Delimiter">:(before "End routine Fields")</span> -<span class="Normal">enum</span> routine_state state<span class="Delimiter">;</span> +enum routine_state state<span class="Delimiter">;</span> <span class="Delimiter">:(before "End routine Constructor")</span> state = RUNNING<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Globals")</span> vector<routine*> Routines<span class="Delimiter">;</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> Current_routine_index = <span class="Constant">0</span><span class="Delimiter">;</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> Scheduling_interval = <span class="Constant">500</span><span class="Delimiter">;</span> +long long int Current_routine_index = <span class="Constant">0</span><span class="Delimiter">;</span> +long long int Scheduling_interval = <span class="Constant">500</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End Setup")</span> Scheduling_interval = <span class="Constant">500</span><span class="Delimiter">;</span> Routines<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> <span class="Delimiter">:(replace{} "void run(recipe_ordinal r)")</span> -<span class="Normal">void</span> run<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> - Routines<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Normal">new</span> routine<span class="Delimiter">(</span>r<span class="Delimiter">));</span> +void run<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + Routines<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new routine<span class="Delimiter">(</span>r<span class="Delimiter">));</span> Current_routine_index = <span class="Constant">0</span><span class="Delimiter">,</span> Current_routine = Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>!all_routines_done<span class="Delimiter">())</span> <span class="Delimiter">{</span> + while <span class="Delimiter">(</span>!all_routines_done<span class="Delimiter">())</span> <span class="Delimiter">{</span> skip_to_next_routine<span class="Delimiter">();</span> assert<span class="Delimiter">(</span>Current_routine<span class="Delimiter">);</span> assert<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>state == RUNNING<span class="Delimiter">);</span> trace<span class="Delimiter">(</span><span class="Constant">"schedule"</span><span class="Delimiter">)</span> << current_routine_label<span class="Delimiter">()</span> << end<span class="Delimiter">();</span> run_current_routine<span class="Delimiter">(</span>Scheduling_interval<span class="Delimiter">);</span> <span class="Comment">// Scheduler State Transitions</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>completed<span class="Delimiter">())</span> + if <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>completed<span class="Delimiter">())</span> Current_routine<span class="Delimiter">-></span>state = COMPLETED<span class="Delimiter">;</span> <span class="Comment">// End Scheduler State Transitions</span> @@ -103,9 +102,9 @@ Routines<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -<span class="Normal">bool</span> all_routines_done<span class="Delimiter">()</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state == RUNNING<span class="Delimiter">)</span> <span class="Delimiter">{</span> +bool all_routines_done<span class="Delimiter">()</span> <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>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state == RUNNING<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> @@ -113,11 +112,11 @@ Routines<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Comment">// skip Current_routine_index past non-RUNNING routines</span> -<span class="Normal">void</span> skip_to_next_routine<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void skip_to_next_routine<span class="Delimiter">()</span> <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>!Routines<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> assert<span class="Delimiter">(</span>Current_routine_index < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">));</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Delimiter">(</span>Current_routine_index+<span class="Constant">1</span><span class="Delimiter">)</span>%SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> i != Current_routine_index<span class="Delimiter">;</span> i = <span class="Delimiter">(</span>i+<span class="Constant">1</span><span class="Delimiter">)</span>%SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">))</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state == RUNNING<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int i = <span class="Delimiter">(</span>Current_routine_index+<span class="Constant">1</span><span class="Delimiter">)</span>%SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> i != Current_routine_index<span class="Delimiter">;</span> i = <span class="Delimiter">(</span>i+<span class="Constant">1</span><span class="Delimiter">)</span>%SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">))</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state == RUNNING<span class="Delimiter">)</span> <span class="Delimiter">{</span> Current_routine_index = i<span class="Delimiter">;</span> Current_routine = Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> <span class="Identifier">return</span><span class="Delimiter">;</span> @@ -128,16 +127,16 @@ Routines<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> string current_routine_label<span class="Delimiter">()</span> <span class="Delimiter">{</span> ostringstream result<span class="Delimiter">;</span> call_stack calls = Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>call_stack::iterator p = calls<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != calls<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>p != calls<span class="Delimiter">.</span>begin<span class="Delimiter">())</span> result << <span class="Constant">'/'</span><span class="Delimiter">;</span> + for <span class="Delimiter">(</span>call_stack::iterator p = calls<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != calls<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>p != calls<span class="Delimiter">.</span>begin<span class="Delimiter">())</span> result << <span class="Constant">'/'</span><span class="Delimiter">;</span> result << Recipe[p<span class="Delimiter">-></span>running_recipe]<span class="Delimiter">.</span>name<span class="Delimiter">;</span> <span class="Delimiter">}</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 Teardown")</span> -<span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> - <span class="Normal">delete</span> Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> + delete Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> Routines<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> <span class="SalientComment">//:: To schedule new routines to run, call 'start-running'.</span> @@ -145,9 +144,9 @@ Routines<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> <span class="Comment">//: 'start-running' will return a unique id for the routine that was created.</span> <span class="Comment">//: routine id is a number, but don't do any arithmetic on it</span> <span class="Delimiter">:(before "End routine Fields")</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> id<span class="Delimiter">;</span> +long long int id<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Globals")</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> Next_routine_id = <span class="Constant">1</span><span class="Delimiter">;</span> +long long int Next_routine_id = <span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End Setup")</span> Next_routine_id = <span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End routine Constructor")</span> @@ -157,7 +156,7 @@ Next_routine_id++<span class="Delimiter">;</span> <span class="Comment">//: routines save the routine that spawned them</span> <span class="Delimiter">:(before "End routine Fields")</span> <span class="Comment">// todo: really should be routine_id, but that's less efficient.</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> parent_index<span class="Delimiter">;</span> <span class="Comment">// only < 0 if there's no parent_index</span> +long long int parent_index<span class="Delimiter">;</span> <span class="Comment">// only < 0 if there's no parent_index</span> <span class="Delimiter">:(before "End routine Constructor")</span> parent_index = -<span class="Constant">1</span><span class="Delimiter">;</span> @@ -166,11 +165,23 @@ START_RUNNING<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"start-running"</span>] = START_RUNNING<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> START_RUNNING: <span class="Delimiter">{</span> - routine* new_routine = <span class="Normal">new</span> routine<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> +case START_RUNNING: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> + raise << <span class="Constant">"'start-running' requires at least one ingredient: the recipe to start running</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <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">"first ingredient of 'start-running' should be a recipe, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + if <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="Delimiter">{</span> + raise << <span class="Constant">"'start-running' received non-existent recipe: '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + routine* new_routine = new routine<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> new_routine<span class="Delimiter">-></span>parent_index = Current_routine_index<span class="Delimiter">;</span> <span class="Comment">// populate ingredients</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> + for <span class="Delimiter">(</span>long long int i = <span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> new_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> Routines<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_routine<span class="Delimiter">);</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> @@ -237,8 +248,8 @@ recipe f2 [ <span class="Comment">//: this scenario will require some careful setup in escaped C++</span> <span class="Comment">//: (straining our tangle capabilities to near-breaking point)</span> <span class="Delimiter">:(scenario scheduler_skips_completed_routines)</span> -<span class="Special">% recipe_ordinal f1 = load("recipe f1 [\n1:number <- copy 0\n]").front();</span> -<span class="Special">% recipe_ordinal f2 = load("recipe f2 [\n2:number <- copy 0\n]").front();</span> +<span class="Special">% recipe_ordinal f1 = load("recipe f1 [\n1:number <- copy 0\n]\n").front();</span> +<span class="Special">% recipe_ordinal f2 = load("recipe f2 [\n2:number <- copy 0\n]\n").front();</span> <span class="Special">% Routines.push_back(new routine(f1)); // f1 meant to run</span> <span class="Special">% Routines.push_back(new routine(f2));</span> <span class="Special">% Routines.back()->state = COMPLETED; // f2 not meant to run</span> @@ -278,18 +289,18 @@ recipe f1 [ <span class="traceAbsent">-schedule: f1</span> <span class="Delimiter">:(before "End Scheduler Cleanup")</span> -<span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state == COMPLETED<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>parent_index < <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Comment">// root thread</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>has_completed_parent<span class="Delimiter">(</span>i<span class="Delimiter">))</span> <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>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state == COMPLETED<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>parent_index < <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Comment">// root thread</span> + if <span class="Delimiter">(</span>has_completed_parent<span class="Delimiter">(</span>i<span class="Delimiter">))</span> <span class="Delimiter">{</span> Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state = COMPLETED<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -<span class="Normal">bool</span> has_completed_parent<span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> routine_index<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> j = routine_index<span class="Delimiter">;</span> j >= <span class="Constant">0</span><span class="Delimiter">;</span> j = Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)-></span>parent_index<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)-></span>state == COMPLETED<span class="Delimiter">)</span> +bool has_completed_parent<span class="Delimiter">(</span>long long int routine_index<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int j = routine_index<span class="Delimiter">;</span> j >= <span class="Constant">0</span><span class="Delimiter">;</span> j = Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)-></span>parent_index<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)-></span>state == COMPLETED<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> @@ -317,19 +328,19 @@ ROUTINE_STATE<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"routine-state"</span>] = ROUTINE_STATE<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> ROUTINE_STATE: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case ROUTINE_STATE: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'routine-state' requires exactly one ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> + 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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'routine-state' should be a routine id generated by 'start-running', but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> id = 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="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> result = -<span class="Constant">1</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>id == id<span class="Delimiter">)</span> <span class="Delimiter">{</span> + long long int id = 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> + long long int result = -<span class="Constant">1</span><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>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>id == id<span class="Delimiter">)</span> <span class="Delimiter">{</span> result = Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state<span class="Delimiter">;</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -346,18 +357,18 @@ RESTART<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"restart"</span>] = RESTART<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> RESTART: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case RESTART: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'restart' requires exactly one ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> + 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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'restart' should be a routine id generated by 'start-running', but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> id = 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="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>id == id<span class="Delimiter">)</span> <span class="Delimiter">{</span> + long long int id = 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> + for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>id == id<span class="Delimiter">)</span> <span class="Delimiter">{</span> Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state = RUNNING<span class="Delimiter">;</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -370,18 +381,18 @@ STOP<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"stop"</span>] = STOP<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> STOP: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case STOP: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'stop' requires exactly one ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> + 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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'stop' should be a routine id generated by 'start-running', but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> id = 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="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>id == id<span class="Delimiter">)</span> <span class="Delimiter">{</span> + long long int id = 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> + for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>id == id<span class="Delimiter">)</span> <span class="Delimiter">{</span> Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state = COMPLETED<span class="Delimiter">;</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -394,12 +405,75 @@ _DUMP_ROUTINES<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"$dump-routines"</span>] = _DUMP_ROUTINES<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> _DUMP_ROUTINES: <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> +case _DUMP_ROUTINES: <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>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> cerr << i << <span class="Constant">": "</span> << Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>id << <span class="Constant">' '</span> << Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state << <span class="Constant">' '</span> << Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>parent_index << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> + +<span class="Comment">//: support for stopping routines after some number of cycles</span> + +<span class="Delimiter">:(scenario routine_discontinues_past_limit)</span> +<span class="Special">% Scheduling_interval = 2;</span> +recipe f1 [ + <span class="Constant">1</span>:number/child-id<span class="Special"> <- </span>start-running f2:recipe + limit-time <span class="Constant">1</span>:number/child-id<span class="Delimiter">,</span> <span class="Constant">1</span> +] +recipe f2 [ +<span class="Delimiter">{</span> + loop <span class="Comment"># run forever</span> +<span class="Delimiter">}</span> +] +<span class="Comment"># f2 terminates</span> +<span class="traceContains">+schedule: discontinuing routine 2</span> + +<span class="Delimiter">:(before "End routine States")</span> +DISCONTINUED<span class="Delimiter">,</span> +<span class="Delimiter">:(before "End Scheduler State Transitions")</span> +if <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>limit >= <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>limit <= Scheduling_interval<span class="Delimiter">)</span> <span class="Delimiter">{</span> + trace<span class="Delimiter">(</span><span class="Constant">"schedule"</span><span class="Delimiter">)</span> << <span class="Constant">"discontinuing routine "</span> << Current_routine<span class="Delimiter">-></span>id << end<span class="Delimiter">();</span> + Current_routine<span class="Delimiter">-></span>state = DISCONTINUED<span class="Delimiter">;</span> + Current_routine<span class="Delimiter">-></span>limit = <span class="Constant">0</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + else <span class="Delimiter">{</span> + Current_routine<span class="Delimiter">-></span>limit -= Scheduling_interval<span class="Delimiter">;</span> + <span class="Delimiter">}</span> +<span class="Delimiter">}</span> + +<span class="Delimiter">:(before "End routine Fields")</span> +long long int limit<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End routine Constructor")</span> +limit = -<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Comment">/*</span><span class="Comment"> no limit </span><span class="Comment">*/</span> + +<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> +LIMIT_TIME<span class="Delimiter">,</span> +<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> +Recipe_ordinal[<span class="Constant">"limit-time"</span>] = LIMIT_TIME<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> +case LIMIT_TIME: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'limit-time' requires exactly two ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'limit-time' should be a routine id generated by 'start-running', but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <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> <span class="Delimiter">{</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": second ingredient of 'limit-time' should be a number (of instructions to run for), but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + long long int id = 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> + for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>id == id<span class="Delimiter">)</span> <span class="Delimiter">{</span> + Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>limit = 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> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <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/039wait.cc.html b/html/039wait.cc.html index 36dcbdcc..dc19a3b3 100644 --- a/html/039wait.cc.html +++ b/html/039wait.cc.html @@ -13,14 +13,13 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.traceContains { color: #008000; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } --> </style> @@ -41,7 +40,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } recipe f1 [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> start-running f2:recipe - wait-<span class="Normal">for</span>-location <span class="Constant">1</span>:number + wait-for-location <span class="Constant">1</span>:number <span class="Comment"># now wait for f2 to run and modify location 1 before using its value</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:number ] @@ -57,8 +56,8 @@ recipe f2 [ WAITING<span class="Delimiter">,</span> <span class="Delimiter">:(before "End routine Fields")</span> <span class="Comment">// only if state == WAITING</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> waiting_on_location<span class="Delimiter">;</span> -<span class="Normal">int</span> old_value_of_waiting_location<span class="Delimiter">;</span> +long long int waiting_on_location<span class="Delimiter">;</span> +int old_value_of_waiting_location<span class="Delimiter">;</span> <span class="Delimiter">:(before "End routine Constructor")</span> waiting_on_location = old_value_of_waiting_location = <span class="Constant">0</span><span class="Delimiter">;</span> @@ -69,7 +68,7 @@ WAIT_FOR_LOCATION<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"wait-for-location"</span>] = WAIT_FOR_LOCATION<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> WAIT_FOR_LOCATION: <span class="Delimiter">{</span> +case WAIT_FOR_LOCATION: <span class="Delimiter">{</span> reagent loc = 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> Current_routine<span class="Delimiter">-></span>state = WAITING<span class="Delimiter">;</span> Current_routine<span class="Delimiter">-></span>waiting_on_location = loc<span class="Delimiter">.</span>value<span class="Delimiter">;</span> @@ -81,9 +80,9 @@ Recipe_ordinal[<span class="Constant">"wait-for-location"</span>] = WA <span class="Comment">//: scheduler tweak to get routines out of that state</span> <span class="Delimiter">:(before "End Scheduler State Transitions")</span> -<span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state != WAITING<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>waiting_on_location && +for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state != WAITING<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>waiting_on_location && Memory[Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>waiting_on_location] != Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>old_value_of_waiting_location<span class="Delimiter">)</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">"schedule"</span><span class="Delimiter">)</span> << <span class="Constant">"waking up routine</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state = RUNNING<span class="Delimiter">;</span> @@ -97,7 +96,7 @@ Recipe_ordinal[<span class="Constant">"wait-for-location"</span>] = WA recipe f1 [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Constant">12</span>:number/routine<span class="Special"> <- </span>start-running f2:recipe - wait-<span class="Normal">for</span>-routine <span class="Constant">12</span>:number/routine + wait-for-routine <span class="Constant">12</span>:number/routine <span class="Comment"># now wait for f2 to run and modify location 1 before using its value</span> <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:number ] @@ -114,7 +113,7 @@ recipe f2 [ <span class="Delimiter">:(before "End routine Fields")</span> <span class="Comment">// only if state == WAITING</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> waiting_on_routine<span class="Delimiter">;</span> +long long int waiting_on_routine<span class="Delimiter">;</span> <span class="Delimiter">:(before "End routine Constructor")</span> waiting_on_routine = <span class="Constant">0</span><span class="Delimiter">;</span> @@ -123,16 +122,16 @@ WAIT_FOR_ROUTINE<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"wait-for-routine"</span>] = WAIT_FOR_ROUTINE<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> WAIT_FOR_ROUTINE: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case WAIT_FOR_ROUTINE: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'wait-for-routine' requires exactly one ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> + 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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'wait-for-routine' should be a routine id generated by 'start-running', but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> == Current_routine<span class="Delimiter">-></span>id<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <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> == Current_routine<span class="Delimiter">-></span>id<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": routine can't wait for itself! "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -146,13 +145,13 @@ Recipe_ordinal[<span class="Constant">"wait-for-routine"</span>] = WAI <span class="Comment">// Wake up any routines waiting for other routines to go to sleep.</span> <span class="Comment">// Important: this must come after the scheduler loop above giving routines</span> <span class="Comment">// waiting for locations to change a chance to wake up.</span> -<span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state != WAITING<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>waiting_on_routine<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> id = Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>waiting_on_routine<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>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state != WAITING<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>waiting_on_routine<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + long long int id = Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>waiting_on_routine<span class="Delimiter">;</span> assert<span class="Delimiter">(</span>id != Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>id<span class="Delimiter">);</span> <span class="Comment">// routine can't wait on itself</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)-></span>id == id && Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)-></span>state != RUNNING<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>Routines<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)-></span>id == id && Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)-></span>state != RUNNING<span class="Delimiter">)</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">"schedule"</span><span class="Delimiter">)</span> << <span class="Constant">"waking up routine "</span> << Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>id << end<span class="Delimiter">();</span> Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state = RUNNING<span class="Delimiter">;</span> Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>waiting_on_routine = <span class="Constant">0</span><span class="Delimiter">;</span> @@ -165,9 +164,9 @@ SWITCH<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"switch"</span>] = SWITCH<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> SWITCH: <span class="Delimiter">{</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> id = some_other_running_routine<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>id<span class="Delimiter">)</span> <span class="Delimiter">{</span> +case SWITCH: <span class="Delimiter">{</span> + long long int id = some_other_running_routine<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>id<span class="Delimiter">)</span> <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>id != Current_routine<span class="Delimiter">-></span>id<span class="Delimiter">);</span> Current_routine<span class="Delimiter">-></span>state = WAITING<span class="Delimiter">;</span> Current_routine<span class="Delimiter">-></span>waiting_on_routine = id<span class="Delimiter">;</span> @@ -176,12 +175,12 @@ Recipe_ordinal[<span class="Constant">"switch"</span>] = SWITCH<span c <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> some_other_running_routine<span class="Delimiter">()</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>i == Current_routine_index<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> +long long int some_other_running_routine<span class="Delimiter">()</span> <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>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>i == Current_routine_index<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> assert<span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> != Current_routine<span class="Delimiter">);</span> assert<span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>id != Current_routine<span class="Delimiter">-></span>id<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state == RUNNING<span class="Delimiter">)</span> + if <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state == RUNNING<span class="Delimiter">)</span> <span class="Identifier">return</span> Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>id<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span> diff --git a/html/040brace.cc.html b/html/040brace.cc.html index 4837653d..223e7923 100644 --- a/html/040brace.cc.html +++ b/html/040brace.cc.html @@ -13,15 +13,14 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.Constant { color: #00a0a0; } -.cSpecial { color: #008000; } .CommentedCode { color: #6c6c6c; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.cSpecial { color: #008000; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } +.traceContains { color: #008000; } --> </style> @@ -71,37 +70,37 @@ recipe main [ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>transform_braces<span class="Delimiter">);</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> transform_braces<span class="Delimiter">(</span><span class="Normal">const</span> recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void transform_braces<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cout << "AAA transform_braces\n"; //? 1</span> <span class="CommentedCode">//? exit(0); //? 1</span> - <span class="Normal">const</span> <span class="Normal">int</span> OPEN = <span class="Constant">0</span><span class="Delimiter">,</span> CLOSE = <span class="Constant">1</span><span class="Delimiter">;</span> + const int OPEN = <span class="Constant">0</span><span class="Delimiter">,</span> CLOSE = <span class="Constant">1</span><span class="Delimiter">;</span> <span class="Comment">// use signed integer for step index because we'll be doing arithmetic on it</span> - list<pair<<span class="Normal">int</span><span class="Comment">/*</span><span class="Comment">OPEN/CLOSE</span><span class="Comment">*/</span><span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">step</span><span class="Comment">*/</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>> > braces<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> index = <span class="Constant">0</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">const</span> instruction& inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label == <span class="Constant">"{"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - trace<span class="Delimiter">(</span><span class="Constant">"brace"</span><span class="Delimiter">)</span> << r << <span class="Constant">": push (open, "</span> << index << <span class="Constant">")"</span> << end<span class="Delimiter">();</span> - braces<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<<span class="Normal">int</span><span class="Delimiter">,</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>><span class="Delimiter">(</span>OPEN<span class="Delimiter">,</span> index<span class="Delimiter">));</span> + list<pair<int<span class="Comment">/*</span><span class="Comment">OPEN/CLOSE</span><span class="Comment">*/</span><span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">step</span><span class="Comment">*/</span>long long int> > braces<span class="Delimiter">;</span> + for <span class="Delimiter">(</span>long long int index = <span class="Constant">0</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++index<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>index<span class="Delimiter">);</span> + if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label == <span class="Constant">"{"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + trace<span class="Delimiter">(</span><span class="Constant">"brace"</span><span class="Delimiter">)</span> << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": push (open, "</span> << index << <span class="Constant">")"</span> << end<span class="Delimiter">();</span> + braces<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<int<span class="Delimiter">,</span>long long int><span class="Delimiter">(</span>OPEN<span class="Delimiter">,</span> index<span class="Delimiter">));</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label == <span class="Constant">"}"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label == <span class="Constant">"}"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">"brace"</span><span class="Delimiter">)</span> << <span class="Constant">"push (close, "</span> << index << <span class="Constant">")"</span> << end<span class="Delimiter">();</span> - braces<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<<span class="Normal">int</span><span class="Delimiter">,</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>><span class="Delimiter">(</span>CLOSE<span class="Delimiter">,</span> index<span class="Delimiter">));</span> + braces<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<int<span class="Delimiter">,</span>long long int><span class="Delimiter">(</span>CLOSE<span class="Delimiter">,</span> index<span class="Delimiter">));</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> - stack<<span class="Comment">/*</span><span class="Comment">step</span><span class="Comment">*/</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>> open_braces<span class="Delimiter">;</span> + stack<<span class="Comment">/*</span><span class="Comment">step</span><span class="Comment">*/</span>long long int> open_braces<span class="Delimiter">;</span> trace<span class="Delimiter">(</span><span class="Constant">"after-brace"</span><span class="Delimiter">)</span> << <span class="Constant">"recipe "</span> << Recipe[r]<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> index = <span class="Constant">0</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int index = <span class="Constant">0</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> instruction& inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label == <span class="Constant">"{"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label == <span class="Constant">"{"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> open_braces<span class="Delimiter">.</span>push<span class="Delimiter">(</span>index<span class="Delimiter">);</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label == <span class="Constant">"}"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label == <span class="Constant">"}"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> open_braces<span class="Delimiter">.</span>pop<span class="Delimiter">();</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>is_label<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation != Recipe_ordinal[<span class="Constant">"loop"</span>] + if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>is_label<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation != Recipe_ordinal[<span class="Constant">"loop"</span>] && inst<span class="Delimiter">.</span>operation != Recipe_ordinal[<span class="Constant">"loop-if"</span>] && inst<span class="Delimiter">.</span>operation != Recipe_ordinal[<span class="Constant">"loop-unless"</span>] && inst<span class="Delimiter">.</span>operation != Recipe_ordinal[<span class="Constant">"break"</span>] @@ -111,23 +110,23 @@ recipe main [ <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">// update instruction operation</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-if"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> + if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-if"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> inst<span class="Delimiter">.</span>operation = Recipe_ordinal[<span class="Constant">"jump-if"</span>]<span class="Delimiter">;</span> - <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-unless"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> + else if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-unless"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> inst<span class="Delimiter">.</span>operation = Recipe_ordinal[<span class="Constant">"jump-unless"</span>]<span class="Delimiter">;</span> - <span class="Normal">else</span> + else inst<span class="Delimiter">.</span>operation = Recipe_ordinal[<span class="Constant">"jump"</span>]<span class="Delimiter">;</span> <span class="Comment">// check for explicitly provided targets</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-if"</span><span class="Delimiter">)</span> != string::npos || inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-unless"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-if"</span><span class="Delimiter">)</span> != string::npos || inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-unless"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// conditional branches check arg 1</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">1</span> && is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">1</span> && is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">"after-brace"</span><span class="Delimiter">)</span> << <span class="Constant">"jump "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name << <span class="Constant">":offset"</span> << end<span class="Delimiter">();</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> + else <span class="Delimiter">{</span> <span class="Comment">// unconditional branches check arg 0</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && is_literal<span class="Delimiter">(</span>inst<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> + if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && is_literal<span class="Delimiter">(</span>inst<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> trace<span class="Delimiter">(</span><span class="Constant">"after-brace"</span><span class="Delimiter">)</span> << <span class="Constant">"jump "</span> << inst<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">":offset"</span> << end<span class="Delimiter">();</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -136,38 +135,38 @@ recipe main [ reagent target<span class="Delimiter">;</span> target<span class="Delimiter">.</span>types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"offset"</span>]<span class="Delimiter">);</span> target<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>open_braces<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> + if <span class="Delimiter">(</span>open_braces<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> raise << inst<span class="Delimiter">.</span>name << <span class="Constant">" needs a '{' before</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> - <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"loop"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> + else if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"loop"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> target<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>open_braces<span class="Delimiter">.</span>top<span class="Delimiter">()</span>-index<span class="Delimiter">);</span> - <span class="Normal">else</span> <span class="Comment">// break instruction</span> + else <span class="Comment">// break instruction</span> target<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>matching_brace<span class="Delimiter">(</span>open_braces<span class="Delimiter">.</span>top<span class="Delimiter">(),</span> braces<span class="Delimiter">,</span> r<span class="Delimiter">)</span> - index - <span class="Constant">1</span><span class="Delimiter">);</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>target<span class="Delimiter">);</span> <span class="Comment">// log computed target</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-if"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> + if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-if"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> trace<span class="Delimiter">(</span><span class="Constant">"after-brace"</span><span class="Delimiter">)</span> << <span class="Constant">"jump-if "</span> << inst<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> << target<span class="Delimiter">.</span>value << <span class="Constant">":offset"</span> << end<span class="Delimiter">();</span> - <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-unless"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> + else if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-unless"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> trace<span class="Delimiter">(</span><span class="Constant">"after-brace"</span><span class="Delimiter">)</span> << <span class="Constant">"jump-unless "</span> << inst<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> << target<span class="Delimiter">.</span>value << <span class="Constant">":offset"</span> << end<span class="Delimiter">();</span> - <span class="Normal">else</span> + else trace<span class="Delimiter">(</span><span class="Constant">"after-brace"</span><span class="Delimiter">)</span> << <span class="Constant">"jump "</span> << target<span class="Delimiter">.</span>value << <span class="Constant">":offset"</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Comment">// returns a signed integer not just so that we can return -1 but also to</span> <span class="Comment">// enable future signed arithmetic</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> matching_brace<span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> index<span class="Delimiter">,</span> <span class="Normal">const</span> list<pair<<span class="Normal">int</span><span class="Delimiter">,</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>> >& braces<span class="Delimiter">,</span> recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">int</span> stacksize = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>list<pair<<span class="Normal">int</span><span class="Delimiter">,</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>> >::const_iterator p = braces<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != braces<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>p<span class="Delimiter">-></span>second < index<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> +long long int matching_brace<span class="Delimiter">(</span>long long int index<span class="Delimiter">,</span> const list<pair<int<span class="Delimiter">,</span> long long int> >& braces<span class="Delimiter">,</span> recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + int stacksize = <span class="Constant">0</span><span class="Delimiter">;</span> + for <span class="Delimiter">(</span>list<pair<int<span class="Delimiter">,</span> long long int> >::const_iterator p = braces<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != braces<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>p<span class="Delimiter">-></span>second < index<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> stacksize += <span class="Delimiter">(</span>p<span class="Delimiter">-></span>first ? <span class="Constant">1</span> : -<span class="Constant">1</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>stacksize == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> p<span class="Delimiter">-></span>second<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>stacksize == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> p<span class="Delimiter">-></span>second<span class="Delimiter">;</span> <span class="Delimiter">}</span> raise << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": unbalanced '{'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span> SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> <span class="Comment">// exit current routine</span> <span class="Delimiter">}</span> <span class="Comment">// temporarily suppress run</span> -<span class="Normal">void</span> transform<span class="Delimiter">(</span>string form<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void transform<span class="Delimiter">(</span>string form<span class="Delimiter">)</span> <span class="Delimiter">{</span> load<span class="Delimiter">(</span>form<span class="Delimiter">);</span> transform_all<span class="Delimiter">();</span> <span class="Delimiter">}</span> @@ -231,7 +230,7 @@ recipe main [ <span class="traceContains">+after-brace: jump 0:offset</span> <span class="traceContains">+after-brace: jump 0:offset</span> -<span class="Delimiter">:(scenario break_cascading2)</span> +<span class="Delimiter">:(scenario break_cascading_2)</span> recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> @@ -255,7 +254,7 @@ recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Delimiter">{</span> - <span class="Identifier">break</span>-<span class="Normal">if</span> <span class="Constant">2</span>:number + <span class="Identifier">break</span>-if <span class="Constant">2</span>:number <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Delimiter">}</span> <span class="Delimiter">{</span> @@ -296,7 +295,7 @@ recipe main [ ] <span class="traceContains">+after-brace: jump 3:offset</span> -<span class="Delimiter">:(scenario break_nested_degenerate2)</span> +<span class="Delimiter">:(scenario break_nested_degenerate_2)</span> recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Delimiter">{</span> @@ -356,7 +355,7 @@ recipe main [ <span class="Delimiter">{</span> <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Delimiter">}</span> - loop-<span class="Normal">if</span> <span class="Constant">4</span>:boolean + loop-if <span class="Constant">4</span>:boolean <span class="Constant">5</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Delimiter">}</span> ] @@ -382,7 +381,7 @@ recipe test-factorial [ <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span> <span class="Delimiter">{</span> <span class="Constant">3</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">1</span> - <span class="Identifier">break</span>-<span class="Normal">if</span> <span class="Constant">3</span>:boolean + <span class="Identifier">break</span>-if <span class="Constant">3</span>:boolean <span class="Comment"># $print 1:number</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>multiply <span class="Constant">2</span>:number<span class="Delimiter">,</span> <span class="Constant">1</span>:number <span class="Constant">1</span>:number<span class="Special"> <- </span>subtract <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">1</span> diff --git a/html/041jump_label.cc.html b/html/041jump_label.cc.html index 3ab513f4..6b0f0bd4 100644 --- a/html/041jump_label.cc.html +++ b/html/041jump_label.cc.html @@ -13,16 +13,15 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } .traceAbsent { color: #c00000; } -.Constant { color: #00a0a0; } -.cSpecial { color: #008000; } +.traceContains { color: #008000; } .CommentedCode { color: #6c6c6c; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.cSpecial { color: #008000; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } --> </style> @@ -55,25 +54,25 @@ Type_ordinal[<span class="Constant">"label"</span>] = <span class="Con Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>transform_labels<span class="Delimiter">);</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> transform_labels<span class="Delimiter">(</span><span class="Normal">const</span> recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> - map<string<span class="Delimiter">,</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>> offset<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">const</span> instruction& inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>label<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> offset[inst<span class="Delimiter">.</span>label] = i<span class="Delimiter">;</span> +void transform_labels<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + map<string<span class="Delimiter">,</span> long long int> offset<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>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<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>i<span class="Delimiter">);</span> + if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>label<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> offset[inst<span class="Delimiter">.</span>label] = i<span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <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>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> instruction& inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"jump"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"jump"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span> replace_offset<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">),</span> offset<span class="Delimiter">,</span> i<span class="Delimiter">,</span> r<span class="Delimiter">);</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"jump-if"</span>] || inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"jump-unless"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"jump-if"</span>] || inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"jump-unless"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span> replace_offset<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">),</span> offset<span class="Delimiter">,</span> i<span class="Delimiter">,</span> r<span class="Delimiter">);</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">((</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"loop"</span>] || inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"break"</span>]<span class="Delimiter">)</span> + if <span class="Delimiter">((</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"loop"</span>] || inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"break"</span>]<span class="Delimiter">)</span> && SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> replace_offset<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">),</span> offset<span class="Delimiter">,</span> i<span class="Delimiter">,</span> r<span class="Delimiter">);</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">((</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"loop-if"</span>] || inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"loop-unless"</span>] + if <span class="Delimiter">((</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"loop-if"</span>] || inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"loop-unless"</span>] || inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"break-if"</span>] || inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"break-unless"</span>]<span class="Delimiter">)</span> && SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> == <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> replace_offset<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">),</span> offset<span class="Delimiter">,</span> i<span class="Delimiter">,</span> r<span class="Delimiter">);</span> @@ -82,14 +81,14 @@ Type_ordinal[<span class="Constant">"label"</span>] = <span class="Con <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> replace_offset<span class="Delimiter">(</span>reagent& x<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">const</span><span class="Comment">*/</span> map<string<span class="Delimiter">,</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>>& offset<span class="Delimiter">,</span> <span class="Normal">const</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> current_offset<span class="Delimiter">,</span> <span class="Normal">const</span> recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Delimiter">{</span> +void replace_offset<span class="Delimiter">(</span>reagent& x<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">const</span><span class="Comment">*/</span> map<string<span class="Delimiter">,</span> long long int>& offset<span class="Delimiter">,</span> const long long int current_offset<span class="Delimiter">,</span> const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": jump target must be offset or label but is "</span> << x<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> assert<span class="Delimiter">(</span>!x<span class="Delimiter">.</span>initialized<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// non-labels will be handled like other number operands</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>offset<span class="Delimiter">.</span>find<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">)</span> == offset<span class="Delimiter">.</span>end<span class="Delimiter">())</span> + if <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// non-labels will be handled like other number operands</span> + if <span class="Delimiter">(</span>offset<span class="Delimiter">.</span>find<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">)</span> == offset<span class="Delimiter">.</span>end<span class="Delimiter">())</span> raise << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": can't find label "</span> << x<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> x<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>offset[x<span class="Delimiter">.</span>name]-current_offset<span class="Delimiter">);</span> <span class="Delimiter">}</span> @@ -111,7 +110,7 @@ recipe main [ recipe main [ <span class="Delimiter">{</span> <span class="Delimiter">{</span> - jump-<span class="Normal">if</span> <span class="Constant">1</span><span class="Delimiter">,</span> +target:label + jump-if <span class="Constant">1</span><span class="Delimiter">,</span> +target:label <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> diff --git a/html/042name.cc.html b/html/042name.cc.html index d4567520..c0f0a2cf 100644 --- a/html/042name.cc.html +++ b/html/042name.cc.html @@ -13,17 +13,16 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.traceAbsent { color: #c00000; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } .SalientComment { color: #00ffff; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.traceAbsent { color: #c00000; } +.CommentedCode { color: #6c6c6c; } +.Constant { color: #00a0a0; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } -.CommentedCode { color: #6c6c6c; } +.traceContains { color: #008000; } --> </style> @@ -41,7 +40,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">:(scenario transform_names)</span> recipe main [ - <span class="Normal">x</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> + x:number<span class="Special"> <- </span>copy <span class="Constant">0</span> ] <span class="traceContains">+name: assign x 1</span> <span class="traceContains">+mem: storing 0 in location 1</span> @@ -50,7 +49,7 @@ recipe main [ <span class="Delimiter">:(scenario transform_names_warns)</span> <span class="Special">% Hide_warnings = true;</span> recipe main [ - <span class="Normal">x</span>:number<span class="Special"> <- </span>copy y:number + x:number<span class="Special"> <- </span>copy y:number ] <span class="traceContains">+warn: use before set: y in main</span> @@ -58,38 +57,38 @@ recipe main [ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>transform_names<span class="Delimiter">);</span> <span class="Delimiter">:(before "End Globals")</span> -map<recipe_ordinal<span class="Delimiter">,</span> map<string<span class="Delimiter">,</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>> > Name<span class="Delimiter">;</span> +map<recipe_ordinal<span class="Delimiter">,</span> map<string<span class="Delimiter">,</span> long long int> > Name<span class="Delimiter">;</span> <span class="Delimiter">:(after "Clear Other State For recently_added_recipes")</span> -<span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>recently_added_recipes<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <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>recently_added_recipes<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> Name<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>recently_added_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> transform_names<span class="Delimiter">(</span><span class="Normal">const</span> recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">bool</span> names_used = <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Normal">bool</span> numeric_locations_used = <span class="Constant">false</span><span class="Delimiter">;</span> - map<string<span class="Delimiter">,</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>>& names = Name[r]<span class="Delimiter">;</span> +void transform_names<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + bool names_used = <span class="Constant">false</span><span class="Delimiter">;</span> + bool numeric_locations_used = <span class="Constant">false</span><span class="Delimiter">;</span> + map<string<span class="Delimiter">,</span> long long int>& names = Name[r]<span class="Delimiter">;</span> <span class="Comment">// store the indices 'used' so far in the map</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>& curr_idx = names[<span class="Constant">""</span>]<span class="Delimiter">;</span> + long long int& curr_idx = names[<span class="Constant">""</span>]<span class="Delimiter">;</span> ++curr_idx<span class="Delimiter">;</span> <span class="Comment">// avoid using index 0, benign skip in some other cases</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <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>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> instruction& inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> <span class="Comment">// Per-recipe Transforms</span> <span class="Comment">// map names to addresses</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> in = <span class="Constant">0</span><span class="Delimiter">;</span> in < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++in<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_numeric_location<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">)))</span> numeric_locations_used = <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_named_location<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">)))</span> names_used = <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>disqualified<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">),</span> inst<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!already_transformed<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">),</span> names<span class="Delimiter">))</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int in = <span class="Constant">0</span><span class="Delimiter">;</span> in < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++in<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>is_numeric_location<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">)))</span> numeric_locations_used = <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>is_named_location<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">)))</span> names_used = <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>disqualified<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">),</span> inst<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!already_transformed<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">),</span> names<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise << <span class="Constant">"use before set: "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">).</span>name << <span class="Constant">" in "</span> << Recipe[r]<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">).</span>set_value<span class="Delimiter">(</span>lookup_name<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">),</span> r<span class="Delimiter">));</span> <span class="Delimiter">}</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> out = <span class="Constant">0</span><span class="Delimiter">;</span> out < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++out<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_numeric_location<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">)))</span> numeric_locations_used = <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_named_location<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">)))</span> names_used = <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>disqualified<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">),</span> inst<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">).</span>name<span class="Delimiter">)</span> == names<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int out = <span class="Constant">0</span><span class="Delimiter">;</span> out < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++out<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>is_numeric_location<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">)))</span> numeric_locations_used = <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>is_named_location<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">)))</span> names_used = <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>disqualified<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">),</span> inst<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">).</span>name<span class="Delimiter">)</span> == names<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">"name"</span><span class="Delimiter">)</span> << <span class="Constant">"assign "</span> << inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">).</span>name << <span class="Constant">" "</span> << curr_idx << end<span class="Delimiter">();</span> names[inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">).</span>name] = curr_idx<span class="Delimiter">;</span> curr_idx += size_of<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">));</span> @@ -97,74 +96,74 @@ map<recipe_ordinal<span class="Delimiter">,</span> map<string<span class=" inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">).</span>set_value<span class="Delimiter">(</span>lookup_name<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">),</span> r<span class="Delimiter">));</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>names_used && numeric_locations_used && r != Recipe_ordinal[<span class="Constant">"interactive"</span>]<span class="Delimiter">)</span> + if <span class="Delimiter">(</span>names_used && numeric_locations_used<span class="Delimiter">)</span> raise << <span class="Constant">"mixing variable names and numeric addresses in "</span> << Recipe[r]<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> -<span class="Normal">bool</span> disqualified<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">mutable</span><span class="Comment">*/</span> reagent& x<span class="Delimiter">,</span> <span class="Normal">const</span> instruction& inst<span class="Delimiter">)</span> <span class="Delimiter">{</span> +bool disqualified<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">mutable</span><span class="Comment">*/</span> reagent& x<span class="Delimiter">,</span> const instruction& inst<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << x.to_string() << '\n'; //? 1</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> raise << <span class="Constant">"missing type in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Comment">// End Disqualified Reagents</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>initialized<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>initialized<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">bool</span> already_transformed<span class="Delimiter">(</span><span class="Normal">const</span> reagent& r<span class="Delimiter">,</span> <span class="Normal">const</span> map<string<span class="Delimiter">,</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>>& names<span class="Delimiter">)</span> <span class="Delimiter">{</span> +bool already_transformed<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">,</span> const map<string<span class="Delimiter">,</span> long long int>& names<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>r<span class="Delimiter">.</span>name<span class="Delimiter">)</span> != names<span class="Delimiter">.</span>end<span class="Delimiter">();</span> <span class="Delimiter">}</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> lookup_name<span class="Delimiter">(</span><span class="Normal">const</span> reagent& r<span class="Delimiter">,</span> <span class="Normal">const</span> recipe_ordinal default_recipe<span class="Delimiter">)</span> <span class="Delimiter">{</span> +long long int lookup_name<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">,</span> const recipe_ordinal default_recipe<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> Name[default_recipe][r<span class="Delimiter">.</span>name]<span class="Delimiter">;</span> <span class="Delimiter">}</span> -type_ordinal skip_addresses<span class="Delimiter">(</span><span class="Normal">const</span> vector<type_ordinal>& types<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>types<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> != Type_ordinal[<span class="Constant">"address"</span>]<span class="Delimiter">)</span> <span class="Identifier">return</span> types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> +type_ordinal skip_addresses<span class="Delimiter">(</span>const vector<type_ordinal>& types<span class="Delimiter">)</span> <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>types<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> != Type_ordinal[<span class="Constant">"address"</span>]<span class="Delimiter">)</span> <span class="Identifier">return</span> types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> <span class="Delimiter">}</span> raise << <span class="Constant">"expected a container"</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">int</span> find_element_name<span class="Delimiter">(</span><span class="Normal">const</span> type_ordinal t<span class="Delimiter">,</span> <span class="Normal">const</span> string& name<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">const</span> type_info& container = Type[t]<span class="Delimiter">;</span> +int find_element_name<span class="Delimiter">(</span>const type_ordinal t<span class="Delimiter">,</span> const string& name<span class="Delimiter">)</span> <span class="Delimiter">{</span> + const type_info& container = Type[t]<span class="Delimiter">;</span> <span class="CommentedCode">//? cout << "looking for element " << name << " in type " << container.name << " with " << SIZE(container.element_names) << " elements\n"; //? 1</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>container<span class="Delimiter">.</span>element_names<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>container<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == name<span class="Delimiter">)</span> <span class="Identifier">return</span> i<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>container<span class="Delimiter">.</span>element_names<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>container<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == name<span class="Delimiter">)</span> <span class="Identifier">return</span> i<span class="Delimiter">;</span> <span class="Delimiter">}</span> raise << <span class="Constant">"unknown element "</span> << name << <span class="Constant">" in container "</span> << Type[t]<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">bool</span> is_numeric_location<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"0"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Comment">// used for chaining lexical scopes</span> +bool is_numeric_location<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"0"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Comment">// used for chaining lexical scopes</span> <span class="Identifier">return</span> is_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">bool</span> is_named_location<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_special_name<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> +bool is_named_location<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>is_special_name<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Identifier">return</span> !is_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">bool</span> is_raw<span class="Delimiter">(</span><span class="Normal">const</span> reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Comment">/*</span><span class="Comment">skip value+type</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>properties<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>first == <span class="Constant">"raw"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> +bool is_raw<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int i = <span class="Comment">/*</span><span class="Comment">skip value+type</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>properties<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>first == <span class="Constant">"raw"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">bool</span> is_special_name<span class="Delimiter">(</span><span class="Normal">const</span> string& s<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>s == <span class="Constant">"_"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>s == <span class="Constant">"0"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> +bool is_special_name<span class="Delimiter">(</span>const string& s<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>s == <span class="Constant">"_"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>s == <span class="Constant">"0"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Comment">// End is_special_name Cases</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -182,7 +181,7 @@ recipe main [ <span class="Delimiter">:(scenario transform_names_passes_raw)</span> <span class="Special">% Hide_warnings = true;</span> recipe main [ - <span class="Normal">x</span>:number/<span class="Special">raw <- </span>copy <span class="Constant">0</span> + x:number/<span class="Special">raw <- </span>copy <span class="Constant">0</span> ] <span class="traceAbsent">-name: assign x 1</span> <span class="traceContains">+warn: can't write to location 0 in 'x:number/raw <- copy 0'</span> @@ -191,14 +190,14 @@ recipe main [ <span class="Delimiter">:(scenario transform_names_warns_when_mixing_names_and_numeric_locations)</span> <span class="Special">% Hide_warnings = true;</span> recipe main [ - <span class="Normal">x</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:number + x:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:number ] <span class="traceContains">+warn: mixing variable names and numeric addresses in main</span> -<span class="Delimiter">:(scenario transform_names_warns_when_mixing_names_and_numeric_locations2)</span> +<span class="Delimiter">:(scenario transform_names_warns_when_mixing_names_and_numeric_locations_2)</span> <span class="Special">% Hide_warnings = true;</span> recipe main [ - <span class="Normal">x</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span> + x:number<span class="Special"> <- </span>copy <span class="Constant">1</span> <span class="Constant">1</span>:number<span class="Special"> <- </span>copy x:number ] <span class="traceContains">+warn: mixing variable names and numeric addresses in main</span> @@ -206,7 +205,7 @@ recipe main [ <span class="Delimiter">:(scenario transform_names_does_not_warn_when_mixing_names_and_raw_locations)</span> <span class="Special">% Hide_warnings = true;</span> recipe main [ - <span class="Normal">x</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:number/<span class="Special">raw</span> + x:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:number/<span class="Special">raw</span> ] <span class="traceAbsent">-warn: mixing variable names and numeric addresses in main</span> $warn: <span class="Constant">0</span> @@ -214,7 +213,7 @@ $warn: <span class="Constant">0</span> <span class="Delimiter">:(scenario transform_names_does_not_warn_when_mixing_names_and_literals)</span> <span class="Special">% Hide_warnings = true;</span> recipe main [ - <span class="Normal">x</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span> + x:number<span class="Special"> <- </span>copy <span class="Constant">1</span> ] <span class="traceAbsent">-warn: mixing variable names and numeric addresses in main</span> $warn: <span class="Constant">0</span> @@ -227,24 +226,24 @@ Type[point]<span class="Delimiter">.</span>element_names<span class="Delimiter"> Type[point]<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">"y"</span><span class="Delimiter">);</span> <span class="Delimiter">:(scenario transform_names_transforms_container_elements)</span> recipe main [ - <span class="Normal">p</span>:address:point<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># unsafe</span> - <span class="Normal">a</span>:number<span class="Special"> <- </span>get *p:address:point<span class="Delimiter">,</span> y:offset - <span class="Normal">b</span>:number<span class="Special"> <- </span>get *p:address:point<span class="Delimiter">,</span> x:offset + p:address:point<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># unsafe</span> + a:number<span class="Special"> <- </span>get *p:address:point<span class="Delimiter">,</span> y:offset + b:number<span class="Special"> <- </span>get *p:address:point<span class="Delimiter">,</span> x:offset ] <span class="traceContains">+name: element y of type point is at offset 1</span> <span class="traceContains">+name: element x of type point is at offset 0</span> <span class="Delimiter">:(after "Per-recipe Transforms")</span> <span class="Comment">// replace element names of containers with offsets</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"get"</span>] +if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"get"</span>] || inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"get-address"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<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>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": exactly 2 ingredients expected in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> + if <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> raise << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": expected ingredient 1 of "</span> << <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"get"</span>] ? <span class="Constant">"'get'"</span> : <span class="Constant">"'get-address'"</span><span class="Delimiter">)</span> << <span class="Constant">" to have type 'offset'; got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">.</span>find_first_not_of<span class="Delimiter">(</span><span class="Constant">"0123456789"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">.</span>find_first_not_of<span class="Delimiter">(</span><span class="Constant">"0123456789"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// since first non-address in base type must be a container, we don't have to canonize</span> type_ordinal base_type = skip_addresses<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>types<span class="Delimiter">);</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>set_value<span class="Delimiter">(</span>find_element_name<span class="Delimiter">(</span>base_type<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">));</span> @@ -256,8 +255,8 @@ recipe main [ <span class="Delimiter">:(scenarios transform)</span> <span class="Delimiter">:(scenario transform_names_handles_containers)</span> recipe main [ - <span class="Normal">a</span>:point<span class="Special"> <- </span>copy <span class="Constant">0</span> - <span class="Normal">b</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> + a:point<span class="Special"> <- </span>copy <span class="Constant">0</span> + b:number<span class="Special"> <- </span>copy <span class="Constant">0</span> ] <span class="traceContains">+name: assign a 1</span> <span class="traceContains">+name: assign b 3</span> @@ -270,20 +269,20 @@ recipe main [ <span class="Constant">12</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span> <span class="Constant">13</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span> <span class="Constant">14</span>:number<span class="Special"> <- </span>copy <span class="Constant">36</span> - <span class="Constant">20</span>:address:point<span class="Special"> <- </span>maybe-convert <span class="Constant">12</span>:number-<span class="Normal">or</span>-point/<span class="Special">raw</span><span class="Delimiter">,</span> p:variant <span class="Comment"># unsafe</span> + <span class="Constant">20</span>:address:point<span class="Special"> <- </span>maybe-convert <span class="Constant">12</span>:number-or-point/<span class="Special">raw</span><span class="Delimiter">,</span> p:variant <span class="Comment"># unsafe</span> ] <span class="traceContains">+name: variant p of type number-or-point has tag 1</span> <span class="traceContains">+mem: storing 13 in location 20</span> <span class="Delimiter">:(after "Per-recipe Transforms")</span> <span class="Comment">// convert variant names of exclusive containers</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"maybe-convert"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"maybe-convert"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": exactly 2 ingredients expected in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> assert<span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">.</span>find_first_not_of<span class="Delimiter">(</span><span class="Constant">"0123456789"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">.</span>find_first_not_of<span class="Delimiter">(</span><span class="Constant">"0123456789"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// since first non-address in base type must be an exclusive container, we don't have to canonize</span> type_ordinal base_type = skip_addresses<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>types<span class="Delimiter">);</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>set_value<span class="Delimiter">(</span>find_element_name<span class="Delimiter">(</span>base_type<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">));</span> diff --git a/html/043new.cc.html b/html/043new.cc.html index 1784aa97..4f4321e1 100644 --- a/html/043new.cc.html +++ b/html/043new.cc.html @@ -13,16 +13,15 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.SalientComment { color: #00ffff; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.SalientComment { color: #00ffff; } +.traceContains { color: #008000; } +.CommentedCode { color: #6c6c6c; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } -.CommentedCode { color: #6c6c6c; } +.Constant { color: #00a0a0; } --> </style> @@ -40,21 +39,20 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">:(scenario new)</span> <span class="Comment"># call new two times with identical arguments; you should get back different results</span> recipe main [ - <span class="Constant">1</span>:address:number/<span class="Special">raw <- </span><span class="Normal">new</span> number:type - <span class="Constant">2</span>:address:number/<span class="Special">raw <- </span><span class="Normal">new</span> number:type + <span class="Constant">1</span>:address:number/<span class="Special">raw <- </span>new number:type + <span class="Constant">2</span>:address:number/<span class="Special">raw <- </span>new number:type <span class="Constant">3</span>:boolean/<span class="Special">raw <- </span>equal <span class="Constant">1</span>:address:number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">2</span>:address:number/<span class="Special">raw</span> ] <span class="traceContains">+mem: storing 0 in location 3</span> <span class="Delimiter">:(before "End Globals")</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> Reserved_for_tests = <span class="Constant">1000</span><span class="Delimiter">;</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> Memory_allocated_until = Reserved_for_tests<span class="Delimiter">;</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> Initial_memory_per_routine = <span class="Constant">100000</span><span class="Delimiter">;</span> +long long int Memory_allocated_until = Reserved_for_tests<span class="Delimiter">;</span> +long long int Initial_memory_per_routine = <span class="Constant">100000</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End Setup")</span> Memory_allocated_until = Reserved_for_tests<span class="Delimiter">;</span> Initial_memory_per_routine = <span class="Constant">100000</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End routine Fields")</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> alloc<span class="Delimiter">,</span> alloc_max<span class="Delimiter">;</span> +long long int alloc<span class="Delimiter">,</span> alloc_max<span class="Delimiter">;</span> <span class="Delimiter">:(before "End routine Constructor")</span> alloc = Memory_allocated_until<span class="Delimiter">;</span> Memory_allocated_until += Initial_memory_per_routine<span class="Delimiter">;</span> @@ -67,20 +65,20 @@ trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimite Type_ordinal[<span class="Constant">"type"</span>] = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">:(after "Per-recipe Transforms")</span> <span class="Comment">// replace type names with type_ordinals</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"new"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span> +if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"new"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// End NEW Transform Special-cases</span> <span class="Comment">// first arg must be of type 'type'</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> + if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> raise << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": 'new' expects one or two ingredients</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> + if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> || inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> || inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> != <span class="Constant">"type"</span><span class="Delimiter">)</span> raise << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": first ingredient of 'new' should be a type, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">.</span>find<span class="Delimiter">(</span>inst<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> == Type_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">())</span> + if <span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">.</span>find<span class="Delimiter">(</span>inst<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> == Type_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">())</span> raise << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": unknown type "</span> << inst<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="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>set_value<span class="Delimiter">(</span>Type_ordinal[inst<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> trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"new"</span><span class="Delimiter">)</span> << inst<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> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name << end<span class="Delimiter">();</span> - <span class="Normal">end_new_transform</span>:<span class="Delimiter">;</span> + end_new_transform:<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="SalientComment">//:: Now implement the primitive recipe.</span> @@ -91,28 +89,28 @@ NEW<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"new"</span>] = NEW<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> NEW: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> || SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case NEW: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> || SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'new' requires one or two ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> + 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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'new' should be a type, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">// compute the space we need</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> size = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> array_length = <span class="Constant">0</span><span class="Delimiter">;</span> + long long int size = <span class="Constant">0</span><span class="Delimiter">;</span> + long long int array_length = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">{</span> vector<type_ordinal> type<span class="Delimiter">;</span> type<span class="Delimiter">.</span>push_back<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="Normal">if</span> <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> <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> <span class="Delimiter">{</span> <span class="Comment">// array</span> array_length = 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> trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"mem"</span><span class="Delimiter">)</span> << <span class="Constant">"array size is "</span> << array_length << end<span class="Delimiter">();</span> size = array_length*size_of<span class="Delimiter">(</span>type<span class="Delimiter">)</span> + <span class="Comment">/*</span><span class="Comment">space for length</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> + else <span class="Delimiter">{</span> <span class="Comment">// scalar</span> size = size_of<span class="Delimiter">(</span>type<span class="Delimiter">);</span> <span class="Delimiter">}</span> @@ -122,16 +120,16 @@ Recipe_ordinal[<span class="Constant">"new"</span>] = NEW<span class=" <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> - <span class="Normal">const</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> result = Current_routine<span class="Delimiter">-></span>alloc<span class="Delimiter">;</span> + const long long int result = Current_routine<span class="Delimiter">-></span>alloc<span class="Delimiter">;</span> trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"mem"</span><span class="Delimiter">)</span> << <span class="Constant">"new alloc: "</span> << result << end<span class="Delimiter">();</span> <span class="Comment">// save result</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="Comment">// initialize allocated space</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> address = result<span class="Delimiter">;</span> address < result+size<span class="Delimiter">;</span> ++address<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int address = result<span class="Delimiter">;</span> address < result+size<span class="Delimiter">;</span> ++address<span class="Delimiter">)</span> <span class="Delimiter">{</span> Memory[address] = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> <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> <span class="Delimiter">{</span> Memory[result] = array_length<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">// bump</span> @@ -154,9 +152,9 @@ Recipe_ordinal[<span class="Constant">"new"</span>] = NEW<span class=" <span class="CommentedCode">//? cerr << SIZE(Memory) << '\n'; //? 1</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> ensure_space<span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> size<span class="Delimiter">)</span> <span class="Delimiter">{</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> - <span class="Normal">if</span> <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>alloc + size > Current_routine<span class="Delimiter">-></span>alloc_max<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>alloc + size > Current_routine<span class="Delimiter">-></span>alloc_max<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// waste the remaining space and create a new chunk</span> Current_routine<span class="Delimiter">-></span>alloc = Memory_allocated_until<span class="Delimiter">;</span> Memory_allocated_until += Initial_memory_per_routine<span class="Delimiter">;</span> @@ -169,15 +167,15 @@ Recipe_ordinal[<span class="Constant">"new"</span>] = NEW<span class=" <span class="Special">% Memory_allocated_until = 10;</span> <span class="Special">% Memory[Memory_allocated_until] = 1;</span> recipe main [ - <span class="Constant">1</span>:address:number<span class="Special"> <- </span><span class="Normal">new</span> number:type + <span class="Constant">1</span>:address:number<span class="Special"> <- </span>new number:type <span class="Constant">2</span>:number<span class="Special"> <- </span>copy *<span class="Constant">1</span>:address:number ] <span class="traceContains">+mem: storing 0 in location 2</span> <span class="Delimiter">:(scenario new_array)</span> recipe main [ - <span class="Constant">1</span>:address:array:number/<span class="Special">raw <- </span><span class="Normal">new</span> number:type<span class="Delimiter">,</span> <span class="Constant">5</span> - <span class="Constant">2</span>:address:number/<span class="Special">raw <- </span><span class="Normal">new</span> number:type + <span class="Constant">1</span>:address:array:number/<span class="Special">raw <- </span>new number:type<span class="Delimiter">,</span> <span class="Constant">5</span> + <span class="Constant">2</span>:address:number/<span class="Special">raw <- </span>new number:type <span class="Constant">3</span>:number/<span class="Special">raw <- </span>subtract <span class="Constant">2</span>:address:number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">1</span>:address:array:number/<span class="Special">raw</span> ] <span class="traceContains">+run: 1:address:array:number/raw <- new number:type, 5</span> @@ -187,8 +185,8 @@ recipe main [ <span class="Delimiter">:(scenario new_empty_array)</span> recipe main [ - <span class="Constant">1</span>:address:array:number/<span class="Special">raw <- </span><span class="Normal">new</span> number:type<span class="Delimiter">,</span> <span class="Constant">0</span> - <span class="Constant">2</span>:address:number/<span class="Special">raw <- </span><span class="Normal">new</span> number:type + <span class="Constant">1</span>:address:array:number/<span class="Special">raw <- </span>new number:type<span class="Delimiter">,</span> <span class="Constant">0</span> + <span class="Constant">2</span>:address:number/<span class="Special">raw <- </span>new number:type <span class="Constant">3</span>:number/<span class="Special">raw <- </span>subtract <span class="Constant">2</span>:address:number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">1</span>:address:array:number/<span class="Special">raw</span> ] <span class="traceContains">+run: 1:address:array:number/raw <- new number:type, 0</span> @@ -199,14 +197,14 @@ recipe main [ <span class="Delimiter">:(scenario new_concurrent)</span> recipe f1 [ start-running f2:recipe - <span class="Constant">1</span>:address:number/<span class="Special">raw <- </span><span class="Normal">new</span> number:type + <span class="Constant">1</span>:address:number/<span class="Special">raw <- </span>new number:type <span class="Comment"># wait for f2 to complete</span> <span class="Delimiter">{</span> loop-unless <span class="Constant">4</span>:number/<span class="Special">raw</span> <span class="Delimiter">}</span> ] recipe f2 [ - <span class="Constant">2</span>:address:number/<span class="Special">raw <- </span><span class="Normal">new</span> number:type + <span class="Constant">2</span>:address:number/<span class="Special">raw <- </span>new number:type <span class="Comment"># hack: assumes scheduler implementation</span> <span class="Constant">3</span>:boolean/<span class="Special">raw <- </span>equal <span class="Constant">1</span>:address:number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">2</span>:address:number/<span class="Special">raw</span> <span class="Comment"># signal f2 complete</span> @@ -218,8 +216,8 @@ recipe f2 [ <span class="Delimiter">:(scenario new_overflow)</span> <span class="Special">% Initial_memory_per_routine = 2;</span> recipe main [ - <span class="Constant">1</span>:address:number/<span class="Special">raw <- </span><span class="Normal">new</span> number:type - <span class="Constant">2</span>:address:point/<span class="Special">raw <- </span><span class="Normal">new</span> point:type <span class="Comment"># not enough room in initial page</span> + <span class="Constant">1</span>:address:number/<span class="Special">raw <- </span>new number:type + <span class="Constant">2</span>:address:point/<span class="Special">raw <- </span>new point:type <span class="Comment"># not enough room in initial page</span> ] <span class="traceContains">+new: routine allocated memory from 1000 to 1002</span> <span class="traceContains">+new: routine allocated memory from 1002 to 1004</span> @@ -229,16 +227,16 @@ recipe main [ <span class="Delimiter">:(scenario new_reclaim)</span> recipe main [ - <span class="Constant">1</span>:address:number<span class="Special"> <- </span><span class="Normal">new</span> number:type + <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><span class="Normal">new</span> number:type <span class="Comment"># must be same size as abandoned memory to reuse</span> + <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<<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span><span class="Delimiter">,</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>> Free_list<span class="Delimiter">;</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> @@ -247,18 +245,18 @@ 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> -<span class="Normal">case</span> ABANDON: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case ABANDON: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'abandon' requires one ingredient, but got '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> + 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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'abandon' should be an address, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> + 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> - <span class="Normal">if</span> <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> + if <span class="Delimiter">(</span>types<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'abandon' should be an address, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -268,12 +266,12 @@ Recipe_ordinal[<span class="Constant">"abandon"</span>] = ABANDON<span <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> abandon<span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> address<span class="Delimiter">,</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> size<span class="Delimiter">)</span> <span class="Delimiter">{</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> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> curr = address<span class="Delimiter">;</span> curr < address+size<span class="Delimiter">;</span> ++curr<span class="Delimiter">)</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> @@ -281,18 +279,18 @@ Recipe_ordinal[<span class="Constant">"abandon"</span>] = ABANDON<span <span class="Delimiter">}</span> <span class="Delimiter">:(before "ensure_space(size)" following "case NEW")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>Free_list[size]<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> result = Free_list[size]<span class="Delimiter">;</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> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> curr = result+<span class="Constant">1</span><span class="Delimiter">;</span> curr < result+size<span class="Delimiter">;</span> ++curr<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Memory[curr] != <span class="Constant">0</span><span class="Delimiter">)</span> <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> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Memory[curr] != <span class="Constant">0</span><span class="Delimiter">)</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> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Comment">// always fatal</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> + 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> - <span class="Normal">else</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> @@ -301,9 +299,9 @@ Recipe_ordinal[<span class="Constant">"abandon"</span>] = ABANDON<span <span class="Delimiter">:(scenario new_differing_size_no_reclaim)</span> recipe main [ - <span class="Constant">1</span>:address:number<span class="Special"> <- </span><span class="Normal">new</span> number:type + <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><span class="Normal">new</span> number:type<span class="Delimiter">,</span> <span class="Constant">2</span> <span class="Comment"># different size</span> + <span class="Constant">2</span>:address:number<span class="Special"> <- </span>new number:type<span class="Delimiter">,</span> <span class="Constant">2</span> <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> @@ -311,9 +309,9 @@ recipe main [ <span class="Delimiter">:(scenario new_reclaim_array)</span> recipe main [ - <span class="Constant">1</span>:address:array:number<span class="Special"> <- </span><span class="Normal">new</span> number:type<span class="Delimiter">,</span> <span class="Constant">2</span> + <span class="Constant">1</span>:address:array:number<span class="Special"> <- </span>new number:type<span class="Delimiter">,</span> <span class="Constant">2</span> abandon <span class="Constant">1</span>:address:array:number - <span class="Constant">2</span>:address:array:number<span class="Special"> <- </span><span class="Normal">new</span> number:type<span class="Delimiter">,</span> <span class="Constant">2</span> + <span class="Constant">2</span>:address:array:number<span class="Special"> <- </span>new number:type<span class="Delimiter">,</span> <span class="Constant">2</span> <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> @@ -323,7 +321,7 @@ recipe main [ <span class="Delimiter">:(scenario new_string)</span> recipe main [ - <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span><span class="Normal">new</span> [abc def] + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new [abc def] <span class="Constant">2</span>:character<span class="Special"> <- </span>index *<span class="Constant">1</span>:address:array:character<span class="Delimiter">,</span> <span class="Constant">5</span> ] <span class="Comment"># number code for 'e'</span> @@ -331,7 +329,7 @@ recipe main [ <span class="Delimiter">:(scenario new_string_handles_unicode)</span> recipe main [ - <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span><span class="Normal">new</span> [a«c] + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new [a«c] <span class="Constant">2</span>:number<span class="Special"> <- </span>length *<span class="Constant">1</span>:address:array:character <span class="Constant">3</span>:character<span class="Special"> <- </span>index *<span class="Constant">1</span>:address:array:character<span class="Delimiter">,</span> <span class="Constant">1</span> ] @@ -340,7 +338,7 @@ recipe main [ <span class="traceContains">+mem: storing 171 in location 3</span> <span class="Delimiter">:(before "End NEW Transform Special-cases")</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> + if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && !inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && !inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">"literal-string"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -350,7 +348,7 @@ recipe main [ <span class="Delimiter">}</span> <span class="Delimiter">:(after "case NEW" following "Primitive Recipe Implementations")</span> -<span class="Normal">if</span> <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> +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> && 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>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">"literal-string"</span><span class="Delimiter">)</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_mu_string<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>name<span class="Delimiter">));</span> @@ -358,20 +356,20 @@ recipe main [ <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> new_mu_string<span class="Delimiter">(</span><span class="Normal">const</span> string& contents<span class="Delimiter">)</span> <span class="Delimiter">{</span> +long long int new_mu_string<span class="Delimiter">(</span>const string& contents<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// allocate an array just large enough for it</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> string_length = unicode_length<span class="Delimiter">(</span>contents<span class="Delimiter">);</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="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> result = Current_routine<span class="Delimiter">-></span>alloc<span class="Delimiter">;</span> + long long int result = Current_routine<span class="Delimiter">-></span>alloc<span class="Delimiter">;</span> Memory[Current_routine<span class="Delimiter">-></span>alloc++] = string_length<span class="Delimiter">;</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> curr = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">const</span> <span class="Normal">char</span>* raw_contents = contents<span class="Delimiter">.</span>c_str<span class="Delimiter">();</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < string_length<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">uint32_t</span> curr_character<span class="Delimiter">;</span> + long long int curr = <span class="Constant">0</span><span class="Delimiter">;</span> + const char* raw_contents = contents<span class="Delimiter">.</span>c_str<span class="Delimiter">();</span> + for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < string_length<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + uint32_t curr_character<span class="Delimiter">;</span> assert<span class="Delimiter">(</span>curr < SIZE<span class="Delimiter">(</span>contents<span class="Delimiter">));</span> tb_utf8_char_to_unicode<span class="Delimiter">(</span>&curr_character<span class="Delimiter">,</span> &raw_contents[curr]<span class="Delimiter">);</span> Memory[Current_routine<span class="Delimiter">-></span>alloc] = curr_character<span class="Delimiter">;</span> @@ -382,29 +380,62 @@ recipe main [ <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> +<span class="Comment">//: stash recognizes strings</span> + +<span class="Delimiter">:(scenario stash_string)</span> +recipe main [ + x:address:array:character<span class="Special"> <- </span>new [abc] + stash [foo: ]<span class="Delimiter">,</span> x:address:array:character +] +<span class="traceContains">+app: foo: abc</span> + +<span class="Delimiter">:(before "End print Special-cases(reagent r, data)")</span> +if <span class="Delimiter">(</span>is_mu_string<span class="Delimiter">(</span>r<span class="Delimiter">))</span> <span class="Delimiter">{</span> + assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>data<span class="Delimiter">));</span> + <span class="Identifier">return</span> read_mu_string<span class="Delimiter">(</span>data<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> +<span class="Delimiter">}</span> + <span class="Comment">//: Allocate more to routine when initializing a literal string</span> <span class="Delimiter">:(scenario new_string_overflow)</span> <span class="Special">% Initial_memory_per_routine = 2;</span> recipe main [ - <span class="Constant">1</span>:address:number/<span class="Special">raw <- </span><span class="Normal">new</span> number:type - <span class="Constant">2</span>:address:array:character/<span class="Special">raw <- </span><span class="Normal">new</span> [a] <span class="Comment"># not enough room in initial page, if you take the array size into account</span> + <span class="Constant">1</span>:address:number/<span class="Special">raw <- </span>new number:type + <span class="Constant">2</span>:address:array:character/<span class="Special">raw <- </span>new [a] <span class="Comment"># not enough room in initial page, if you take the array size into account</span> ] <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">//: helpers</span> <span class="Delimiter">:(code)</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> unicode_length<span class="Delimiter">(</span><span class="Normal">const</span> string& s<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">const</span> <span class="Normal">char</span>* in = s<span class="Delimiter">.</span>c_str<span class="Delimiter">();</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> result = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> curr = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>curr < SIZE<span class="Delimiter">(</span>s<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Comment">// carefully bounds-check on the string</span> +long long int unicode_length<span class="Delimiter">(</span>const string& s<span class="Delimiter">)</span> <span class="Delimiter">{</span> + const char* in = s<span class="Delimiter">.</span>c_str<span class="Delimiter">();</span> + long long int result = <span class="Constant">0</span><span class="Delimiter">;</span> + long long int curr = <span class="Constant">0</span><span class="Delimiter">;</span> + while <span class="Delimiter">(</span>curr < SIZE<span class="Delimiter">(</span>s<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Comment">// carefully bounds-check on the string</span> <span class="Comment">// before accessing its raw pointer</span> ++result<span class="Delimiter">;</span> curr += tb_utf8_char_length<span class="Delimiter">(</span>in[curr]<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> + +bool is_mu_string<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Identifier">return</span> SIZE<span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">)</span> == <span class="Constant">3</span> + && x<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>] + && x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)</span> == Type_ordinal[<span class="Constant">"array"</span>] + && x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">)</span> == Type_ordinal[<span class="Constant">"character"</span>]<span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +string read_mu_string<span class="Delimiter">(</span>long long int address<span class="Delimiter">)</span> <span class="Delimiter">{</span> + long long int size = Memory[address]<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>size == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">""</span><span class="Delimiter">;</span> + ostringstream tmp<span class="Delimiter">;</span> + for <span class="Delimiter">(</span>long long int curr = address+<span class="Constant">1</span><span class="Delimiter">;</span> curr <= address+size<span class="Delimiter">;</span> ++curr<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <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="Identifier">return</span> tmp<span class="Delimiter">.</span>str<span class="Delimiter">();</span> +<span class="Delimiter">}</span> </pre> </body> </html> diff --git a/html/044space.cc.html b/html/044space.cc.html index b538647a..99f80cd9 100644 --- a/html/044space.cc.html +++ b/html/044space.cc.html @@ -13,17 +13,16 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } +.traceAbsent { color: #c00000; } .SalientComment { color: #00ffff; } -.Constant { color: #00a0a0; } +.traceContains { color: #008000; } .CommentedCode { color: #6c6c6c; } .cSpecial { color: #008000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } -.traceAbsent { color: #c00000; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } --> </style> @@ -44,7 +43,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment"># then location 0 is really location 11, location 1 is really location 12, and so on.</span> recipe main [ <span class="Constant">10</span>:number<span class="Special"> <- </span>copy <span class="Constant">5</span> <span class="Comment"># pretend array; in practice we'll use new</span> - <span class="Normal">default</span>-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span> + default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span> <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">23</span> ] <span class="traceContains">+mem: storing 23 in location 12</span> @@ -56,7 +55,7 @@ recipe main [ <span class="Comment"># pretend array</span> <span class="Constant">1000</span>:number<span class="Special"> <- </span>copy <span class="Constant">5</span> <span class="Comment"># actual start of this recipe</span> - <span class="Normal">default</span>-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">1000</span> + default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">1000</span> <span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">3</span> <span class="Constant">8</span>:number/<span class="Special">raw <- </span>copy *<span class="Constant">1</span>:address:number ] @@ -65,20 +64,20 @@ recipe main [ <span class="SalientComment">//:: first disable name conversion for 'default-space'</span> <span class="Delimiter">:(scenario convert_names_passes_default_space)</span> recipe main [ - <span class="Normal">default</span>-space:number<span class="Delimiter">,</span> x:number<span class="Special"> <- </span>copy <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">1</span> + default-space:number<span class="Delimiter">,</span> x:number<span class="Special"> <- </span>copy <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">1</span> ] <span class="traceContains">+name: assign x 1</span> <span class="traceAbsent">-name: assign default-space 1</span> <span class="Delimiter">:(before "End Disqualified Reagents")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"default-space"</span><span class="Delimiter">)</span> +if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"default-space"</span><span class="Delimiter">)</span> x<span class="Delimiter">.</span>initialized = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End is_special_name Cases")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>s == <span class="Constant">"default-space"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> +if <span class="Delimiter">(</span>s == <span class="Constant">"default-space"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="SalientComment">//:: now implement space support</span> <span class="Delimiter">:(before "End call Fields")</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> default_space<span class="Delimiter">;</span> +long long int default_space<span class="Delimiter">;</span> <span class="Delimiter">:(before "End call Constructor")</span> default_space = <span class="Constant">0</span><span class="Delimiter">;</span> @@ -87,8 +86,9 @@ reagent r = absolutize<span class="Delimiter">(</span>x<span class="Delimiter">) <span class="Delimiter">:(code)</span> reagent absolutize<span class="Delimiter">(</span>reagent x<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cout << "absolutize " << x.to_string() << '\n'; //? 4</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">)</span> || is_dummy<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> x<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>initialized<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">)</span> || is_dummy<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> x<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"default-space"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> x<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>initialized<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">": reagent not initialized: "</span> << x<span class="Delimiter">.</span>original_string << end<span class="Delimiter">();</span> <span class="Identifier">return</span> x<span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -111,7 +111,7 @@ recipe main [ <span class="Comment"># pretend array</span> <span class="Constant">1000</span>:number<span class="Special"> <- </span>copy <span class="Constant">5</span> <span class="Comment"># actual start of this recipe</span> - <span class="Normal">default</span>-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">1000</span> + default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">1000</span> <span class="Constant">1</span>:address:point<span class="Special"> <- </span>copy <span class="Constant">12</span> <span class="Constant">9</span>:number/<span class="Special">raw <- </span>get *<span class="Constant">1</span>:address:point<span class="Delimiter">,</span> <span class="Constant">1</span>:offset ] @@ -131,7 +131,7 @@ recipe main [ <span class="Comment"># pretend array</span> <span class="Constant">1000</span>:number<span class="Special"> <- </span>copy <span class="Constant">5</span> <span class="Comment"># actual start of this recipe</span> - <span class="Normal">default</span>-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">1000</span> + default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">1000</span> <span class="Constant">1</span>:address:array:number<span class="Special"> <- </span>copy <span class="Constant">12</span> <span class="Constant">9</span>:number/<span class="Special">raw <- </span>index *<span class="Constant">1</span>:address:array:number<span class="Delimiter">,</span> <span class="Constant">1</span> ] @@ -145,36 +145,36 @@ tmp<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>pus <span class="Delimiter">:(scenario new_default_space)</span> recipe main [ - <span class="Normal">new</span>-<span class="Normal">default</span>-space - <span class="Normal">x</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> - <span class="Normal">y</span>:number<span class="Special"> <- </span>copy <span class="Constant">3</span> + new-default-space + x:number<span class="Special"> <- </span>copy <span class="Constant">0</span> + y:number<span class="Special"> <- </span>copy <span class="Constant">3</span> ] <span class="Comment"># allocate space for x and y, as well as the chaining slot at 0</span> <span class="traceContains">+mem: array size is 3</span> <span class="Delimiter">:(before "End Disqualified Reagents")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"number-of-locals"</span><span class="Delimiter">)</span> +if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"number-of-locals"</span><span class="Delimiter">)</span> x<span class="Delimiter">.</span>initialized = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End is_special_name Cases")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>s == <span class="Constant">"number-of-locals"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> +if <span class="Delimiter">(</span>s == <span class="Constant">"number-of-locals"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End Rewrite Instruction(curr)")</span> <span class="Comment">// rewrite `new-default-space` to</span> <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> -<span class="Normal">if</span> <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> +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> 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> - <span class="Normal">if</span> <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> - vector<<span class="Normal">double</span>> result<span class="Delimiter">;</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> + vector<double> result<span class="Delimiter">;</span> result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>Name[Recipe_ordinal[current_recipe_name<span class="Delimiter">()</span>]][<span class="Constant">""</span>]<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>result<span class="Delimiter">.</span>back<span class="Delimiter">()</span> == <span class="Constant">0</span><span class="Delimiter">)</span> + if <span class="Delimiter">(</span>result<span class="Delimiter">.</span>back<span class="Delimiter">()</span> == <span class="Constant">0</span><span class="Delimiter">)</span> raise << <span class="Constant">"no space allocated for default-space in recipe "</span> << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">"; are you using names</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(after "void write_memory(reagent x, vector<double> data)")</span> - <span class="Normal">if</span> <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> + 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> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": can't write to special name 'number-of-locals'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -190,8 +190,8 @@ recipe main [ ] recipe foo [ local-scope - <span class="Normal">x</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> - reply <span class="Normal">default</span>-space:address:array:location + x:number<span class="Special"> <- </span>copy <span class="Constant">34</span> + 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> @@ -204,28 +204,28 @@ 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> -<span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"local-scope"</span><span class="Delimiter">)</span> <span class="Delimiter">{</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> -<span class="Normal">void</span> try_reclaim_locals<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void try_reclaim_locals<span class="Delimiter">()</span> <span class="Delimiter">{</span> <span class="Comment">// only reclaim routines starting with 'local-scope'</span> - <span class="Normal">const</span> recipe_ordinal r = Recipe_ordinal[current_recipe_name<span class="Delimiter">()</span>]<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> - <span class="Normal">const</span> 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> - <span class="Normal">if</span> <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> + const recipe_ordinal r = Recipe_ordinal[current_recipe_name<span class="Delimiter">()</span>]<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</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> 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> -<span class="Normal">void</span> rewrite_default_space_instruction<span class="Delimiter">(</span>instruction& curr<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> - <span class="Normal">if</span> <span class="Delimiter">(</span>!curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<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> << end<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> - <span class="Normal">if</span> <span class="Delimiter">(</span>!curr<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<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> << end<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> @@ -233,14 +233,14 @@ try_reclaim_locals<span class="Delimiter">();</span> <span class="SalientComment">//:: helpers</span> <span class="Delimiter">:(code)</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> space_base<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> +long long int space_base<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</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="Delimiter">}</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> address<span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> offset<span class="Delimiter">,</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> base<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>base == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> offset<span class="Delimiter">;</span> <span class="Comment">// raw</span> +long long int address<span class="Delimiter">(</span>long long int offset<span class="Delimiter">,</span> long long int base<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>base == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> offset<span class="Delimiter">;</span> <span class="Comment">// raw</span> <span class="CommentedCode">//? cout << base << '\n'; //? 2</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>offset >= <span class="Normal">static_cast</span><<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>><span class="Delimiter">(</span>Memory[base]<span class="Delimiter">))</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>offset >= static_cast<long long int><span class="Delimiter">(</span>Memory[base]<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Comment">// todo: test</span> raise << <span class="Constant">"location "</span> << offset << <span class="Constant">" is out of bounds "</span> << Memory[base] << <span class="Constant">" at "</span> << base << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> @@ -248,8 +248,8 @@ try_reclaim_locals<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">:(after "void write_memory(reagent x, vector<double> data)")</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"default-space"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>data<span class="Delimiter">))</span> + if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"default-space"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>data<span class="Delimiter">))</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'default-space' should be of type address:array:location, but tried to write "</span> << to_string<span class="Delimiter">(</span>data<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>default_space = data<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> <span class="Identifier">return</span><span class="Delimiter">;</span> @@ -257,14 +257,14 @@ try_reclaim_locals<span class="Delimiter">();</span> <span class="Delimiter">:(scenario get_default_space)</span> recipe main [ - <span class="Normal">default</span>-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span> - <span class="Constant">1</span>:number/<span class="Special">raw <- </span>copy <span class="Normal">default</span>-space:address:array:location + default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span> + <span class="Constant">1</span>:number/<span class="Special">raw <- </span>copy default-space:address:array:location ] <span class="traceContains">+mem: storing 10 in location 1</span> <span class="Delimiter">:(after "vector<double> read_memory(reagent x)")</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"default-space"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - vector<<span class="Normal">double</span>> result<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"default-space"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + vector<double> result<span class="Delimiter">;</span> result<span class="Delimiter">.</span>push_back<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="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> diff --git a/html/045space_surround.cc.html b/html/045space_surround.cc.html index a2705517..6ceb3696 100644 --- a/html/045space_surround.cc.html +++ b/html/045space_surround.cc.html @@ -13,14 +13,13 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.traceContains { color: #008000; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } --> </style> @@ -43,7 +42,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } recipe main [ <span class="Constant">10</span>:number<span class="Special"> <- </span>copy <span class="Constant">5</span> <span class="Comment"># pretend array</span> <span class="Constant">20</span>:number<span class="Special"> <- </span>copy <span class="Constant">5</span> <span class="Comment"># pretend array</span> - <span class="Normal">default</span>-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span> + default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span> <span class="Constant">0</span>:address:array:location/names:dummy<span class="Special"> <- </span>copy <span class="Constant">20</span> <span class="Comment"># later layers will explain the /names: property</span> <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">32</span> <span class="Constant">1</span>:number/space:<span class="Constant">1</span><span class="Special"> <- </span>copy <span class="Constant">33</span> @@ -60,22 +59,22 @@ recipe main [ <span class="Comment">//: one.</span> <span class="Delimiter">:(replace{} "long long int space_base(const reagent& x)")</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> space_base<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> +long long int space_base<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> space_base<span class="Delimiter">(</span>x<span class="Delimiter">,</span> space_index<span class="Delimiter">(</span>x<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="Delimiter">}</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> space_base<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">,</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> space_index<span class="Delimiter">,</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> base<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>space_index == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +long long int space_base<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">,</span> long long int space_index<span class="Delimiter">,</span> long long int base<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>space_index == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> base<span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> result = space_base<span class="Delimiter">(</span>x<span class="Delimiter">,</span> space_index-<span class="Constant">1</span><span class="Delimiter">,</span> Memory[base+<span class="Constant">1</span>]<span class="Delimiter">);</span> + long long int result = space_base<span class="Delimiter">(</span>x<span class="Delimiter">,</span> space_index-<span class="Constant">1</span><span class="Delimiter">,</span> Memory[base+<span class="Constant">1</span>]<span class="Delimiter">);</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> space_index<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Comment">/*</span><span class="Comment">skip name:type</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>first == <span class="Constant">"space"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> +long long int space_index<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int i = <span class="Comment">/*</span><span class="Comment">skip name:type</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>first == <span class="Constant">"space"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": /space metadata should take exactly one value in "</span> << x<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span> to_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> <span class="Delimiter">}</span> @@ -85,7 +84,7 @@ recipe main [ <span class="Delimiter">:(scenario permit_space_as_variable_name)</span> recipe main [ - <span class="Normal">space</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> + space:number<span class="Special"> <- </span>copy <span class="Constant">0</span> ] </pre> </body> diff --git a/html/046closure_name.cc.html b/html/046closure_name.cc.html index 92e39280..5b612e50 100644 --- a/html/046closure_name.cc.html +++ b/html/046closure_name.cc.html @@ -13,15 +13,14 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.CommentedCode { color: #6c6c6c; } +.Constant { color: #00a0a0; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } -.CommentedCode { color: #6c6c6c; } +.traceContains { color: #008000; } --> </style> @@ -40,24 +39,24 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">:(scenario closure)</span> recipe main [ - <span class="Normal">default</span>-space:address:array:location<span class="Special"> <- </span><span class="Normal">new</span> location:type<span class="Delimiter">,</span> <span class="Constant">30</span> - <span class="Constant">1</span>:address:array:location/names:<span class="Normal">new</span>-counter<span class="Special"> <- </span><span class="Normal">new</span>-counter - <span class="Constant">2</span>:number/<span class="Special">raw <- </span>increment-counter <span class="Constant">1</span>:address:array:location/names:<span class="Normal">new</span>-counter - <span class="Constant">3</span>:number/<span class="Special">raw <- </span>increment-counter <span class="Constant">1</span>:address:array:location/names:<span class="Normal">new</span>-counter + default-space:address:array:location<span class="Special"> <- </span>new location:type<span class="Delimiter">,</span> <span class="Constant">30</span> + <span class="Constant">1</span>:address:array:location/names:new-counter<span class="Special"> <- </span>new-counter + <span class="Constant">2</span>:number/<span class="Special">raw <- </span>increment-counter <span class="Constant">1</span>:address:array:location/names:new-counter + <span class="Constant">3</span>:number/<span class="Special">raw <- </span>increment-counter <span class="Constant">1</span>:address:array:location/names:new-counter ] -recipe <span class="Normal">new</span>-counter [ - <span class="Normal">default</span>-space:address:array:location<span class="Special"> <- </span><span class="Normal">new</span> location:type<span class="Delimiter">,</span> <span class="Constant">30</span> - <span class="Normal">x</span>:number<span class="Special"> <- </span>copy <span class="Constant">23</span> - <span class="Normal">y</span>:number<span class="Special"> <- </span>copy <span class="Constant">3</span> <span class="Comment"># variable that will be incremented</span> - reply <span class="Normal">default</span>-space:address:array:location +recipe new-counter [ + default-space:address:array:location<span class="Special"> <- </span>new location:type<span class="Delimiter">,</span> <span class="Constant">30</span> + x:number<span class="Special"> <- </span>copy <span class="Constant">23</span> + y:number<span class="Special"> <- </span>copy <span class="Constant">3</span> <span class="Comment"># variable that will be incremented</span> + reply default-space:address:array:location ] recipe increment-counter [ - <span class="Normal">default</span>-space:address:array:location<span class="Special"> <- </span><span class="Normal">new</span> location:type<span class="Delimiter">,</span> <span class="Constant">30</span> - <span class="Constant">0</span>:address:array:location/names:<span class="Normal">new</span>-counter<span class="Special"> <- </span>next-ingredient <span class="Comment"># outer space must be created by 'new-counter' above</span> - <span class="Normal">y</span>:number/space:<span class="Constant">1</span><span class="Special"> <- </span>add y:number/space:<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">1</span> <span class="Comment"># increment</span> - <span class="Normal">y</span>:number<span class="Special"> <- </span>copy <span class="Constant">234</span> <span class="Comment"># dummy</span> + default-space:address:array:location<span class="Special"> <- </span>new location:type<span class="Delimiter">,</span> <span class="Constant">30</span> + <span class="Constant">0</span>:address:array:location/names:new-counter<span class="Special"> <- </span>next-ingredient <span class="Comment"># outer space must be created by 'new-counter' above</span> + y:number/space:<span class="Constant">1</span><span class="Special"> <- </span>add y:number/space:<span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">1</span> <span class="Comment"># increment</span> + y:number<span class="Special"> <- </span>copy <span class="Constant">234</span> <span class="Comment"># dummy</span> reply y:number/space:<span class="Constant">1</span> ] @@ -74,14 +73,14 @@ map<recipe_ordinal<span class="Delimiter">,</span> recipe_ordinal> Surroun Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>collect_surrounding_spaces<span class="Delimiter">);</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> collect_surrounding_spaces<span class="Delimiter">(</span><span class="Normal">const</span> recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">const</span> instruction& inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>is_label<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>name != <span class="Constant">"0"</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>types<span class="Delimiter">)</span> != <span class="Constant">3</span> +void collect_surrounding_spaces<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <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>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<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>i<span class="Delimiter">);</span> + if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>is_label<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>name != <span class="Constant">"0"</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>types<span class="Delimiter">)</span> != <span class="Constant">3</span> || inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<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>] || inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)</span> != Type_ordinal[<span class="Constant">"array"</span>] || inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">)</span> != Type_ordinal[<span class="Constant">"location"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -89,13 +88,13 @@ map<recipe_ordinal<span class="Delimiter">,</span> recipe_ordinal> Surroun <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> vector<string> s = property<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">),</span> <span class="Constant">"names"</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>s<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>s<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> raise << <span class="Constant">"slot 0 requires a /names property in recipe "</span> << Recipe[r]<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>s<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span> raise << <span class="Constant">"slot 0 should have a single value in /names, but got "</span> << inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>s<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span> raise << <span class="Constant">"slot 0 should have a single value in /names, but got "</span> << inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> string surrounding_recipe_name = s<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Surrounding_space<span class="Delimiter">.</span>find<span class="Delimiter">(</span>r<span class="Delimiter">)</span> != Surrounding_space<span class="Delimiter">.</span>end<span class="Delimiter">()</span> + if <span class="Delimiter">(</span>Surrounding_space<span class="Delimiter">.</span>find<span class="Delimiter">(</span>r<span class="Delimiter">)</span> != Surrounding_space<span class="Delimiter">.</span>end<span class="Delimiter">()</span> && Surrounding_space[r] != Recipe_ordinal[surrounding_recipe_name]<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << <span class="Constant">"recipe "</span> << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">" can have only one 'surrounding' recipe but has "</span> << Recipe[Surrounding_space[r]]<span class="Delimiter">.</span>name << <span class="Constant">" and "</span> << surrounding_recipe_name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> @@ -110,16 +109,16 @@ map<recipe_ordinal<span class="Delimiter">,</span> recipe_ordinal> Surroun <span class="Comment">//: /space properties.</span> <span class="Delimiter">:(replace{} "long long int lookup_name(const reagent& r, const recipe_ordinal default_recipe)")</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> lookup_name<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">,</span> <span class="Normal">const</span> recipe_ordinal default_recipe<span class="Delimiter">)</span> <span class="Delimiter">{</span> +long long int lookup_name<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">,</span> const recipe_ordinal default_recipe<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cout << "AAA " << default_recipe << " " << Recipe[default_recipe].name << '\n'; //? 2</span> <span class="CommentedCode">//? cout << "AAA " << x.to_string() << '\n'; //? 1</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!has_property<span class="Delimiter">(</span>x<span class="Delimiter">,</span> <span class="Constant">"space"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Name[default_recipe]<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> raise << <span class="Constant">"name not found: "</span> << x<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>!has_property<span class="Delimiter">(</span>x<span class="Delimiter">,</span> <span class="Constant">"space"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Name[default_recipe]<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> raise << <span class="Constant">"name not found: "</span> << x<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span> Name[default_recipe][x<span class="Delimiter">.</span>name]<span class="Delimiter">;</span> <span class="Delimiter">}</span> vector<string> p = property<span class="Delimiter">(</span>x<span class="Delimiter">,</span> <span class="Constant">"space"</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>p<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> raise << <span class="Constant">"/space property should have exactly one (non-negative integer) value</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> n = to_integer<span class="Delimiter">(</span>p<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>p<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> raise << <span class="Constant">"/space property should have exactly one (non-negative integer) value</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + long long int n = to_integer<span class="Delimiter">(</span>p<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> assert<span class="Delimiter">(</span>n >= <span class="Constant">0</span><span class="Delimiter">);</span> recipe_ordinal surrounding_recipe = lookup_surrounding_recipe<span class="Delimiter">(</span>default_recipe<span class="Delimiter">,</span> n<span class="Delimiter">);</span> set<recipe_ordinal> done<span class="Delimiter">;</span> @@ -129,11 +128,11 @@ map<recipe_ordinal<span class="Delimiter">,</span> recipe_ordinal> Surroun <span class="Comment">// If the recipe we need to lookup this name in doesn't have names done yet,</span> <span class="Comment">// recursively call transform_names on it.</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> lookup_name<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">,</span> <span class="Normal">const</span> recipe_ordinal r<span class="Delimiter">,</span> set<recipe_ordinal>& done<span class="Delimiter">,</span> vector<recipe_ordinal>& path<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Name[r]<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> Name[r][x<span class="Delimiter">.</span>name]<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>done<span class="Delimiter">.</span>find<span class="Delimiter">(</span>r<span class="Delimiter">)</span> != done<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> +long long int lookup_name<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">,</span> const recipe_ordinal r<span class="Delimiter">,</span> set<recipe_ordinal>& done<span class="Delimiter">,</span> vector<recipe_ordinal>& path<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!Name[r]<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> Name[r][x<span class="Delimiter">.</span>name]<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>done<span class="Delimiter">.</span>find<span class="Delimiter">(</span>r<span class="Delimiter">)</span> != done<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> raise << <span class="Constant">"can't compute address of "</span> << x<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">" because "</span> << end<span class="Delimiter">();</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>path<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int i = <span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>path<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << path<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i-<span class="Constant">1</span><span class="Delimiter">)</span> << <span class="Constant">" requires computing names of "</span> << path<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> raise << path<span class="Delimiter">.</span>at<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>path<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">)</span> << <span class="Constant">" requires computing names of "</span> << r << <span class="Constant">"..ad infinitum</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> @@ -146,9 +145,9 @@ map<recipe_ordinal<span class="Delimiter">,</span> recipe_ordinal> Surroun <span class="Identifier">return</span> Name[r][x<span class="Delimiter">.</span>name]<span class="Delimiter">;</span> <span class="Delimiter">}</span> -recipe_ordinal lookup_surrounding_recipe<span class="Delimiter">(</span><span class="Normal">const</span> recipe_ordinal r<span class="Delimiter">,</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> n<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>n == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> r<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Surrounding_space<span class="Delimiter">.</span>find<span class="Delimiter">(</span>r<span class="Delimiter">)</span> == Surrounding_space<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> +recipe_ordinal lookup_surrounding_recipe<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">,</span> long long int n<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>n == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> r<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>Surrounding_space<span class="Delimiter">.</span>find<span class="Delimiter">(</span>r<span class="Delimiter">)</span> == Surrounding_space<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> raise << <span class="Constant">"don't know surrounding recipe of "</span> << Recipe[r]<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -158,14 +157,14 @@ recipe_ordinal lookup_surrounding_recipe<span class="Delimiter">(</span><span cl <span class="Comment">//: weaken use-before-set warnings just a tad</span> <span class="Delimiter">:(replace{} "bool already_transformed(const reagent& r, const map<string, long long int>& names)")</span> -<span class="Normal">bool</span> already_transformed<span class="Delimiter">(</span><span class="Normal">const</span> reagent& r<span class="Delimiter">,</span> <span class="Normal">const</span> map<string<span class="Delimiter">,</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>>& names<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">"space"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> +bool already_transformed<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">,</span> const map<string<span class="Delimiter">,</span> long long int>& names<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">"space"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> vector<string> p = property<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">"space"</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>p<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>p<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << <span class="Constant">"/space property should have exactly one (non-negative integer) value in "</span> << r<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>p<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> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>p<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> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Identifier">return</span> names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>r<span class="Delimiter">.</span>name<span class="Delimiter">)</span> != names<span class="Delimiter">.</span>end<span class="Delimiter">();</span> <span class="Delimiter">}</span> diff --git a/html/047global.cc.html b/html/047global.cc.html index 4a1a84f1..c90a4500 100644 --- a/html/047global.cc.html +++ b/html/047global.cc.html @@ -13,14 +13,13 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.traceContains { color: #008000; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } --> </style> @@ -44,7 +43,7 @@ recipe main [ <span class="Constant">20</span>:number<span class="Special"> <- </span>copy <span class="Constant">5</span> <span class="Comment"># actual start of this recipe</span> global-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">20</span> - <span class="Normal">default</span>-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span> + default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span> <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">23</span> <span class="Constant">1</span>:number/space:global<span class="Special"> <- </span>copy <span class="Constant">24</span> ] @@ -53,21 +52,21 @@ recipe main [ <span class="Comment">//: to support it, create another special variable called global space</span> <span class="Delimiter">:(before "End Disqualified Reagents")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"global-space"</span><span class="Delimiter">)</span> +if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"global-space"</span><span class="Delimiter">)</span> x<span class="Delimiter">.</span>initialized = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End is_special_name Cases")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>s == <span class="Constant">"global-space"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> +if <span class="Delimiter">(</span>s == <span class="Constant">"global-space"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Comment">//: writes to this variable go to a field in the current routine</span> <span class="Delimiter">:(before "End routine Fields")</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> global_space<span class="Delimiter">;</span> +long long int global_space<span class="Delimiter">;</span> <span class="Delimiter">:(before "End routine Constructor")</span> global_space = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">:(after "void write_memory(reagent x, vector<double> data)")</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"global-space"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>data<span class="Delimiter">))</span> + if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"global-space"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>data<span class="Delimiter">))</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'global-space' should be of type address:array:location, but tried to write "</span> << to_string<span class="Delimiter">(</span>data<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>global_space<span class="Delimiter">)</span> + if <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>global_space<span class="Delimiter">)</span> raise << <span class="Constant">"routine already has a global-space; you can't over-write your globals"</span> << end<span class="Delimiter">();</span> Current_routine<span class="Delimiter">-></span>global_space = data<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> <span class="Identifier">return</span><span class="Delimiter">;</span> @@ -75,8 +74,8 @@ global_space = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Comment">//: now marking variables as /space:global looks them up inside this field</span> <span class="Delimiter">:(after "long long int space_base(const reagent& x)")</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_global<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Current_routine<span class="Delimiter">-></span>global_space<span class="Delimiter">)</span> + if <span class="Delimiter">(</span>is_global<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!Current_routine<span class="Delimiter">-></span>global_space<span class="Delimiter">)</span> raise << <span class="Constant">"routine has no global space</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span> Current_routine<span class="Delimiter">-></span>global_space<span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -87,22 +86,22 @@ global_space = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">:(scenario global_space_with_names)</span> <span class="Special">% Hide_warnings = true;</span> recipe main [ - global-space:address:array:location<span class="Special"> <- </span><span class="Normal">new</span> location:type<span class="Delimiter">,</span> <span class="Constant">10</span> - <span class="Normal">x</span>:number<span class="Special"> <- </span>copy <span class="Constant">23</span> + global-space:address:array:location<span class="Special"> <- </span>new location:type<span class="Delimiter">,</span> <span class="Constant">10</span> + x:number<span class="Special"> <- </span>copy <span class="Constant">23</span> <span class="Constant">1</span>:number/space:global<span class="Special"> <- </span>copy <span class="Constant">24</span> ] <span class="Comment"># don't warn that we're mixing numeric addresses and names</span> $warn: <span class="Constant">0</span> <span class="Delimiter">:(after "bool is_numeric_location(const reagent& x)")</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_global<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>is_global<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Comment">//: helpers</span> <span class="Delimiter">:(code)</span> -<span class="Normal">bool</span> is_global<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Comment">/*</span><span class="Comment">skip name:type</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>first == <span class="Constant">"space"</span><span class="Delimiter">)</span> +bool is_global<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int i = <span class="Comment">/*</span><span class="Comment">skip name:type</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>first == <span class="Constant">"space"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> !x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">"global"</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> diff --git a/html/048typecheck.cc.html b/html/048typecheck.cc.html index 2cff827d..f39bc4bf 100644 --- a/html/048typecheck.cc.html +++ b/html/048typecheck.cc.html @@ -13,14 +13,13 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.Constant { color: #00a0a0; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } +.traceContains { color: #008000; } --> </style> @@ -43,8 +42,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">:(scenario transform_types_warns_on_reusing_name_with_different_type)</span> <span class="Special">% Hide_warnings = true;</span> recipe main [ - <span class="Normal">x</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span> - <span class="Normal">x</span>:boolean<span class="Special"> <- </span>copy <span class="Constant">1</span> + x:number<span class="Special"> <- </span>copy <span class="Constant">1</span> + x:boolean<span class="Special"> <- </span>copy <span class="Constant">1</span> ] <span class="traceContains">+warn: x used with multiple types in main</span> @@ -52,43 +51,43 @@ recipe main [ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>transform_types<span class="Delimiter">);</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> transform_types<span class="Delimiter">(</span><span class="Normal">const</span> recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void transform_types<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> map<string<span class="Delimiter">,</span> vector<type_ordinal> > metadata<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <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>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> instruction& inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> in = <span class="Constant">0</span><span class="Delimiter">;</span> in < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++in<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int in = <span class="Constant">0</span><span class="Delimiter">;</span> in < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++in<span class="Delimiter">)</span> <span class="Delimiter">{</span> deduce_missing_type<span class="Delimiter">(</span>metadata<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">));</span> check_metadata<span class="Delimiter">(</span>metadata<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">),</span> r<span class="Delimiter">);</span> <span class="Delimiter">}</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> out = <span class="Constant">0</span><span class="Delimiter">;</span> out < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++out<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int out = <span class="Constant">0</span><span class="Delimiter">;</span> out < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++out<span class="Delimiter">)</span> <span class="Delimiter">{</span> deduce_missing_type<span class="Delimiter">(</span>metadata<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">));</span> check_metadata<span class="Delimiter">(</span>metadata<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">),</span> r<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> check_metadata<span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> vector<type_ordinal> >& metadata<span class="Delimiter">,</span> <span class="Normal">const</span> reagent& x<span class="Delimiter">,</span> <span class="Normal">const</span> recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> +void check_metadata<span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> vector<type_ordinal> >& metadata<span class="Delimiter">,</span> const reagent& x<span class="Delimiter">,</span> const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// if you use raw locations you're probably doing something unsafe</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// will throw a more precise warning elsewhere</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>metadata<span class="Delimiter">.</span>find<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">)</span> == metadata<span class="Delimiter">.</span>end<span class="Delimiter">())</span> + if <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// will throw a more precise warning elsewhere</span> + if <span class="Delimiter">(</span>metadata<span class="Delimiter">.</span>find<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">)</span> == metadata<span class="Delimiter">.</span>end<span class="Delimiter">())</span> metadata[x<span class="Delimiter">.</span>name] = x<span class="Delimiter">.</span>types<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>metadata[x<span class="Delimiter">.</span>name] != x<span class="Delimiter">.</span>types<span class="Delimiter">)</span> + if <span class="Delimiter">(</span>metadata[x<span class="Delimiter">.</span>name] != x<span class="Delimiter">.</span>types<span class="Delimiter">)</span> raise << x<span class="Delimiter">.</span>name << <span class="Constant">" used with multiple types in "</span> << Recipe[r]<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">:(scenario transform_types_fills_in_missing_types)</span> recipe main [ - <span class="Normal">x</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span> - <span class="Normal">y</span>:number<span class="Special"> <- </span>add x<span class="Delimiter">,</span> <span class="Constant">1</span> + x:number<span class="Special"> <- </span>copy <span class="Constant">1</span> + y:number<span class="Special"> <- </span>add x<span class="Delimiter">,</span> <span class="Constant">1</span> ] <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> deduce_missing_type<span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> vector<type_ordinal> >& metadata<span class="Delimiter">,</span> reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>metadata<span class="Delimiter">.</span>find<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">)</span> == metadata<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> +void deduce_missing_type<span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> vector<type_ordinal> >& metadata<span class="Delimiter">,</span> reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>metadata<span class="Delimiter">.</span>find<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">)</span> == metadata<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> copy<span class="Delimiter">(</span>metadata[x<span class="Delimiter">.</span>name]<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> metadata[x<span class="Delimiter">.</span>name]<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> inserter<span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">,</span> x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>begin<span class="Delimiter">()));</span> assert<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>resize<span class="Delimiter">(</span>metadata[x<span class="Delimiter">.</span>name]<span class="Delimiter">.</span>size<span class="Delimiter">());</span> @@ -97,13 +96,13 @@ recipe main [ <span class="Delimiter">:(scenario transform_types_fills_in_missing_types_in_product)</span> recipe main [ - <span class="Normal">x</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span> + x:number<span class="Special"> <- </span>copy <span class="Constant">1</span> x<span class="Special"> <- </span>copy <span class="Constant">2</span> ] <span class="Delimiter">:(scenario transform_types_fills_in_missing_types_in_product_and_ingredient)</span> recipe main [ - <span class="Normal">x</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span> + x:number<span class="Special"> <- </span>copy <span class="Constant">1</span> x<span class="Special"> <- </span>add x<span class="Delimiter">,</span> <span class="Constant">1</span> ] <span class="traceContains">+mem: storing 2 in location 1</span> @@ -112,14 +111,14 @@ recipe main [ <span class="Special">% Hide_warnings = true;</span> recipe main [ x<span class="Special"> <- </span>copy <span class="Constant">1</span> - <span class="Normal">x</span>:number<span class="Special"> <- </span>copy <span class="Constant">2</span> + x:number<span class="Special"> <- </span>copy <span class="Constant">2</span> ] <span class="traceContains">+warn: missing type in 'x <- copy 1'</span> <span class="Delimiter">:(scenario typo_in_address_type_warns)</span> <span class="Special">% Hide_warnings = true;</span> recipe main [ - <span class="Normal">y</span>:address:charcter<span class="Special"> <- </span><span class="Normal">new</span> character:type + y:address:charcter<span class="Special"> <- </span>new character:type *y<span class="Special"> <- </span>copy <span class="Constant">67</span> ] <span class="traceContains">+warn: unknown type: charcter</span> diff --git a/html/050scenario.cc.html b/html/050scenario.cc.html index f2b7c24f..db392a7c 100644 --- a/html/050scenario.cc.html +++ b/html/050scenario.cc.html @@ -13,17 +13,16 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.SalientComment { color: #00ffff; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } +.SalientComment { color: #00ffff; } +.Identifier { color: #804000; } .traceAbsent { color: #c00000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } -.Identifier { color: #804000; } .CommentedCode { color: #6c6c6c; } +.Constant { color: #00a0a0; } +.traceContains { color: #008000; } --> </style> @@ -74,23 +73,23 @@ scenario foo [ scenario foo [ run [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">13</span> - trace [a]<span class="Delimiter">,</span> [a b c] + trace <span class="Constant">1</span><span class="Delimiter">,</span> [a]<span class="Delimiter">,</span> [a b c] ] memory-should-contain [ <span class="Constant">1</span><span class="Special"> <- </span><span class="Constant">13</span> ] trace-should-contain [ - <span class="Normal">a</span>: a b c + a: a b c ] - trace-should-<span class="Normal">not</span>-contain [ - <span class="Normal">a</span>: x y z + trace-should-not-contain [ + a: x y z ] ] <span class="SalientComment">//:: Core data structure</span> <span class="Delimiter">:(before "End Types")</span> -<span class="Normal">struct</span> scenario <span class="Delimiter">{</span> +struct scenario <span class="Delimiter">{</span> string name<span class="Delimiter">;</span> string to_run<span class="Delimiter">;</span> <span class="Delimiter">};</span> @@ -102,7 +101,7 @@ vector<scenario> Scenarios<span class="Delimiter">;</span> <span class="Comment">//: Simply store the text of the scenario.</span> <span class="Delimiter">:(before "End Command Handlers")</span> -<span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>command == <span class="Constant">"scenario"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +else if <span class="Delimiter">(</span>command == <span class="Constant">"scenario"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> Scenarios<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>parse_scenario<span class="Delimiter">(</span>in<span class="Delimiter">));</span> <span class="Delimiter">}</span> @@ -135,7 +134,7 @@ scenario foo [ <span class="Delimiter">:(scenario read_scenario_with_bracket_in_comment_in_nested_string)</span> scenario foo [ - <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span><span class="Normal">new</span> [<span class="Comment"># not a comment]</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new [<span class="Comment"># not a comment]</span> ] <span class="traceContains">+run: 1:address:array:character <- new [# not a comment]</span> @@ -143,35 +142,35 @@ scenario foo [ <span class="Comment">//: Treat the text of the scenario as a regular series of instructions.</span> <span class="Delimiter">:(before "End Tests")</span> -<span class="Normal">time_t</span> mu_time<span class="Delimiter">;</span> time<span class="Delimiter">(</span>&mu_time<span class="Delimiter">);</span> +time_t mu_time<span class="Delimiter">;</span> time<span class="Delimiter">(</span>&mu_time<span class="Delimiter">);</span> cerr << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">Mu tests: "</span> << ctime<span class="Delimiter">(</span>&mu_time<span class="Delimiter">);</span> -<span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Scenarios<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <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>Scenarios<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << Passed << '\n'; //? 1</span> -<span class="CommentedCode">//? cerr << i << ": " << Scenarios.at(i).name << '\n'; //? 6</span> +<span class="CommentedCode">//? cerr << i << ": " << Scenarios.at(i).name << '\n'; //? 7</span> run_mu_scenario<span class="Delimiter">(</span>Scenarios<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Passed<span class="Delimiter">)</span> cerr << <span class="Constant">"."</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>Passed<span class="Delimiter">)</span> cerr << <span class="Constant">"."</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">//: Convenience: run a single named scenario.</span> <span class="Delimiter">:(after "Test Runs")</span> -<span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Scenarios<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Scenarios<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name == argv[argc-<span class="Constant">1</span>]<span class="Delimiter">)</span> <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>Scenarios<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Scenarios<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name == argv[argc-<span class="Constant">1</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span> run_mu_scenario<span class="Delimiter">(</span>Scenarios<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Passed<span class="Delimiter">)</span> cerr << <span class="Constant">".</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>Passed<span class="Delimiter">)</span> cerr << <span class="Constant">".</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Globals")</span> -<span class="Normal">const</span> scenario* Current_scenario = <span class="Constant">NULL</span><span class="Delimiter">;</span> +const scenario* Current_scenario = <span class="Constant">NULL</span><span class="Delimiter">;</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> run_mu_scenario<span class="Delimiter">(</span><span class="Normal">const</span> scenario& s<span class="Delimiter">)</span> <span class="Delimiter">{</span> +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> - <span class="Normal">bool</span> not_already_inside_test = !Trace_stream<span class="Delimiter">;</span> + bool not_already_inside_test = !Trace_stream<span class="Delimiter">;</span> <span class="CommentedCode">//? cerr << s.name << '\n'; //? 12</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>not_already_inside_test<span class="Delimiter">)</span> <span class="Delimiter">{</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 = <span class="Normal">new</span> trace_stream<span class="Delimiter">;</span> + Trace_stream = new trace_stream<span class="Delimiter">;</span> setup<span class="Delimiter">();</span> <span class="Delimiter">}</span> assert<span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> @@ -179,12 +178,12 @@ cerr << <span class="Constant">"</span><span class="cSpecial">\n</spa bind_special_scenario_names<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> transform_all<span class="Delimiter">();</span> run<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>front<span class="Delimiter">());</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>not_already_inside_test && Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>not_already_inside_test && Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span> teardown<span class="Delimiter">();</span> ofstream fout<span class="Delimiter">((</span>Trace_dir+Trace_file<span class="Delimiter">).</span>c_str<span class="Delimiter">());</span> fout << Trace_stream<span class="Delimiter">-></span>readable_contents<span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">);</span> fout<span class="Delimiter">.</span>close<span class="Delimiter">();</span> - <span class="Normal">delete</span> Trace_stream<span class="Delimiter">;</span> + delete Trace_stream<span class="Delimiter">;</span> Trace_stream = <span class="Constant">NULL</span><span class="Delimiter">;</span> Trace_file = <span class="Constant">""</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -207,7 +206,7 @@ recipe scenario-foo [ <span class="traceContains">+warn: redefining recipe scenario-foo</span> <span class="Delimiter">:(after "bool warn_on_redefine(const string& recipe_name)")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>recipe_name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"scenario-"</span><span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> +if <span class="Delimiter">(</span>recipe_name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"scenario-"</span><span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="SalientComment">//:: The special instructions we want to support inside scenarios.</span> <span class="Comment">//: In a compiler for the mu VM these will require more work.</span> @@ -228,7 +227,7 @@ RUN<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"run"</span>] = RUN<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> RUN: <span class="Delimiter">{</span> +case RUN: <span class="Delimiter">{</span> <span class="CommentedCode">//? cout << "recipe " << current_instruction().ingredients.at(0).name << '\n'; //? 1</span> ostringstream tmp<span class="Delimiter">;</span> tmp << <span class="Constant">"recipe run"</span> << Next_recipe_ordinal << <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><span class="Delimiter">;</span> @@ -244,7 +243,7 @@ Recipe_ordinal[<span class="Constant">"run"</span>] = RUN<span class=" <span class="Comment">// Some variables for fake resources always get special addresses in</span> <span class="Comment">// scenarios.</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> bind_special_scenario_names<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void bind_special_scenario_names<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// Special Scenario Variable Names(r)</span> <span class="Comment">// End Special Scenario Variable Names(r)</span> <span class="Delimiter">}</span> @@ -265,7 +264,7 @@ recipe main [ <span class="Comment">//: Also includes some special support for checking strings.</span> <span class="Delimiter">:(before "End Globals")</span> -<span class="Normal">bool</span> Scenario_testing_scenario = <span class="Constant">false</span><span class="Delimiter">;</span> +bool Scenario_testing_scenario = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End Setup")</span> Scenario_testing_scenario = <span class="Constant">false</span><span class="Delimiter">;</span> @@ -285,44 +284,44 @@ MEMORY_SHOULD_CONTAIN<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"memory-should-contain"</span>] = MEMORY_SHOULD_CONTAIN<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> MEMORY_SHOULD_CONTAIN: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> +case MEMORY_SHOULD_CONTAIN: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="CommentedCode">//? cout << current_instruction().ingredients.at(0).name << '\n'; //? 1</span> check_memory<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>name<span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> check_memory<span class="Delimiter">(</span><span class="Normal">const</span> string& s<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void check_memory<span class="Delimiter">(</span>const string& s<span class="Delimiter">)</span> <span class="Delimiter">{</span> istringstream in<span class="Delimiter">(</span>s<span class="Delimiter">);</span> in >> std::noskipws<span class="Delimiter">;</span> - set<<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>> locations_checked<span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span><span class="Constant">true</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + set<long long int> locations_checked<span class="Delimiter">;</span> + while <span class="Delimiter">(</span><span class="Constant">true</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span> string lhs = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!is_integer<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!is_integer<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Delimiter">{</span> check_type<span class="Delimiter">(</span>lhs<span class="Delimiter">,</span> in<span class="Delimiter">);</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">int</span> address = to_integer<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span> + int address = to_integer<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span> skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span> string _assign<span class="Delimiter">;</span> in >> _assign<span class="Delimiter">;</span> assert<span class="Delimiter">(</span>_assign == <span class="Constant">"<-"</span><span class="Delimiter">);</span> skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span> - <span class="Normal">int</span> value = <span class="Constant">0</span><span class="Delimiter">;</span> in >> value<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>locations_checked<span class="Delimiter">.</span>find<span class="Delimiter">(</span>address<span class="Delimiter">)</span> != locations_checked<span class="Delimiter">.</span>end<span class="Delimiter">())</span> + int value = <span class="Constant">0</span><span class="Delimiter">;</span> in >> value<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>locations_checked<span class="Delimiter">.</span>find<span class="Delimiter">(</span>address<span class="Delimiter">)</span> != locations_checked<span class="Delimiter">.</span>end<span class="Delimiter">())</span> raise << <span class="Constant">"duplicate expectation for location "</span> << address << <span class="cSpecial">'\n'</span> << end<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">"checking location "</span> << address << end<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Memory[address] != value<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Current_scenario && !Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Memory[address] != value<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Current_scenario && !Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// genuine test in a mu file</span> raise << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span> << Current_scenario<span class="Delimiter">-></span>name << <span class="Constant">": expected location "</span> << address << <span class="Constant">" to contain "</span> << value << <span class="Constant">" but saw "</span> << Memory[address] << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> + else <span class="Delimiter">{</span> <span class="Comment">// just testing scenario support</span> raise << <span class="Constant">"expected location "</span> << address << <span class="Constant">" to contain "</span> << value << <span class="Constant">" but saw "</span> << Memory[address] << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> Passed = <span class="Constant">false</span><span class="Delimiter">;</span> ++Num_failures<span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -332,16 +331,16 @@ Recipe_ordinal[<span class="Constant">"memory-should-contain"</span>] <span class="Delimiter">}</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> check_type<span class="Delimiter">(</span><span class="Normal">const</span> string& lhs<span class="Delimiter">,</span> istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void check_type<span class="Delimiter">(</span>const string& lhs<span class="Delimiter">,</span> istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> reagent x<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">"string"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">"string"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> x<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>to_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">));</span> skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span> string _assign = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span> assert<span class="Delimiter">(</span>_assign == <span class="Constant">"<-"</span><span class="Delimiter">);</span> skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span> string literal = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> address = x<span class="Delimiter">.</span>value<span class="Delimiter">;</span> + long long int address = x<span class="Delimiter">.</span>value<span class="Delimiter">;</span> <span class="Comment">// exclude quoting brackets</span> assert<span class="Delimiter">(</span>*literal<span class="Delimiter">.</span>begin<span class="Delimiter">()</span> == <span class="Constant">'['</span><span class="Delimiter">);</span> literal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>literal<span class="Delimiter">.</span>begin<span class="Delimiter">());</span> assert<span class="Delimiter">(</span>*--literal<span class="Delimiter">.</span>end<span class="Delimiter">()</span> == <span class="Constant">']'</span><span class="Delimiter">);</span> literal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>--literal<span class="Delimiter">.</span>end<span class="Delimiter">());</span> @@ -351,32 +350,32 @@ Recipe_ordinal[<span class="Constant">"memory-should-contain"</span>] raise << <span class="Constant">"don't know how to check memory for "</span> << lhs << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> check_string<span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> address<span class="Delimiter">,</span> <span class="Normal">const</span> string& literal<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void check_string<span class="Delimiter">(</span>long long int address<span class="Delimiter">,</span> const string& literal<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">"checking string length at "</span> << address << end<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Memory[address] != SIZE<span class="Delimiter">(</span>literal<span class="Delimiter">))</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Current_scenario && !Scenario_testing_scenario<span class="Delimiter">)</span> + if <span class="Delimiter">(</span>Memory[address] != SIZE<span class="Delimiter">(</span>literal<span class="Delimiter">))</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Current_scenario && !Scenario_testing_scenario<span class="Delimiter">)</span> raise << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span> << Current_scenario<span class="Delimiter">-></span>name << <span class="Constant">": expected location "</span> << address << <span class="Constant">" to contain length "</span> << SIZE<span class="Delimiter">(</span>literal<span class="Delimiter">)</span> << <span class="Constant">" of string ["</span> << literal << <span class="Constant">"] but saw "</span> << Memory[address] << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> - <span class="Normal">else</span> + else raise << <span class="Constant">"expected location "</span> << address << <span class="Constant">" to contain length "</span> << SIZE<span class="Delimiter">(</span>literal<span class="Delimiter">)</span> << <span class="Constant">" of string ["</span> << literal << <span class="Constant">"] but saw "</span> << Memory[address] << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> Passed = <span class="Constant">false</span><span class="Delimiter">;</span> ++Num_failures<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> ++address<span class="Delimiter">;</span> <span class="Comment">// now skip length</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>literal<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <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>literal<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">"checking location "</span> << address+i << end<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Memory[address+i] != literal<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Current_scenario && !Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Memory[address+i] != literal<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Current_scenario && !Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// genuine test in a mu file</span> raise << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span> << Current_scenario<span class="Delimiter">-></span>name << <span class="Constant">": expected location "</span> << <span class="Delimiter">(</span>address+i<span class="Delimiter">)</span> << <span class="Constant">" to contain "</span> << literal<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> << <span class="Constant">" but saw "</span> << Memory[address+i] << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> + else <span class="Delimiter">{</span> <span class="Comment">// just testing scenario support</span> raise << <span class="Constant">"expected location "</span> << <span class="Delimiter">(</span>address+i<span class="Delimiter">)</span> << <span class="Constant">" to contain "</span> << literal<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> << <span class="Constant">" but saw "</span> << Memory[address+i] << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> Passed = <span class="Constant">false</span><span class="Delimiter">;</span> ++Num_failures<span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -436,19 +435,19 @@ recipe main [ <span class="Special">% Hide_warnings = true;</span> recipe main [ trace-should-contain [ - <span class="Normal">a</span>: b - <span class="Normal">a</span>: d + a: b + a: d ] ] -<span class="traceContains">+warn: missing [b] in trace layer a</span> +<span class="traceContains">+warn: missing [b] in trace with label a</span> <span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> TRACE_SHOULD_CONTAIN<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"trace-should-contain"</span>] = TRACE_SHOULD_CONTAIN<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> TRACE_SHOULD_CONTAIN: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> +case TRACE_SHOULD_CONTAIN: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> check_trace<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>name<span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -456,37 +455,37 @@ Recipe_ordinal[<span class="Constant">"trace-should-contain"</span>] = <span class="Delimiter">:(code)</span> <span class="Comment">// simplified version of check_trace_contents() that emits warnings rather</span> <span class="Comment">// than just printing to stderr</span> -<span class="Normal">bool</span> check_trace<span class="Delimiter">(</span><span class="Normal">const</span> string& expected<span class="Delimiter">)</span> <span class="Delimiter">{</span> +bool check_trace<span class="Delimiter">(</span>const string& expected<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << "AAA " << expected << '\n'; //? 1</span> Trace_stream<span class="Delimiter">-></span>newline<span class="Delimiter">();</span> vector<trace_line> expected_lines = parse_trace<span class="Delimiter">(</span>expected<span class="Delimiter">);</span> <span class="CommentedCode">//? cerr << "BBB " << SIZE(expected_lines) << '\n'; //? 1</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>expected_lines<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> curr_expected_line = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>vector<trace_line>::iterator p = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>label != p<span class="Delimiter">-></span>label<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>contents != trim<span class="Delimiter">(</span>p<span class="Delimiter">-></span>contents<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>expected_lines<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + long long int curr_expected_line = <span class="Constant">0</span><span class="Delimiter">;</span> + for <span class="Delimiter">(</span>vector<trace_line>::iterator p = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>label != p<span class="Delimiter">-></span>label<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>contents != trim<span class="Delimiter">(</span>p<span class="Delimiter">-></span>contents<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Comment">// match</span> ++curr_expected_line<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr_expected_line == SIZE<span class="Delimiter">(</span>expected_lines<span class="Delimiter">))</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>curr_expected_line == SIZE<span class="Delimiter">(</span>expected_lines<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << "ZZZ\n"; //? 1</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> raise << <span class="Constant">"missing ["</span> << expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>contents << <span class="Constant">"] "</span> - << <span class="Constant">"in trace layer "</span> << expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>label << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + << <span class="Constant">"in trace with label "</span> << expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>label << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> Passed = <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> -vector<trace_line> parse_trace<span class="Delimiter">(</span><span class="Normal">const</span> string& expected<span class="Delimiter">)</span> <span class="Delimiter">{</span> +vector<trace_line> parse_trace<span class="Delimiter">(</span>const string& expected<span class="Delimiter">)</span> <span class="Delimiter">{</span> vector<string> buf = split<span class="Delimiter">(</span>expected<span class="Delimiter">,</span> <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> vector<trace_line> result<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>buf<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <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>buf<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> buf<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> = trim<span class="Delimiter">(</span>buf<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>buf<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>empty<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> delim = buf<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>find<span class="Delimiter">(</span><span class="Constant">": "</span><span class="Delimiter">);</span> + if <span class="Delimiter">(</span>buf<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>empty<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + long long int delim = buf<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>find<span class="Delimiter">(</span><span class="Constant">": "</span><span class="Delimiter">);</span> result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>trace_line<span class="Delimiter">(</span>trim<span class="Delimiter">(</span>buf<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>substr<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">,</span> delim<span class="Delimiter">)),</span> trim<span class="Delimiter">(</span>buf<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>substr<span class="Delimiter">(</span>delim+<span class="Constant">2</span><span class="Delimiter">))));</span> <span class="Delimiter">}</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> @@ -497,27 +496,27 @@ vector<trace_line> parse_trace<span class="Delimiter">(</span><span class= <span class="Special">% Hide_warnings = true;</span> recipe main [ run [ - trace [a]<span class="Delimiter">,</span> [b] + trace <span class="Constant">1</span><span class="Delimiter">,</span> [a]<span class="Delimiter">,</span> [b] ] trace-should-contain [ - <span class="Normal">a</span>: b - <span class="Normal">a</span>: d + a: b + a: d ] ] -<span class="traceContains">+warn: missing [d] in trace layer a</span> +<span class="traceContains">+warn: missing [d] in trace with label a</span> <span class="Delimiter">:(scenario trace_check_passes_silently)</span> <span class="Special">% Scenario_testing_scenario = true;</span> <span class="Special">% Hide_warnings = true;</span> recipe main [ run [ - trace [a]<span class="Delimiter">,</span> [b] + trace <span class="Constant">1</span><span class="Delimiter">,</span> [a]<span class="Delimiter">,</span> [b] ] trace-should-contain [ - <span class="Normal">a</span>: b + a: b ] ] -<span class="traceAbsent">-warn: missing [b] in trace layer a</span> +<span class="traceAbsent">-warn: missing [b] in trace with label a</span> $warn: <span class="Constant">0</span> <span class="Comment">//: 'trace-should-not-contain' is like the '-' lines in our scenarios so far</span> @@ -529,21 +528,21 @@ $warn: <span class="Constant">0</span> <span class="Special">% Hide_warnings = true;</span> recipe main [ run [ - trace [a]<span class="Delimiter">,</span> [b] + trace <span class="Constant">1</span><span class="Delimiter">,</span> [a]<span class="Delimiter">,</span> [b] ] - trace-should-<span class="Normal">not</span>-contain [ - <span class="Normal">a</span>: b + trace-should-not-contain [ + a: b ] ] -<span class="traceContains">+warn: unexpected [b] in trace layer a</span> +<span class="traceContains">+warn: unexpected [b] in trace with label a</span> <span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> TRACE_SHOULD_NOT_CONTAIN<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"trace-should-not-contain"</span>] = TRACE_SHOULD_NOT_CONTAIN<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> TRACE_SHOULD_NOT_CONTAIN: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> +case TRACE_SHOULD_NOT_CONTAIN: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> check_trace_missing<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>name<span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -551,12 +550,12 @@ Recipe_ordinal[<span class="Constant">"trace-should-not-contain"</span <span class="Delimiter">:(code)</span> <span class="Comment">// simplified version of check_trace_contents() that emits warnings rather</span> <span class="Comment">// than just printing to stderr</span> -<span class="Normal">bool</span> check_trace_missing<span class="Delimiter">(</span><span class="Normal">const</span> string& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> +bool check_trace_missing<span class="Delimiter">(</span>const string& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> Trace_stream<span class="Delimiter">-></span>newline<span class="Delimiter">();</span> vector<trace_line> lines = parse_trace<span class="Delimiter">(</span>in<span class="Delimiter">);</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>lines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span>lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>label<span class="Delimiter">,</span> lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>contents<span class="Delimiter">)</span> != <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - raise << <span class="Constant">"unexpected ["</span> << lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>contents << <span class="Constant">"] in trace layer "</span> << lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>label << <span class="cSpecial">'\n'</span> << end<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>lines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span>lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>label<span class="Delimiter">,</span> lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>contents<span class="Delimiter">)</span> != <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << <span class="Constant">"unexpected ["</span> << lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>contents << <span class="Constant">"] in trace with label "</span> << lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>label << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> Passed = <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> @@ -568,11 +567,11 @@ Recipe_ordinal[<span class="Constant">"trace-should-not-contain"</span <span class="Special">% Scenario_testing_scenario = true;</span> <span class="Special">% Hide_warnings = true;</span> recipe main [ - trace-should-<span class="Normal">not</span>-contain [ - <span class="Normal">a</span>: b + trace-should-not-contain [ + a: b ] ] -<span class="traceAbsent">-warn: unexpected [b] in trace layer a</span> +<span class="traceAbsent">-warn: unexpected [b] in trace with label a</span> $warn: <span class="Constant">0</span> <span class="Delimiter">:(scenario trace_negative_check_warns_on_any_unexpected_line)</span> @@ -580,25 +579,85 @@ $warn: <span class="Constant">0</span> <span class="Special">% Hide_warnings = true;</span> recipe main [ run [ - trace [a]<span class="Delimiter">,</span> [d] + trace <span class="Constant">1</span><span class="Delimiter">,</span> [a]<span class="Delimiter">,</span> [d] + ] + trace-should-not-contain [ + a: b + a: d + ] +] +<span class="traceContains">+warn: unexpected [d] in trace with label a</span> + +<span class="Delimiter">:(scenario trace_count_check)</span> +recipe main [ + run [ + trace <span class="Constant">1</span><span class="Delimiter">,</span> [a]<span class="Delimiter">,</span> [foo] ] - trace-should-<span class="Normal">not</span>-contain [ - <span class="Normal">a</span>: b - <span class="Normal">a</span>: d + check-trace-count-for-label <span class="Constant">1</span><span class="Delimiter">,</span> [a] +] + +<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> +CHECK_TRACE_COUNT_FOR_LABEL<span class="Delimiter">,</span> +<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> +Recipe_ordinal[<span class="Constant">"check-trace-count-for-label"</span>] = CHECK_TRACE_COUNT_FOR_LABEL<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> +case CHECK_TRACE_COUNT_FOR_LABEL: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><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">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'check-trace-for-label' requires exactly two ingredients, but got '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'check-trace-for-label' should be a number (count), but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + long long int expected_count = 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>!is_literal_string<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> <span class="Delimiter">{</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": second ingredient of 'check-trace-for-label' should be a literal string (label), but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + string label = 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>name<span class="Delimiter">;</span> + long long int count = trace_count<span class="Delimiter">(</span>label<span class="Delimiter">);</span> + if <span class="Delimiter">(</span>count != expected_count<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Current_scenario && !Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Comment">// genuine test in a mu file</span> + raise << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span> << Current_scenario<span class="Delimiter">-></span>name << <span class="Constant">": "</span> << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": expected "</span> << expected_count << <span class="Constant">" lines in trace with label "</span> << label << <span class="Constant">" in trace: "</span><span class="Delimiter">;</span> + DUMP<span class="Delimiter">(</span>label<span class="Delimiter">);</span> + raise<span class="Delimiter">;</span> + <span class="Delimiter">}</span> + else <span class="Delimiter">{</span> + <span class="Comment">// just testing scenario support</span> + raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": expected "</span> << expected_count << <span class="Constant">" lines in trace with label "</span> << label << <span class="Constant">" in trace</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Delimiter">}</span> + if <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> + Passed = <span class="Constant">false</span><span class="Delimiter">;</span> + ++Num_failures<span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Delimiter">}</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +<span class="Delimiter">:(scenario trace_count_check_2)</span> +<span class="Special">% Scenario_testing_scenario = true;</span> +<span class="Special">% Hide_warnings = true;</span> +recipe main [ + run [ + trace <span class="Constant">1</span><span class="Delimiter">,</span> [a]<span class="Delimiter">,</span> [foo] ] + check-trace-count-for-label <span class="Constant">2</span><span class="Delimiter">,</span> [a] ] -<span class="traceContains">+warn: unexpected [d] in trace layer a</span> +<span class="traceContains">+warn: main: expected 2 lines in trace with label a in trace</span> <span class="Comment">//: Minor detail: ignore 'system' calls in scenarios, since anything we do</span> <span class="Comment">//: with them is by definition impossible to test through mu.</span> <span class="Delimiter">:(after "case _SYSTEM:")</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Current_scenario<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>Current_scenario<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="SalientComment">//:: Helpers</span> <span class="Delimiter">:(code)</span> <span class="Comment">// just for the scenarios running scenarios in C++ layers</span> -<span class="Normal">void</span> run_mu_scenario<span class="Delimiter">(</span><span class="Normal">const</span> string& form<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void run_mu_scenario<span class="Delimiter">(</span>const string& form<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << form << '\n'; //? 1</span> istringstream in<span class="Delimiter">(</span>form<span class="Delimiter">);</span> in >> std::noskipws<span class="Delimiter">;</span> diff --git a/html/051scenario_test.mu.html b/html/051scenario_test.mu.html index d02cc41a..d38539dd 100644 --- a/html/051scenario_test.mu.html +++ b/html/051scenario_test.mu.html @@ -92,7 +92,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muScenario">scenario</span> check_trace_instruction [ run [ - trace <span class="Constant">[foo]</span>, <span class="Constant">[aaa]</span> + trace <span class="Constant">1</span>, <span class="Constant">[foo]</span>, <span class="Constant">[aaa]</span> ] trace-should-contain [ foo: aaa diff --git a/html/052tangle.cc.html b/html/052tangle.cc.html index fc5943fd..93323d00 100644 --- a/html/052tangle.cc.html +++ b/html/052tangle.cc.html @@ -13,15 +13,14 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.Constant { color: #00a0a0; } +.Identifier { color: #804000; } .cSpecial { color: #008000; } -.CommentedCode { color: #6c6c6c; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } -.Identifier { color: #804000; } +.CommentedCode { color: #6c6c6c; } +.Constant { color: #00a0a0; } +.traceContains { color: #008000; } --> </style> @@ -64,13 +63,13 @@ After_fragments<span class="Delimiter">.</span>clear<span class="Delimiter">();< Fragments_used<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> <span class="Delimiter">:(before "End Command Handlers")</span> -<span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>command == <span class="Constant">"before"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +else if <span class="Delimiter">(</span>command == <span class="Constant">"before"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> string label = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span> recipe tmp = slurp_recipe<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="CommentedCode">//? cerr << "adding before fragment " << label << '\n'; //? 1</span> Before_fragments[label]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>Before_fragments[label]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> tmp<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> tmp<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>end<span class="Delimiter">());</span> <span class="Delimiter">}</span> -<span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>command == <span class="Constant">"after"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +else if <span class="Delimiter">(</span>command == <span class="Constant">"after"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> string label = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span> recipe tmp = slurp_recipe<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="CommentedCode">//? cerr << "adding after fragment " << label << '\n'; //? 1</span> @@ -86,32 +85,32 @@ Fragments_used<span class="Delimiter">.</span>clear<span class="Delimiter">();</ <span class="Comment">//: include more labels that need further insertions. Track which labels we've</span> <span class="Comment">//: already processed using an extra field.</span> <span class="Delimiter">:(before "End instruction Fields")</span> -<span class="Normal">mutable</span> <span class="Normal">bool</span> tangle_done<span class="Delimiter">;</span> +mutable bool tangle_done<span class="Delimiter">;</span> <span class="Delimiter">:(before "End instruction Constructor")</span> tangle_done = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> insert_fragments<span class="Delimiter">(</span><span class="Normal">const</span> recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">bool</span> made_progress = <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>made_progress<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void insert_fragments<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + bool made_progress = <span class="Constant">true</span><span class="Delimiter">;</span> + while <span class="Delimiter">(</span>made_progress<span class="Delimiter">)</span> <span class="Delimiter">{</span> made_progress = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Comment">// create a new vector because insertions invalidate iterators</span> vector<instruction> result<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">const</span> instruction inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>is_label || inst<span class="Delimiter">.</span>tangle_done<span class="Delimiter">)</span> <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>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<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>i<span class="Delimiter">);</span> + if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>is_label || inst<span class="Delimiter">.</span>tangle_done<span class="Delimiter">)</span> <span class="Delimiter">{</span> result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>inst<span class="Delimiter">);</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> inst<span class="Delimiter">.</span>tangle_done = <span class="Constant">true</span><span class="Delimiter">;</span> made_progress = <span class="Constant">true</span><span class="Delimiter">;</span> Fragments_used<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Before_fragments<span class="Delimiter">.</span>find<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label<span class="Delimiter">)</span> != Before_fragments<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Before_fragments<span class="Delimiter">.</span>find<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label<span class="Delimiter">)</span> != Before_fragments<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << "loading code before " << inst.label << '\n'; //? 1</span> result<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>result<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> Before_fragments[inst<span class="Delimiter">.</span>label]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> Before_fragments[inst<span class="Delimiter">.</span>label]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>end<span class="Delimiter">());</span> <span class="Delimiter">}</span> result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>inst<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>After_fragments<span class="Delimiter">.</span>find<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label<span class="Delimiter">)</span> != After_fragments<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>After_fragments<span class="Delimiter">.</span>find<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label<span class="Delimiter">)</span> != After_fragments<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << "loading code after " << inst.label << '\n'; //? 1</span> result<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>result<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> After_fragments[inst<span class="Delimiter">.</span>label]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> After_fragments[inst<span class="Delimiter">.</span>label]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>end<span class="Delimiter">());</span> <span class="Delimiter">}</span> @@ -122,19 +121,19 @@ tangle_done = <span class="Constant">false</span><span class="Delimiter">;</span <span class="Comment">//: warn about unapplied fragments</span> <span class="Delimiter">:(before "End Globals")</span> -<span class="Normal">bool</span> Transform_check_insert_fragments_Ran = <span class="Constant">false</span><span class="Delimiter">;</span> +bool Transform_check_insert_fragments_Ran = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End One-time Setup")</span> Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_insert_fragments<span class="Delimiter">);</span> <span class="Comment">// final transform</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> check_insert_fragments<span class="Delimiter">(</span>unused recipe_ordinal<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Transform_check_insert_fragments_Ran<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> +void check_insert_fragments<span class="Delimiter">(</span>unused recipe_ordinal<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Transform_check_insert_fragments_Ran<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> Transform_check_insert_fragments_Ran = <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> recipe>::iterator p = Before_fragments<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Before_fragments<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Fragments_used<span class="Delimiter">.</span>find<span class="Delimiter">(</span>p<span class="Delimiter">-></span>first<span class="Delimiter">)</span> == Fragments_used<span class="Delimiter">.</span>end<span class="Delimiter">())</span> + for <span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> recipe>::iterator p = Before_fragments<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Before_fragments<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Fragments_used<span class="Delimiter">.</span>find<span class="Delimiter">(</span>p<span class="Delimiter">-></span>first<span class="Delimiter">)</span> == Fragments_used<span class="Delimiter">.</span>end<span class="Delimiter">())</span> raise << <span class="Constant">"could not locate insert before "</span> << p<span class="Delimiter">-></span>first << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> recipe>::iterator p = After_fragments<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != After_fragments<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Fragments_used<span class="Delimiter">.</span>find<span class="Delimiter">(</span>p<span class="Delimiter">-></span>first<span class="Delimiter">)</span> == Fragments_used<span class="Delimiter">.</span>end<span class="Delimiter">())</span> + for <span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> recipe>::iterator p = After_fragments<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != After_fragments<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Fragments_used<span class="Delimiter">.</span>find<span class="Delimiter">(</span>p<span class="Delimiter">-></span>first<span class="Delimiter">)</span> == Fragments_used<span class="Delimiter">.</span>end<span class="Delimiter">())</span> raise << <span class="Constant">"could not locate insert after "</span> << p<span class="Delimiter">-></span>first << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> diff --git a/html/053continuation.cc.html b/html/053continuation.cc.html index d9a7a185..c0c00353 100644 --- a/html/053continuation.cc.html +++ b/html/053continuation.cc.html @@ -13,17 +13,16 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.traceAbsent { color: #c00000; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } +.SalientComment { color: #00ffff; } +.traceAbsent { color: #c00000; } +.traceContains { color: #008000; } .CommentedCode { color: #6c6c6c; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.Constant { color: #00a0a0; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } -.SalientComment { color: #00ffff; } --> </style> @@ -44,8 +43,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment">//: todo: implement continuations in mu's memory</span> <span class="Delimiter">:(before "End Globals")</span> -map<<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span><span class="Delimiter">,</span> call_stack> Continuation<span class="Delimiter">;</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> Next_continuation_id = <span class="Constant">0</span><span class="Delimiter">;</span> +map<long long int<span class="Delimiter">,</span> call_stack> Continuation<span class="Delimiter">;</span> +long long int Next_continuation_id = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End Setup")</span> Continuation<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> Next_continuation_id = <span class="Constant">0</span><span class="Delimiter">;</span> @@ -59,7 +58,7 @@ CURRENT_CONTINUATION<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"current-continuation"</span>] = CURRENT_CONTINUATION<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> CURRENT_CONTINUATION: <span class="Delimiter">{</span> +case CURRENT_CONTINUATION: <span class="Delimiter">{</span> <span class="Comment">// copy the current call stack</span> Continuation[Next_continuation_id] = Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">;</span> <span class="Comment">// deep copy because calls have no pointers</span> <span class="Comment">// make sure calling the copy doesn't spawn the same continuation again</span> @@ -76,12 +75,12 @@ CONTINUE_FROM<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"continue-from"</span>] = CONTINUE_FROM<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> CONTINUE_FROM: <span class="Delimiter">{</span> - <span class="Normal">if</span> <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> +case CONTINUE_FROM: <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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'continue-from' should be a continuation id generated by 'current-continuation', but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> c = 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> + long long int c = 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> Current_routine<span class="Delimiter">-></span>calls = Continuation[c]<span class="Delimiter">;</span> <span class="Comment">// deep copy; calls have no pointers</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Comment">// skip rest of this instruction</span> <span class="Delimiter">}</span> @@ -93,8 +92,8 @@ recipe main [ <span class="Constant">2</span>:continuation<span class="Special"> <- </span>current-continuation <span class="Delimiter">{</span> <span class="CommentedCode">#? $print 1:number</span> - <span class="Constant">3</span>:boolean<span class="Special"> <- </span>greater-<span class="Normal">or</span>-equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">3</span> - <span class="Identifier">break</span>-<span class="Normal">if</span> <span class="Constant">3</span>:boolean + <span class="Constant">3</span>:boolean<span class="Special"> <- </span>greater-or-equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">3</span> + <span class="Identifier">break</span>-if <span class="Constant">3</span>:boolean <span class="Constant">1</span>:number<span class="Special"> <- </span>add <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">1</span> <span class="Identifier">continue</span>-from <span class="Constant">2</span>:continuation <span class="Comment"># loop</span> <span class="Delimiter">}</span> @@ -112,8 +111,8 @@ recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Constant">2</span>:continuation<span class="Special"> <- </span>loop-body <span class="Delimiter">{</span> - <span class="Constant">3</span>:boolean<span class="Special"> <- </span>greater-<span class="Normal">or</span>-equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">3</span> - <span class="Identifier">break</span>-<span class="Normal">if</span> <span class="Constant">3</span>:boolean + <span class="Constant">3</span>:boolean<span class="Special"> <- </span>greater-or-equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">3</span> + <span class="Identifier">break</span>-if <span class="Constant">3</span>:boolean <span class="Identifier">continue</span>-from <span class="Constant">2</span>:continuation <span class="Comment"># loop</span> <span class="Delimiter">}</span> ] @@ -147,8 +146,8 @@ recipe main [ <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">5</span> <span class="Delimiter">{</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>call <span class="Constant">1</span>:continuation<span class="Delimiter">,</span> <span class="Constant">2</span>:number <span class="Comment"># 2 is an argument to g, the 'top' of the continuation</span> - <span class="Constant">3</span>:boolean<span class="Special"> <- </span>greater-<span class="Normal">or</span>-equal <span class="Constant">2</span>:number<span class="Delimiter">,</span> <span class="Constant">8</span> - <span class="Identifier">break</span>-<span class="Normal">if</span> <span class="Constant">3</span>:boolean + <span class="Constant">3</span>:boolean<span class="Special"> <- </span>greater-or-equal <span class="Constant">2</span>:number<span class="Delimiter">,</span> <span class="Constant">8</span> + <span class="Identifier">break</span>-if <span class="Constant">3</span>:boolean loop <span class="Delimiter">}</span> ] @@ -196,7 +195,7 @@ recipe g [ <span class="Comment">//: the call stack</span> <span class="Delimiter">:(before "End call Fields")</span> -<span class="Normal">bool</span> is_reset<span class="Delimiter">;</span> +bool is_reset<span class="Delimiter">;</span> <span class="Delimiter">:(before "End call Constructor")</span> is_reset = <span class="Constant">false</span><span class="Delimiter">;</span> @@ -207,7 +206,7 @@ CREATE_DELIMITED_CONTINUATION<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"create-delimited-continuation"</span>] = CREATE_DELIMITED_CONTINUATION<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> CREATE_DELIMITED_CONTINUATION: <span class="Delimiter">{</span> +case CREATE_DELIMITED_CONTINUATION: <span class="Delimiter">{</span> Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>is_reset = <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[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> ingredients<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>begin<span class="Delimiter">());</span> <span class="Comment">// drop the callee</span> @@ -218,8 +217,8 @@ Recipe_ordinal[<span class="Constant">"create-delimited-continuation"< <span class="Comment">//: call, and return it as the result.</span> <span class="Comment">//: todo: implement delimited continuations in mu's memory</span> <span class="Delimiter">:(before "End Globals")</span> -map<<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span><span class="Delimiter">,</span> call_stack> Delimited_continuation<span class="Delimiter">;</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> Next_delimited_continuation_id = <span class="Constant">0</span><span class="Delimiter">;</span> +map<long long int<span class="Delimiter">,</span> call_stack> Delimited_continuation<span class="Delimiter">;</span> +long long int Next_delimited_continuation_id = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End Setup")</span> Delimited_continuation<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> Next_delimited_continuation_id = <span class="Constant">0</span><span class="Delimiter">;</span> @@ -229,7 +228,7 @@ REPLY_DELIMITED_CONTINUATION<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"reply-delimited-continuation"</span>] = REPLY_DELIMITED_CONTINUATION<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> REPLY_DELIMITED_CONTINUATION: <span class="Delimiter">{</span> +case REPLY_DELIMITED_CONTINUATION: <span class="Delimiter">{</span> <span class="Comment">// first clear any existing ingredients, to isolate the creation of the</span> <span class="Comment">// continuation from its calls</span> Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> @@ -237,12 +236,12 @@ Recipe_ordinal[<span class="Constant">"reply-delimited-continuation"</ <span class="Comment">// copy the current call stack until the most recent 'reset' call</span> call_stack::iterator find_reset<span class="Delimiter">(</span>call_stack& c<span class="Delimiter">);</span> <span class="Comment">// manual prototype containing '::'</span> call_stack::iterator reset = find_reset<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>reset == Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>reset == Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": couldn't find a 'reset' call to jump out to</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> Delimited_continuation[Next_delimited_continuation_id] = call_stack<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> reset<span class="Delimiter">);</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>begin<span class="Delimiter">()</span> != reset<span class="Delimiter">)</span> <span class="Delimiter">{</span> + while <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>begin<span class="Delimiter">()</span> != reset<span class="Delimiter">)</span> <span class="Delimiter">{</span> --Callstack_depth<span class="Delimiter">;</span> Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>pop_front<span class="Delimiter">();</span> <span class="Delimiter">}</span> @@ -255,23 +254,23 @@ Recipe_ordinal[<span class="Constant">"reply-delimited-continuation"</ <span class="Delimiter">:(code)</span> call_stack::iterator find_reset<span class="Delimiter">(</span>call_stack& c<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>call_stack::iterator p = c<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != c<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>p<span class="Delimiter">-></span>is_reset<span class="Delimiter">)</span> <span class="Identifier">return</span> p<span class="Delimiter">;</span> + for <span class="Delimiter">(</span>call_stack::iterator p = c<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != c<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> + if <span class="Delimiter">(</span>p<span class="Delimiter">-></span>is_reset<span class="Delimiter">)</span> <span class="Identifier">return</span> p<span class="Delimiter">;</span> <span class="Identifier">return</span> c<span class="Delimiter">.</span>end<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Comment">//: overload 'call' for continuations</span> <span class="Delimiter">:(after "Begin Call")</span> - <span class="Normal">if</span> <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>properties<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> + if <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>properties<span class="Delimiter">.</span>empty<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>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>empty<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>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">"continuation"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// copy multiple calls on to current call stack</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> - <span class="Normal">if</span> <span class="Delimiter">(</span>Delimited_continuation<span class="Delimiter">.</span>find<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> == Delimited_continuation<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Delimited_continuation<span class="Delimiter">.</span>find<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> == Delimited_continuation<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": no such delimited continuation "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> - <span class="Normal">const</span> call_stack& new_calls = Delimited_continuation[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="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>call_stack::const_reverse_iterator p = new_calls<span class="Delimiter">.</span>rbegin<span class="Delimiter">();</span> p != new_calls<span class="Delimiter">.</span>rend<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> + const call_stack& new_calls = Delimited_continuation[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="Delimiter">;</span> + for <span class="Delimiter">(</span>call_stack::const_reverse_iterator p = new_calls<span class="Delimiter">.</span>rbegin<span class="Delimiter">();</span> p != new_calls<span class="Delimiter">.</span>rend<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>push_front<span class="Delimiter">(</span>*p<span class="Delimiter">);</span> ++current_step_index<span class="Delimiter">();</span> <span class="Comment">// skip past the reply-delimited-continuation</span> ingredients<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>begin<span class="Delimiter">());</span> <span class="Comment">// drop the callee</span> diff --git a/html/060string.mu.html b/html/060string.mu.html index 80c1c900..7a2126ff 100644 --- a/html/060string.mu.html +++ b/html/060string.mu.html @@ -13,14 +13,14 @@ 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; } -.muControl { color: #c0a020; } .muRecipe { color: #ff8700; } -.Delimiter { color: #a04060; } -.CommentedCode { color: #6c6c6c; } +.muScenario { color: #00af00; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .Special { color: #ff6060; } -.muScenario { color: #00af00; } +.CommentedCode { color: #6c6c6c; } +.Delimiter { color: #a04060; } +.muControl { color: #c0a020; } --> </style> @@ -42,13 +42,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } b-len:number<span class="Special"> <- </span>length *b <span class="Comment"># compare lengths</span> <span class="Delimiter">{</span> - trace <span class="Constant">[string-equal]</span>, <span class="Constant">[comparing lengths]</span> + trace <span class="Constant">99</span>, <span class="Constant">[string-equal]</span>, <span class="Constant">[comparing lengths]</span> length-equal?:boolean<span class="Special"> <- </span>equal a-len, b-len <span class="muControl">break-if</span> length-equal? <span class="muControl">reply</span> <span class="Constant">0</span> <span class="Delimiter">}</span> <span class="Comment"># compare each corresponding character</span> - trace <span class="Constant">[string-equal]</span>, <span class="Constant">[comparing characters]</span> + trace <span class="Constant">99</span>, <span class="Constant">[string-equal]</span>, <span class="Constant">[comparing characters]</span> i:number<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Delimiter">{</span> done?:boolean<span class="Special"> <- </span>greater-or-equal i, a-len @@ -184,7 +184,7 @@ container buffer [ <span class="muControl">reply</span> result ] -<span class="Comment"># in:address:buffer <- buffer-append in:address:buffer, c:character</span> +<span class="Comment"># in <- buffer-append in:address:buffer, c:character</span> <span class="muRecipe">recipe</span> buffer-append [ <span class="Constant">local-scope</span> in:address:buffer<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -286,7 +286,7 @@ container buffer [ negative?:boolean<span class="Special"> <- </span>lesser-than n, <span class="Constant">0</span> <span class="muControl">break-unless</span> negative? negate-result<span class="Special"> <- </span>copy <span class="Constant">1</span> - n<span class="Special"> <- </span>multiply n, -1 + n<span class="Special"> <- </span>multiply n, <span class="Constant">-1</span> <span class="Delimiter">}</span> <span class="Comment"># add digits from right to left into intermediate buffer</span> tmp:address:buffer<span class="Special"> <- </span>new-buffer <span class="Constant">30</span> @@ -374,7 +374,7 @@ container buffer [ <span class="muScenario">scenario</span> integer-to-decimal-digit-negative [ run [ - <span class="Constant">1</span>:address:array:character/<span class="Special">raw <- </span>integer-to-decimal-string -1 + <span class="Constant">1</span>:address:array:character/<span class="Special">raw <- </span>integer-to-decimal-string <span class="Constant">-1</span> <span class="Constant">2</span>:array:character/<span class="Special">raw <- </span>copy *<span class="Constant">1</span>:address:array:character/<span class="Special">raw</span> ] memory-should-contain [ @@ -438,6 +438,78 @@ container buffer [ ] ] +<span class="muScenario">scenario</span> replace-character-in-string [ + run [ + <span class="Constant">1</span>:address:array:character/<span class="Special">raw <- </span>new <span class="Constant">[abc]</span> + <span class="Constant">1</span>:address:array:character/<span class="Special">raw <- </span>string-replace <span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>, <span class="Constant">98/b</span>, <span class="Constant">122/z</span> + <span class="Constant">2</span>:array:character/<span class="Special">raw <- </span>copy *<span class="Constant">1</span>:address:array:character/<span class="Special">raw</span> + ] + memory-should-contain [ + <span class="Constant">2</span>:string<span class="Special"> <- </span><span class="Constant">[azc]</span> + ] +] + +<span class="muRecipe">recipe</span> string-replace [ + <span class="Constant">local-scope</span> + s:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + oldc:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + newc:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + from:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + len:number<span class="Special"> <- </span>length *s + i:number<span class="Special"> <- </span>find-next s, oldc, from + done?:boolean<span class="Special"> <- </span>greater-or-equal i, len + <span class="muControl">reply-if</span> done?, s/same-as-ingredient:<span class="Constant">0</span> + dest:address:character<span class="Special"> <- </span>index-address *s, i + *dest<span class="Special"> <- </span>copy newc + i<span class="Special"> <- </span>add i, <span class="Constant">1</span> + s<span class="Special"> <- </span>string-replace s, oldc, newc, i + <span class="muControl">reply</span> s/same-as-ingredient:<span class="Constant">0</span> +] + +<span class="muScenario">scenario</span> replace-character-at-start [ + run [ + <span class="Constant">1</span>:address:array:character/<span class="Special">raw <- </span>new <span class="Constant">[abc]</span> + <span class="Constant">1</span>:address:array:character/<span class="Special">raw <- </span>string-replace <span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>, <span class="Constant">97/a</span>, <span class="Constant">122/z</span> + <span class="Constant">2</span>:array:character/<span class="Special">raw <- </span>copy *<span class="Constant">1</span>:address:array:character/<span class="Special">raw</span> + ] + memory-should-contain [ + <span class="Constant">2</span>:string<span class="Special"> <- </span><span class="Constant">[zbc]</span> + ] +] + +<span class="muScenario">scenario</span> replace-character-at-end [ + run [ + <span class="Constant">1</span>:address:array:character/<span class="Special">raw <- </span>new <span class="Constant">[abc]</span> + <span class="Constant">1</span>:address:array:character/<span class="Special">raw <- </span>string-replace <span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>, <span class="Constant">99/c</span>, <span class="Constant">122/z</span> + <span class="Constant">2</span>:array:character/<span class="Special">raw <- </span>copy *<span class="Constant">1</span>:address:array:character/<span class="Special">raw</span> + ] + memory-should-contain [ + <span class="Constant">2</span>:string<span class="Special"> <- </span><span class="Constant">[abz]</span> + ] +] + +<span class="muScenario">scenario</span> replace-character-missing [ + run [ + <span class="Constant">1</span>:address:array:character/<span class="Special">raw <- </span>new <span class="Constant">[abc]</span> + <span class="Constant">1</span>:address:array:character/<span class="Special">raw <- </span>string-replace <span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>, <span class="Constant">100/d</span>, <span class="Constant">122/z</span> + <span class="Constant">2</span>:array:character/<span class="Special">raw <- </span>copy *<span class="Constant">1</span>:address:array:character/<span class="Special">raw</span> + ] + memory-should-contain [ + <span class="Constant">2</span>:string<span class="Special"> <- </span><span class="Constant">[abc]</span> + ] +] + +<span class="muScenario">scenario</span> replace-all-characters [ + run [ + <span class="Constant">1</span>:address:array:character/<span class="Special">raw <- </span>new <span class="Constant">[banana]</span> + <span class="Constant">1</span>:address:array:character/<span class="Special">raw <- </span>string-replace <span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>, <span class="Constant">97/a</span>, <span class="Constant">122/z</span> + <span class="Constant">2</span>:array:character/<span class="Special">raw <- </span>copy *<span class="Constant">1</span>:address:array:character/<span class="Special">raw</span> + ] + memory-should-contain [ + <span class="Constant">2</span>:string<span class="Special"> <- </span><span class="Constant">[bznznz]</span> + ] +] + <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 [ @@ -653,7 +725,7 @@ container buffer [ <span class="muControl">loop</span> <span class="Delimiter">}</span> <span class="Comment"># result = new character[end+1 - start]</span> - new-len:number<span class="Special"> <- </span>subtract end, start, -1 + new-len:number<span class="Special"> <- </span>subtract end, start, <span class="Constant">-1</span> result:address:array:character<span class="Special"> <- </span>new <span class="Constant">character:type</span>, new-len <span class="Comment"># copy the untrimmed parts between start and end</span> i:number<span class="Special"> <- </span>copy start @@ -828,7 +900,7 @@ container buffer [ ] ] -<span class="Comment"># idx:number <- find-substring text:address:array:character, pattern:address:array:character, idx:number</span> +<span class="Comment"># next-index:number <- find-substring text:address:array:character, pattern:address:array:character, idx:number</span> <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 [ diff --git a/html/061channel.mu.html b/html/061channel.mu.html index 8fa625b4..350dab6e 100644 --- a/html/061channel.mu.html +++ b/html/061channel.mu.html @@ -13,14 +13,14 @@ 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; } -.muControl { color: #c0a020; } -.muRecipe { color: #ff8700; } .muScenario { color: #00af00; } .SalientComment { color: #00ffff; } +.muRecipe { color: #ff8700; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .Special { color: #ff6060; } .Delimiter { color: #a04060; } +.muControl { color: #c0a020; } --> </style> @@ -84,7 +84,7 @@ container channel [ <span class="muControl">reply</span> result ] -<span class="Comment"># chan:address:channel <- write chan:address:channel, val:location</span> +<span class="Comment"># chan <- write chan:address:channel, val:location</span> <span class="muRecipe">recipe</span> write [ <span class="Constant">local-scope</span> chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -113,7 +113,7 @@ container channel [ <span class="muControl">reply</span> chan/same-as-ingredient:<span class="Constant">0</span> ] -<span class="Comment"># result:location, chan:address:channel <- read chan:address:channel</span> +<span class="Comment"># result:location, chan <- read chan:address:channel</span> <span class="muRecipe">recipe</span> read [ <span class="Constant">local-scope</span> chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -311,7 +311,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="Comment"># out <- buffer-lines in:address:channel, out:address:channel</span> <span class="muRecipe">recipe</span> buffer-lines [ <span class="Constant">local-scope</span> in:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -399,7 +399,7 @@ F buffer-lines-blocks-until-newline: channel should be empty <span class="muReci <span class="Constant">9</span>:boolean/completed?<span class="Special"> <- </span>not <span class="Constant">8</span>:boolean assert <span class="Constant">9</span>:boolean/completed?, [ F buffer-lines-blocks-until-newline: channel should contain data <span class="muRecipe">after</span> writing newline] - trace <span class="Constant">[test]</span>, <span class="Constant">[reached end]</span> + trace <span class="Constant">1</span>, <span class="Constant">[test]</span>, <span class="Constant">[reached end]</span> ] trace-should-contain [ test: reached end diff --git a/html/062array.mu.html b/html/062array.mu.html index 32af078f..b65da102 100644 --- a/html/062array.mu.html +++ b/html/062array.mu.html @@ -13,13 +13,13 @@ 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; } -.muControl { color: #c0a020; } -.muRecipe { color: #ff8700; } .muScenario { color: #00af00; } +.muRecipe { color: #ff8700; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .Special { color: #ff6060; } .Delimiter { color: #a04060; } +.muControl { color: #c0a020; } --> </style> diff --git a/html/063list.mu.html b/html/063list.mu.html index fe31c9ab..7d106ca0 100644 --- a/html/063list.mu.html +++ b/html/063list.mu.html @@ -13,13 +13,13 @@ 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; } -.muControl { color: #c0a020; } .muRecipe { color: #ff8700; } .muScenario { color: #00af00; } -.CommentedCode { color: #6c6c6c; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .Special { color: #ff6060; } +.CommentedCode { color: #6c6c6c; } +.muControl { color: #c0a020; } --> </style> diff --git a/html/064random.cc.html b/html/064random.cc.html index 393ea7f8..e8a75626 100644 --- a/html/064random.cc.html +++ b/html/064random.cc.html @@ -13,15 +13,14 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } +.traceContains { color: #008000; } .PreProc { color: #c000c0; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } --> </style> @@ -38,7 +37,7 @@ RANDOM<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"random"</span>] = RANDOM<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> RANDOM: <span class="Delimiter">{</span> +case RANDOM: <span class="Delimiter">{</span> <span class="Comment">// todo: limited range of numbers, might be imperfectly random</span> <span class="Comment">// todo: thread state in extra ingredients and products</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> @@ -51,7 +50,7 @@ MAKE_RANDOM_NONDETERMINISTIC<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"make-random-nondeterministic"</span>] = MAKE_RANDOM_NONDETERMINISTIC<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> MAKE_RANDOM_NONDETERMINISTIC: <span class="Delimiter">{</span> +case MAKE_RANDOM_NONDETERMINISTIC: <span class="Delimiter">{</span> srand<span class="Delimiter">(</span>time<span class="Delimiter">(</span><span class="Constant">NULL</span><span class="Delimiter">));</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -61,12 +60,12 @@ ROUND<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"round"</span>] = ROUND<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> ROUND: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case ROUND: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'round' requires exactly one ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> + 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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'round' should be a number, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> diff --git a/html/065duplex_list.mu.html b/html/065duplex_list.mu.html index 127b5910..1ed671cd 100644 --- a/html/065duplex_list.mu.html +++ b/html/065duplex_list.mu.html @@ -13,14 +13,14 @@ 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; } -.muControl { color: #c0a020; } .muRecipe { color: #ff8700; } .muScenario { color: #00af00; } -.CommentedCode { color: #6c6c6c; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .Special { color: #ff6060; } +.CommentedCode { color: #6c6c6c; } .Delimiter { color: #a04060; } +.muControl { color: #c0a020; } --> </style> diff --git a/html/066stream.mu.html b/html/066stream.mu.html index 2535cd8f..c6504424 100644 --- a/html/066stream.mu.html +++ b/html/066stream.mu.html @@ -13,11 +13,11 @@ 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; } -.muControl { color: #c0a020; } .muRecipe { color: #ff8700; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .Special { color: #ff6060; } +.muControl { color: #c0a020; } --> </style> diff --git a/html/070display.cc.html b/html/070display.cc.html index 73ddc796..f61edd06 100644 --- a/html/070display.cc.html +++ b/html/070display.cc.html @@ -13,14 +13,13 @@ 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; } -.SalientComment { color: #00ffff; } +.cSpecial { color: #008000; } +.Identifier { color: #804000; } .Constant { color: #00a0a0; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } +.SalientComment { color: #00ffff; } .CommentedCode { color: #6c6c6c; } -.Identifier { color: #804000; } -.cSpecial { color: #008000; } --> </style> @@ -41,17 +40,24 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="SalientComment">//:: Display management</span> <span class="Delimiter">:(before "End Globals")</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> Display_row = <span class="Constant">0</span><span class="Delimiter">,</span> Display_column = <span class="Constant">0</span><span class="Delimiter">;</span> -<span class="Normal">bool</span> Autodisplay = <span class="Constant">true</span><span class="Delimiter">;</span> +long long int Display_row = <span class="Constant">0</span><span class="Delimiter">,</span> Display_column = <span class="Constant">0</span><span class="Delimiter">;</span> +bool Autodisplay = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> OPEN_CONSOLE<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"open-console"</span>] = OPEN_CONSOLE<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> OPEN_CONSOLE: <span class="Delimiter">{</span> +case OPEN_CONSOLE: <span class="Delimiter">{</span> tb_init<span class="Delimiter">();</span> Display_row = Display_column = <span class="Constant">0</span><span class="Delimiter">;</span> + long long int width = tb_width<span class="Delimiter">();</span> + long long int height = tb_height<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>width > <span class="Constant">222</span> || height > <span class="Constant">222</span><span class="Delimiter">)</span> tb_shutdown<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>width > <span class="Constant">222</span><span class="Delimiter">)</span> + raise << <span class="Constant">"sorry, mu doesn't support windows wider than 222 characters. Please resize your window.</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>height > <span class="Constant">222</span><span class="Delimiter">)</span> + raise << <span class="Constant">"sorry, mu doesn't support windows taller than 222 characters. Please resize your window.</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -60,7 +66,7 @@ CLOSE_CONSOLE<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"close-console"</span>] = CLOSE_CONSOLE<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> CLOSE_CONSOLE: <span class="Delimiter">{</span> +case CLOSE_CONSOLE: <span class="Delimiter">{</span> tb_shutdown<span class="Delimiter">();</span> <span class="CommentedCode">//? Trace_stream->dump_layer = "all"; //? 1</span> <span class="Identifier">break</span><span class="Delimiter">;</span> @@ -74,7 +80,7 @@ CLEAR_DISPLAY<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"clear-display"</span>] = CLEAR_DISPLAY<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> CLEAR_DISPLAY: <span class="Delimiter">{</span> +case CLEAR_DISPLAY: <span class="Delimiter">{</span> tb_clear<span class="Delimiter">();</span> Display_row = Display_column = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Identifier">break</span><span class="Delimiter">;</span> @@ -85,13 +91,13 @@ CLEAR_LINE_ON_DISPLAY<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"clear-line-on-display"</span>] = CLEAR_LINE_ON_DISPLAY<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> CLEAR_LINE_ON_DISPLAY: <span class="Delimiter">{</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> width = tb_width<span class="Delimiter">();</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> x = Display_column<span class="Delimiter">;</span> x < width<span class="Delimiter">;</span> ++x<span class="Delimiter">)</span> <span class="Delimiter">{</span> +case CLEAR_LINE_ON_DISPLAY: <span class="Delimiter">{</span> + long long int width = tb_width<span class="Delimiter">();</span> + for <span class="Delimiter">(</span>long long int x = Display_column<span class="Delimiter">;</span> x < width<span class="Delimiter">;</span> ++x<span class="Delimiter">)</span> <span class="Delimiter">{</span> tb_change_cell<span class="Delimiter">(</span>x<span class="Delimiter">,</span> Display_row<span class="Delimiter">,</span> <span class="Constant">' '</span><span class="Delimiter">,</span> TB_WHITE<span class="Delimiter">,</span> TB_BLACK<span class="Delimiter">);</span> <span class="Delimiter">}</span> tb_set_cursor<span class="Delimiter">(</span>Display_column<span class="Delimiter">,</span> Display_row<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -100,60 +106,60 @@ PRINT_CHARACTER_TO_DISPLAY<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"print-character-to-display"</span>] = PRINT_CHARACTER_TO_DISPLAY<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> PRINT_CHARACTER_TO_DISPLAY: <span class="Delimiter">{</span> - <span class="Normal">int</span> h=tb_height<span class="Delimiter">(),</span> w=tb_width<span class="Delimiter">();</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> height = <span class="Delimiter">(</span>h >= <span class="Constant">0</span><span class="Delimiter">)</span> ? h : <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> width = <span class="Delimiter">(</span>w >= <span class="Constant">0</span><span class="Delimiter">)</span> ? w : <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> +case PRINT_CHARACTER_TO_DISPLAY: <span class="Delimiter">{</span> + int h=tb_height<span class="Delimiter">(),</span> w=tb_width<span class="Delimiter">();</span> + long long int height = <span class="Delimiter">(</span>h >= <span class="Constant">0</span><span class="Delimiter">)</span> ? h : <span class="Constant">0</span><span class="Delimiter">;</span> + long long int width = <span class="Delimiter">(</span>w >= <span class="Constant">0</span><span class="Delimiter">)</span> ? w : <span class="Constant">0</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'print-character-to-display' requires at least one ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> + 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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'print-character-to-display' should be a character, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> c = 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="Normal">int</span> color = TB_BLACK<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <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> <span class="Delimiter">{</span> + long long int c = 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> + int color = TB_BLACK<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span> <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> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": second ingredient of 'print-character-to-display' should be a foreground color number, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> color = 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> <span class="Delimiter">}</span> - <span class="Normal">int</span> bg_color = TB_BLACK<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> + int bg_color = TB_BLACK<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">2</span><span class="Delimiter">)</span> <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">2</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": third ingredient of 'print-character-to-display' should be a background color number, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> bg_color = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>bg_color == <span class="Constant">0</span><span class="Delimiter">)</span> bg_color = TB_BLACK<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>bg_color == <span class="Constant">0</span><span class="Delimiter">)</span> bg_color = TB_BLACK<span class="Delimiter">;</span> <span class="Delimiter">}</span> tb_change_cell<span class="Delimiter">(</span>Display_column<span class="Delimiter">,</span> Display_row<span class="Delimiter">,</span> c<span class="Delimiter">,</span> color<span class="Delimiter">,</span> bg_color<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>c == <span class="cSpecial">'\n'</span> || c == <span class="cSpecial">'\r'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Display_row < height-<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>c == <span class="cSpecial">'\n'</span> || c == <span class="cSpecial">'\r'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Display_row < height-<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> Display_column = <span class="Constant">0</span><span class="Delimiter">;</span> ++Display_row<span class="Delimiter">;</span> tb_set_cursor<span class="Delimiter">(</span>Display_column<span class="Delimiter">,</span> Display_row<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>c == <span class="cSpecial">'\b'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Display_column > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>c == <span class="cSpecial">'\b'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Display_column > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> tb_change_cell<span class="Delimiter">(</span>Display_column-<span class="Constant">1</span><span class="Delimiter">,</span> Display_row<span class="Delimiter">,</span> <span class="Constant">' '</span><span class="Delimiter">,</span> color<span class="Delimiter">,</span> bg_color<span class="Delimiter">);</span> --Display_column<span class="Delimiter">;</span> tb_set_cursor<span class="Delimiter">(</span>Display_column<span class="Delimiter">,</span> Display_row<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Display_column < width-<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Display_column < width-<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> ++Display_column<span class="Delimiter">;</span> tb_set_cursor<span class="Delimiter">(</span>Display_column<span class="Delimiter">,</span> Display_row<span class="Delimiter">);</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -162,7 +168,7 @@ CURSOR_POSITION_ON_DISPLAY<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"cursor-position-on-display"</span>] = CURSOR_POSITION_ON_DISPLAY<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> CURSOR_POSITION_ON_DISPLAY: <span class="Delimiter">{</span> +case CURSOR_POSITION_ON_DISPLAY: <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>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>Display_row<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>Display_column<span class="Delimiter">);</span> @@ -174,23 +180,23 @@ MOVE_CURSOR_ON_DISPLAY<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"move-cursor-on-display"</span>] = MOVE_CURSOR_ON_DISPLAY<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> MOVE_CURSOR_ON_DISPLAY: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case MOVE_CURSOR_ON_DISPLAY: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'move-cursor-on-display' requires two ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> + 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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'move-cursor-on-display' should be a row number, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> Display_row = 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="Normal">if</span> <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> <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> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": second ingredient of 'move-cursor-on-display' should be a column number, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> Display_column = 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> tb_set_cursor<span class="Delimiter">(</span>Display_column<span class="Delimiter">,</span> Display_row<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -199,13 +205,13 @@ MOVE_CURSOR_DOWN_ON_DISPLAY<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"move-cursor-down-on-display"</span>] = MOVE_CURSOR_DOWN_ON_DISPLAY<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> MOVE_CURSOR_DOWN_ON_DISPLAY: <span class="Delimiter">{</span> - <span class="Normal">int</span> h=tb_height<span class="Delimiter">();</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> height = <span class="Delimiter">(</span>h >= <span class="Constant">0</span><span class="Delimiter">)</span> ? h : <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Display_row < height-<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case MOVE_CURSOR_DOWN_ON_DISPLAY: <span class="Delimiter">{</span> + int h=tb_height<span class="Delimiter">();</span> + long long int height = <span class="Delimiter">(</span>h >= <span class="Constant">0</span><span class="Delimiter">)</span> ? h : <span class="Constant">0</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>Display_row < height-<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> Display_row++<span class="Delimiter">;</span> tb_set_cursor<span class="Delimiter">(</span>Display_column<span class="Delimiter">,</span> Display_row<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -215,11 +221,11 @@ MOVE_CURSOR_UP_ON_DISPLAY<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"move-cursor-up-on-display"</span>] = MOVE_CURSOR_UP_ON_DISPLAY<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> MOVE_CURSOR_UP_ON_DISPLAY: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Display_row > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case MOVE_CURSOR_UP_ON_DISPLAY: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Display_row > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> Display_row--<span class="Delimiter">;</span> tb_set_cursor<span class="Delimiter">(</span>Display_column<span class="Delimiter">,</span> Display_row<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -229,13 +235,13 @@ MOVE_CURSOR_RIGHT_ON_DISPLAY<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"move-cursor-right-on-display"</span>] = MOVE_CURSOR_RIGHT_ON_DISPLAY<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> MOVE_CURSOR_RIGHT_ON_DISPLAY: <span class="Delimiter">{</span> - <span class="Normal">int</span> w=tb_width<span class="Delimiter">();</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> width = <span class="Delimiter">(</span>w >= <span class="Constant">0</span><span class="Delimiter">)</span> ? w : <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Display_column < width-<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case MOVE_CURSOR_RIGHT_ON_DISPLAY: <span class="Delimiter">{</span> + int w=tb_width<span class="Delimiter">();</span> + long long int width = <span class="Delimiter">(</span>w >= <span class="Constant">0</span><span class="Delimiter">)</span> ? w : <span class="Constant">0</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>Display_column < width-<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> Display_column++<span class="Delimiter">;</span> tb_set_cursor<span class="Delimiter">(</span>Display_column<span class="Delimiter">,</span> Display_row<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -245,11 +251,11 @@ MOVE_CURSOR_LEFT_ON_DISPLAY<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"move-cursor-left-on-display"</span>] = MOVE_CURSOR_LEFT_ON_DISPLAY<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> MOVE_CURSOR_LEFT_ON_DISPLAY: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Display_column > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case MOVE_CURSOR_LEFT_ON_DISPLAY: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Display_column > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> Display_column--<span class="Delimiter">;</span> tb_set_cursor<span class="Delimiter">(</span>Display_column<span class="Delimiter">,</span> Display_row<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -259,7 +265,7 @@ DISPLAY_WIDTH<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"display-width"</span>] = DISPLAY_WIDTH<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> DISPLAY_WIDTH: <span class="Delimiter">{</span> +case DISPLAY_WIDTH: <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>tb_width<span class="Delimiter">());</span> <span class="Identifier">break</span><span class="Delimiter">;</span> @@ -270,7 +276,7 @@ DISPLAY_HEIGHT<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"display-height"</span>] = DISPLAY_HEIGHT<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> DISPLAY_HEIGHT: <span class="Delimiter">{</span> +case DISPLAY_HEIGHT: <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>tb_height<span class="Delimiter">());</span> <span class="Identifier">break</span><span class="Delimiter">;</span> @@ -281,7 +287,7 @@ HIDE_CURSOR_ON_DISPLAY<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"hide-cursor-on-display"</span>] = HIDE_CURSOR_ON_DISPLAY<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> HIDE_CURSOR_ON_DISPLAY: <span class="Delimiter">{</span> +case HIDE_CURSOR_ON_DISPLAY: <span class="Delimiter">{</span> tb_set_cursor<span class="Delimiter">(</span>TB_HIDE_CURSOR<span class="Delimiter">,</span> TB_HIDE_CURSOR<span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -291,7 +297,7 @@ SHOW_CURSOR_ON_DISPLAY<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"show-cursor-on-display"</span>] = SHOW_CURSOR_ON_DISPLAY<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> SHOW_CURSOR_ON_DISPLAY: <span class="Delimiter">{</span> +case SHOW_CURSOR_ON_DISPLAY: <span class="Delimiter">{</span> tb_set_cursor<span class="Delimiter">(</span>Display_row<span class="Delimiter">,</span> Display_column<span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -301,7 +307,7 @@ HIDE_DISPLAY<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"hide-display"</span>] = HIDE_DISPLAY<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> HIDE_DISPLAY: <span class="Delimiter">{</span> +case HIDE_DISPLAY: <span class="Delimiter">{</span> Autodisplay = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -311,7 +317,7 @@ SHOW_DISPLAY<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"show-display"</span>] = SHOW_DISPLAY<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> SHOW_DISPLAY: <span class="Delimiter">{</span> +case SHOW_DISPLAY: <span class="Delimiter">{</span> Autodisplay = <span class="Constant">true</span><span class="Delimiter">;</span> tb_present<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> @@ -324,7 +330,7 @@ WAIT_FOR_SOME_INTERACTION<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"wait-for-some-interaction"</span>] = WAIT_FOR_SOME_INTERACTION<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> WAIT_FOR_SOME_INTERACTION: <span class="Delimiter">{</span> +case WAIT_FOR_SOME_INTERACTION: <span class="Delimiter">{</span> tb_event event<span class="Delimiter">;</span> tb_poll_event<span class="Delimiter">(</span>&event<span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> @@ -335,11 +341,11 @@ CHECK_FOR_INTERACTION<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"check-for-interaction"</span>] = CHECK_FOR_INTERACTION<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> CHECK_FOR_INTERACTION: <span class="Delimiter">{</span> +case CHECK_FOR_INTERACTION: <span class="Delimiter">{</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">);</span> <span class="Comment">// result and status</span> tb_event event<span class="Delimiter">;</span> - <span class="Normal">int</span> event_type = tb_peek_event<span class="Delimiter">(</span>&event<span class="Delimiter">,</span> <span class="Constant">5</span><span class="Comment">/*</span><span class="Comment">ms</span><span class="Comment">*/</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>event_type == TB_EVENT_KEY && event<span class="Delimiter">.</span>ch<span class="Delimiter">)</span> <span class="Delimiter">{</span> + int event_type = tb_peek_event<span class="Delimiter">(</span>&event<span class="Delimiter">,</span> <span class="Constant">5</span><span class="Comment">/*</span><span class="Comment">ms</span><span class="Comment">*/</span><span class="Delimiter">);</span> + if <span class="Delimiter">(</span>event_type == TB_EVENT_KEY && event<span class="Delimiter">.</span>ch<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="Comment">/*</span><span class="Comment">text event</span><span class="Comment">*/</span><span class="Constant">0</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>event<span class="Delimiter">.</span>ch<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> @@ -348,11 +354,11 @@ Recipe_ordinal[<span class="Constant">"check-for-interaction"</span>] <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">// treat keys within ascii as unicode characters</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>event_type == TB_EVENT_KEY && event<span class="Delimiter">.</span>key < <span class="Constant">0xff</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>event_type == TB_EVENT_KEY && event<span class="Delimiter">.</span>key < <span class="Constant">0xff</span><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="Comment">/*</span><span class="Comment">text event</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>event<span class="Delimiter">.</span>key == TB_KEY_CTRL_C<span class="Delimiter">)</span> tb_shutdown<span class="Delimiter">(),</span> exit<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>event<span class="Delimiter">.</span>key == TB_KEY_BACKSPACE2<span class="Delimiter">)</span> event<span class="Delimiter">.</span>key = TB_KEY_BACKSPACE<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>event<span class="Delimiter">.</span>key == TB_KEY_CARRIAGE_RETURN<span class="Delimiter">)</span> event<span class="Delimiter">.</span>key = TB_KEY_NEWLINE<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>event<span class="Delimiter">.</span>key == TB_KEY_CTRL_C<span class="Delimiter">)</span> tb_shutdown<span class="Delimiter">(),</span> exit<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> + if <span class="Delimiter">(</span>event<span class="Delimiter">.</span>key == TB_KEY_BACKSPACE2<span class="Delimiter">)</span> event<span class="Delimiter">.</span>key = TB_KEY_BACKSPACE<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>event<span class="Delimiter">.</span>key == TB_KEY_CARRIAGE_RETURN<span class="Delimiter">)</span> event<span class="Delimiter">.</span>key = TB_KEY_NEWLINE<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>event<span class="Delimiter">.</span>key<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">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> @@ -360,7 +366,7 @@ Recipe_ordinal[<span class="Constant">"check-for-interaction"</span>] <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">// keys outside ascii aren't unicode characters but arbitrary termbox inventions</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>event_type == TB_EVENT_KEY<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>event_type == TB_EVENT_KEY<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="Comment">/*</span><span class="Comment">keycode event</span><span class="Comment">*/</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>event<span class="Delimiter">.</span>key<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> @@ -368,9 +374,7 @@ Recipe_ordinal[<span class="Constant">"check-for-interaction"</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><span class="Comment">/*</span><span class="Comment">found</span><span class="Comment">*/</span><span class="Constant">true</span><span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>event_type == TB_EVENT_MOUSE<span class="Delimiter">)</span> <span class="Delimiter">{</span> -<span class="CommentedCode">//? tb_shutdown(); //? 1</span> -<span class="CommentedCode">//? cerr << "AAA\n"; //? 1</span> + if <span class="Delimiter">(</span>event_type == TB_EVENT_MOUSE<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="Comment">/*</span><span class="Comment">touch event</span><span class="Comment">*/</span><span class="Constant">2</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>event<span class="Delimiter">.</span>key<span class="Delimiter">);</span> <span class="Comment">// which button, etc.</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>event<span class="Delimiter">.</span>y<span class="Delimiter">);</span> <span class="Comment">// row</span> @@ -378,7 +382,15 @@ Recipe_ordinal[<span class="Constant">"check-for-interaction"</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><span class="Comment">/*</span><span class="Comment">found</span><span class="Comment">*/</span><span class="Constant">true</span><span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Comment">// ignore TB_EVENT_RESIZE events for now</span> + if <span class="Delimiter">(</span>event_type == TB_EVENT_RESIZE<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="Comment">/*</span><span class="Comment">resize event</span><span class="Comment">*/</span><span class="Constant">3</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>event<span class="Delimiter">.</span>w<span class="Delimiter">);</span> <span class="Comment">// width</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>event<span class="Delimiter">.</span>h<span class="Delimiter">);</span> <span class="Comment">// height</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><span class="Comment">/*</span><span class="Comment">found</span><span class="Comment">*/</span><span class="Constant">true</span><span class="Delimiter">);</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + assert<span class="Delimiter">(</span>event_type == <span class="Constant">0</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">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">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> @@ -392,11 +404,34 @@ INTERACTIONS_LEFT<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"interactions-left?"</span>] = INTERACTIONS_LEFT<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> INTERACTIONS_LEFT: <span class="Delimiter">{</span> +case INTERACTIONS_LEFT: <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>tb_event_ready<span class="Delimiter">());</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> + +<span class="Comment">//: a hack to make edit.mu more responsive</span> + +<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> +CLEAR_DISPLAY_FROM<span class="Delimiter">,</span> +<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> +Recipe_ordinal[<span class="Constant">"clear-display-from"</span>] = CLEAR_DISPLAY_FROM<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> +case CLEAR_DISPLAY_FROM: <span class="Delimiter">{</span> + <span class="Comment">// todo: error checking</span> + int row = 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> + int column = 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> + int left = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> + int right = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">3</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> + int height=tb_height<span class="Delimiter">();</span> + for <span class="Delimiter">(;</span> row < height<span class="Delimiter">;</span> ++row<span class="Delimiter">,</span> column=left<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// start column from left in every inner loop except first</span> + for <span class="Delimiter">(;</span> column <= right<span class="Delimiter">;</span> ++column<span class="Delimiter">)</span> <span class="Delimiter">{</span> + tb_change_cell<span class="Delimiter">(</span>column<span class="Delimiter">,</span> row<span class="Delimiter">,</span> <span class="Constant">' '</span><span class="Delimiter">,</span> TB_WHITE<span class="Delimiter">,</span> TB_BLACK<span class="Delimiter">);</span> + <span class="Delimiter">}</span> + <span class="Delimiter">}</span> + if <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> </pre> </body> </html> diff --git a/html/071print.mu.html b/html/071print.mu.html index 1c860732..4da9db86 100644 --- a/html/071print.mu.html +++ b/html/071print.mu.html @@ -13,14 +13,14 @@ 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; } -.muControl { color: #c0a020; } .muRecipe { color: #ff8700; } -.Delimiter { color: #a04060; } -.CommentedCode { color: #6c6c6c; } +.muScenario { color: #00af00; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .Special { color: #ff6060; } -.muScenario { color: #00af00; } +.CommentedCode { color: #6c6c6c; } +.Delimiter { color: #a04060; } +.muControl { color: #c0a020; } --> </style> @@ -135,7 +135,7 @@ container screen-cell [ <span class="muControl">break-if</span> bg-color-found? bg-color<span class="Special"> <- </span>copy <span class="Constant">0/black</span> <span class="Delimiter">}</span> -<span class="CommentedCode">#? trace [app], [print character] #? 1</span> + trace <span class="Constant">90</span>, <span class="Constant">[print-character]</span>, c <span class="Delimiter">{</span> <span class="Comment"># if x exists</span> <span class="Comment"># (handle special cases exactly like in the real screen)</span> @@ -620,6 +620,7 @@ container screen-cell [ <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># if x exists (not real display), do nothing</span> + <span class="Comment"># todo: help test this</span> <span class="Delimiter">{</span> <span class="muControl">break-unless</span> screen <span class="muControl">reply</span> screen @@ -633,6 +634,7 @@ container screen-cell [ <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># if x exists (not real display), do nothing</span> + <span class="Comment"># todo: help test this</span> <span class="Delimiter">{</span> <span class="muControl">break-unless</span> screen <span class="muControl">reply</span> screen diff --git a/html/072scenario_screen.cc.html b/html/072scenario_screen.cc.html index 99c13565..5100c44c 100644 --- a/html/072scenario_screen.cc.html +++ b/html/072scenario_screen.cc.html @@ -13,15 +13,14 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } .traceAbsent { color: #c00000; } -.Constant { color: #00a0a0; } +.traceContains { color: #008000; } .cSpecial { color: #008000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } --> </style> @@ -44,7 +43,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } scenario screen-in-scenario [ assume-screen <span class="Constant">5</span>/width<span class="Delimiter">,</span> <span class="Constant">3</span>/height run [ - <span class="Normal">screen</span>:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">97</span> <span class="Comment"># 'a'</span> + screen:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">97</span> <span class="Comment"># 'a'</span> ] screen-should-contain [ <span class="Comment"># 01234</span> @@ -58,8 +57,8 @@ scenario screen-in-scenario [ scenario screen-in-scenario-unicode-color [ assume-screen <span class="Constant">5</span>/width<span class="Delimiter">,</span> <span class="Constant">3</span>/height run [ - <span class="Normal">screen</span>:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">955</span>/greek-small-lambda<span class="Delimiter">,</span> <span class="Constant">1</span>/red - <span class="Normal">screen</span>:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">97</span>/a + screen:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">955</span>/greek-small-lambda<span class="Delimiter">,</span> <span class="Constant">1</span>/red + screen:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">97</span>/a ] screen-should-contain [ <span class="Comment"># 01234</span> @@ -74,8 +73,8 @@ scenario screen-in-scenario-unicode-color [ scenario screen-in-scenario-color [ assume-screen <span class="Constant">5</span>/width<span class="Delimiter">,</span> <span class="Constant">3</span>/height run [ - <span class="Normal">screen</span>:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">955</span>/greek-small-lambda<span class="Delimiter">,</span> <span class="Constant">1</span>/red - <span class="Normal">screen</span>:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">97</span>/a<span class="Delimiter">,</span> <span class="Constant">7</span>/white + screen:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">955</span>/greek-small-lambda<span class="Delimiter">,</span> <span class="Constant">1</span>/red + screen:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">97</span>/a<span class="Delimiter">,</span> <span class="Constant">7</span>/white ] <span class="Comment"># screen-should-contain shows everything</span> screen-should-contain [ @@ -107,7 +106,7 @@ scenario screen-in-scenario-color [ scenario screen-in-scenario-error [ assume-screen <span class="Constant">5</span>/width<span class="Delimiter">,</span> <span class="Constant">3</span>/height run [ - <span class="Normal">screen</span>:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">97</span> <span class="Comment"># 'a'</span> + screen:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">97</span> <span class="Comment"># 'a'</span> ] screen-should-contain [ <span class="Comment"># 01234</span> @@ -125,7 +124,7 @@ scenario screen-in-scenario-error [ scenario screen-in-scenario-color [ assume-screen <span class="Constant">5</span>/width<span class="Delimiter">,</span> <span class="Constant">3</span>/height run [ - <span class="Normal">screen</span>:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">97</span>/a<span class="Delimiter">,</span> <span class="Constant">1</span>/red + screen:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">97</span>/a<span class="Delimiter">,</span> <span class="Constant">1</span>/red ] screen-should-contain-in-color <span class="Constant">2</span>/green<span class="Delimiter">,</span> [ <span class="Comment"># 01234</span> @@ -138,14 +137,14 @@ scenario screen-in-scenario-color [ <span class="Comment">//: allow naming just for 'screen'</span> <span class="Delimiter">:(before "End is_special_name Cases")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>s == <span class="Constant">"screen"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> +if <span class="Delimiter">(</span>s == <span class="Constant">"screen"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">:(scenarios run)</span> <span class="Delimiter">:(scenario convert_names_does_not_warn_when_mixing_special_names_and_numeric_locations)</span> <span class="Special">% Scenario_testing_scenario = true;</span> <span class="Special">% Hide_warnings = true;</span> recipe main [ - <span class="Normal">screen</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:number + screen:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:number ] <span class="traceAbsent">-warn: mixing variable names and numeric addresses in main</span> $warn: <span class="Constant">0</span> @@ -155,8 +154,8 @@ $warn: <span class="Constant">0</span> <span class="Comment">// Scenarios may not define default-space, so they should fit within the</span> <span class="Comment">// initial area of memory reserved for tests. We'll put the predefined</span> <span class="Comment">// variables available to them at the end of that region.</span> -<span class="Normal">const</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> Max_variables_in_scenarios = Reserved_for_tests-<span class="Constant">100</span><span class="Delimiter">;</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> Next_predefined_global_for_scenarios = Max_variables_in_scenarios<span class="Delimiter">;</span> +const long long int Max_variables_in_scenarios = Reserved_for_tests-<span class="Constant">100</span><span class="Delimiter">;</span> +long long int Next_predefined_global_for_scenarios = Max_variables_in_scenarios<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Setup")</span> assert<span class="Delimiter">(</span>Next_predefined_global_for_scenarios < Reserved_for_tests<span class="Delimiter">);</span> <span class="Delimiter">:(after "transform_all()" following "case RUN:")</span> @@ -167,7 +166,7 @@ assert<span class="Delimiter">(</span>Name[tmp_recipe<span class="Delimiter">.</ <span class="Delimiter">:(before "End Globals")</span> <span class="Comment">// Scenario Globals.</span> -<span class="Normal">const</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> SCREEN = Next_predefined_global_for_scenarios++<span class="Delimiter">;</span> +const long long int SCREEN = Next_predefined_global_for_scenarios++<span class="Delimiter">;</span> <span class="Comment">// End Scenario Globals.</span> <span class="Delimiter">:(before "End Special Scenario Variable Names(r)")</span> Name[r][<span class="Constant">"screen"</span>] = SCREEN<span class="Delimiter">;</span> @@ -175,7 +174,7 @@ Name[r][<span class="Constant">"screen"</span>] = SCREEN<span class="D <span class="Delimiter">:(before "End Rewrite Instruction(curr)")</span> <span class="Comment">// rewrite `assume-screen width, height` to</span> <span class="Comment">// `screen:address <- new-fake-screen width, height`</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"assume-screen"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"assume-screen"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> curr<span class="Delimiter">.</span>operation = Recipe_ordinal[<span class="Constant">"new-fake-screen"</span>]<span class="Delimiter">;</span> curr<span class="Delimiter">.</span>name = <span class="Constant">"new-fake-screen"</span><span class="Delimiter">;</span> assert<span class="Delimiter">(</span>curr<span class="Delimiter">.</span>operation<span class="Delimiter">);</span> @@ -190,8 +189,8 @@ SCREEN_SHOULD_CONTAIN<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"screen-should-contain"</span>] = SCREEN_SHOULD_CONTAIN<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> SCREEN_SHOULD_CONTAIN: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> +case SCREEN_SHOULD_CONTAIN: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> check_screen<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>name<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> @@ -201,8 +200,8 @@ SCREEN_SHOULD_CONTAIN_IN_COLOR<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"screen-should-contain-in-color"</span>] = SCREEN_SHOULD_CONTAIN_IN_COLOR<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> SCREEN_SHOULD_CONTAIN_IN_COLOR: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> +case SCREEN_SHOULD_CONTAIN_IN_COLOR: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</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">0</span><span class="Delimiter">)));</span> check_screen<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>name<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="Identifier">break</span><span class="Delimiter">;</span> @@ -210,57 +209,57 @@ Recipe_ordinal[<span class="Constant">"screen-should-contain-in-color" <span class="Delimiter">:(before "End Types")</span> <span class="Comment">// scan an array of characters in a unicode-aware, bounds-checked manner</span> -<span class="Normal">struct</span> raw_string_stream <span class="Delimiter">{</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> index<span class="Delimiter">;</span> - <span class="Normal">const</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> max<span class="Delimiter">;</span> - <span class="Normal">const</span> <span class="Normal">char</span>* buf<span class="Delimiter">;</span> +struct raw_string_stream <span class="Delimiter">{</span> + long long int index<span class="Delimiter">;</span> + const long long int max<span class="Delimiter">;</span> + const char* buf<span class="Delimiter">;</span> - raw_string_stream<span class="Delimiter">(</span><span class="Normal">const</span> string&<span class="Delimiter">);</span> - <span class="Normal">uint32_t</span> get<span class="Delimiter">();</span> <span class="Comment">// unicode codepoint</span> - <span class="Normal">uint32_t</span> peek<span class="Delimiter">();</span> <span class="Comment">// unicode codepoint</span> - <span class="Normal">bool</span> at_end<span class="Delimiter">()</span> <span class="Normal">const</span><span class="Delimiter">;</span> - <span class="Normal">void</span> skip_whitespace_and_comments<span class="Delimiter">();</span> + raw_string_stream<span class="Delimiter">(</span>const string&<span class="Delimiter">);</span> + uint32_t get<span class="Delimiter">();</span> <span class="Comment">// unicode codepoint</span> + uint32_t peek<span class="Delimiter">();</span> <span class="Comment">// unicode codepoint</span> + bool at_end<span class="Delimiter">()</span> const<span class="Delimiter">;</span> + void skip_whitespace_and_comments<span class="Delimiter">();</span> <span class="Delimiter">};</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> check_screen<span class="Delimiter">(</span><span class="Normal">const</span> string& expected_contents<span class="Delimiter">,</span> <span class="Normal">const</span> <span class="Normal">int</span> color<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void check_screen<span class="Delimiter">(</span>const string& expected_contents<span class="Delimiter">,</span> const int color<span class="Delimiter">)</span> <span class="Delimiter">{</span> assert<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">// not supported</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> screen_location = Memory[SCREEN]<span class="Delimiter">;</span> - <span class="Normal">int</span> data_offset = find_element_name<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"screen"</span>]<span class="Delimiter">,</span> <span class="Constant">"data"</span><span class="Delimiter">);</span> + long long int screen_location = Memory[SCREEN]<span class="Delimiter">;</span> + int data_offset = find_element_name<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"screen"</span>]<span class="Delimiter">,</span> <span class="Constant">"data"</span><span class="Delimiter">);</span> assert<span class="Delimiter">(</span>data_offset >= <span class="Constant">0</span><span class="Delimiter">);</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> screen_data_location = screen_location+data_offset<span class="Delimiter">;</span> <span class="Comment">// type: address:array:character</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> screen_data_start = Memory[screen_data_location]<span class="Delimiter">;</span> <span class="Comment">// type: array:character</span> - <span class="Normal">int</span> width_offset = find_element_name<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"screen"</span>]<span class="Delimiter">,</span> <span class="Constant">"num-columns"</span><span class="Delimiter">);</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> screen_width = Memory[screen_location+width_offset]<span class="Delimiter">;</span> - <span class="Normal">int</span> height_offset = find_element_name<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"screen"</span>]<span class="Delimiter">,</span> <span class="Constant">"num-rows"</span><span class="Delimiter">);</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> screen_height = Memory[screen_location+height_offset]<span class="Delimiter">;</span> + long long int screen_data_location = screen_location+data_offset<span class="Delimiter">;</span> <span class="Comment">// type: address:array:character</span> + long long int screen_data_start = Memory[screen_data_location]<span class="Delimiter">;</span> <span class="Comment">// type: array:character</span> + int width_offset = find_element_name<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"screen"</span>]<span class="Delimiter">,</span> <span class="Constant">"num-columns"</span><span class="Delimiter">);</span> + long long int screen_width = Memory[screen_location+width_offset]<span class="Delimiter">;</span> + int height_offset = find_element_name<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"screen"</span>]<span class="Delimiter">,</span> <span class="Constant">"num-rows"</span><span class="Delimiter">);</span> + long long int screen_height = Memory[screen_location+height_offset]<span class="Delimiter">;</span> raw_string_stream cursor<span class="Delimiter">(</span>expected_contents<span class="Delimiter">);</span> <span class="Comment">// todo: too-long expected_contents should fail</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> addr = screen_data_start+<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Comment">// skip length</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> row = <span class="Constant">0</span><span class="Delimiter">;</span> row < screen_height<span class="Delimiter">;</span> ++row<span class="Delimiter">)</span> <span class="Delimiter">{</span> + long long int addr = screen_data_start+<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Comment">// skip length</span> + for <span class="Delimiter">(</span>long long int row = <span class="Constant">0</span><span class="Delimiter">;</span> row < screen_height<span class="Delimiter">;</span> ++row<span class="Delimiter">)</span> <span class="Delimiter">{</span> cursor<span class="Delimiter">.</span>skip_whitespace_and_comments<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>cursor<span class="Delimiter">.</span>at_end<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>cursor<span class="Delimiter">.</span>at_end<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span> assert<span class="Delimiter">(</span>cursor<span class="Delimiter">.</span>get<span class="Delimiter">()</span> == <span class="Constant">'.'</span><span class="Delimiter">);</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> column = <span class="Constant">0</span><span class="Delimiter">;</span> column < screen_width<span class="Delimiter">;</span> ++column<span class="Delimiter">,</span> addr+= <span class="Comment">/*</span><span class="Comment">size of screen-cell</span><span class="Comment">*/</span><span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">const</span> <span class="Normal">int</span> cell_color_offset = <span class="Constant">1</span><span class="Delimiter">;</span> - <span class="Normal">uint32_t</span> curr = cursor<span class="Delimiter">.</span>get<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Memory[addr] == <span class="Constant">0</span> && isspace<span class="Delimiter">(</span>curr<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr == <span class="Constant">' '</span> && color != -<span class="Constant">1</span> && color != Memory[addr+cell_color_offset]<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int column = <span class="Constant">0</span><span class="Delimiter">;</span> column < screen_width<span class="Delimiter">;</span> ++column<span class="Delimiter">,</span> addr+= <span class="Comment">/*</span><span class="Comment">size of screen-cell</span><span class="Comment">*/</span><span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + const int cell_color_offset = <span class="Constant">1</span><span class="Delimiter">;</span> + uint32_t curr = cursor<span class="Delimiter">.</span>get<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>Memory[addr] == <span class="Constant">0</span> && isspace<span class="Delimiter">(</span>curr<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>curr == <span class="Constant">' '</span> && color != -<span class="Constant">1</span> && color != Memory[addr+cell_color_offset]<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// filter out other colors</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Memory[addr] != <span class="Constant">0</span> && Memory[addr] == curr<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>color == -<span class="Constant">1</span> || color == Memory[addr+cell_color_offset]<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>Memory[addr] != <span class="Constant">0</span> && Memory[addr] == curr<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>color == -<span class="Constant">1</span> || color == Memory[addr+cell_color_offset]<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Comment">// contents match but color is off</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Current_scenario && !Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Current_scenario && !Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// genuine test in a mu file</span> raise << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span> << Current_scenario<span class="Delimiter">-></span>name << <span class="Constant">": expected screen location ("</span> << row << <span class="Constant">", "</span> << column << <span class="Constant">", address "</span> << addr << <span class="Constant">", value "</span> << Memory[addr] << <span class="Constant">") to be in color "</span> << color << <span class="Constant">" instead of "</span> << Memory[addr+cell_color_offset] << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> + else <span class="Delimiter">{</span> <span class="Comment">// just testing check_screen</span> raise << <span class="Constant">"expected screen location ("</span> << row << <span class="Constant">", "</span> << column << <span class="Constant">") to be in color "</span> << color << <span class="Constant">" instead of "</span> << Memory[addr+cell_color_offset] << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> Passed = <span class="Constant">false</span><span class="Delimiter">;</span> ++Num_failures<span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -269,27 +268,27 @@ Recipe_ordinal[<span class="Constant">"screen-should-contain-in-color" <span class="Comment">// really a mismatch</span> <span class="Comment">// can't print multi-byte unicode characters in warnings just yet. not very useful for debugging anyway.</span> - <span class="Normal">char</span> expected_pretty[<span class="Constant">10</span>] = <span class="Delimiter">{</span><span class="Constant">0</span><span class="Delimiter">};</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr < <span class="Constant">256</span> && !iscntrl<span class="Delimiter">(</span>curr<span class="Delimiter">))</span> <span class="Delimiter">{</span> + char expected_pretty[<span class="Constant">10</span>] = <span class="Delimiter">{</span><span class="Constant">0</span><span class="Delimiter">};</span> + if <span class="Delimiter">(</span>curr < <span class="Constant">256</span> && !iscntrl<span class="Delimiter">(</span>curr<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Comment">// " ('<curr>')"</span> - expected_pretty[<span class="Constant">0</span>] = <span class="Constant">' '</span><span class="Delimiter">,</span> expected_pretty[<span class="Constant">1</span>] = <span class="Constant">'('</span><span class="Delimiter">,</span> expected_pretty[<span class="Constant">2</span>] = <span class="cSpecial">'\''</span><span class="Delimiter">,</span> expected_pretty[<span class="Constant">3</span>] = <span class="Normal">static_cast</span><<span class="Normal">unsigned</span> <span class="Normal">char</span>><span class="Delimiter">(</span>curr<span class="Delimiter">),</span> expected_pretty[<span class="Constant">4</span>] = <span class="cSpecial">'\''</span><span class="Delimiter">,</span> expected_pretty[<span class="Constant">5</span>] = <span class="Constant">')'</span><span class="Delimiter">,</span> expected_pretty[<span class="Constant">6</span>] = <span class="cSpecial">'\0'</span><span class="Delimiter">;</span> + expected_pretty[<span class="Constant">0</span>] = <span class="Constant">' '</span><span class="Delimiter">,</span> expected_pretty[<span class="Constant">1</span>] = <span class="Constant">'('</span><span class="Delimiter">,</span> expected_pretty[<span class="Constant">2</span>] = <span class="cSpecial">'\''</span><span class="Delimiter">,</span> expected_pretty[<span class="Constant">3</span>] = static_cast<unsigned char><span class="Delimiter">(</span>curr<span class="Delimiter">),</span> expected_pretty[<span class="Constant">4</span>] = <span class="cSpecial">'\''</span><span class="Delimiter">,</span> expected_pretty[<span class="Constant">5</span>] = <span class="Constant">')'</span><span class="Delimiter">,</span> expected_pretty[<span class="Constant">6</span>] = <span class="cSpecial">'\0'</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">char</span> actual_pretty[<span class="Constant">10</span>] = <span class="Delimiter">{</span><span class="Constant">0</span><span class="Delimiter">};</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Memory[addr] < <span class="Constant">256</span> && !iscntrl<span class="Delimiter">(</span>Memory[addr]<span class="Delimiter">))</span> <span class="Delimiter">{</span> + char actual_pretty[<span class="Constant">10</span>] = <span class="Delimiter">{</span><span class="Constant">0</span><span class="Delimiter">};</span> + if <span class="Delimiter">(</span>Memory[addr] < <span class="Constant">256</span> && !iscntrl<span class="Delimiter">(</span>Memory[addr]<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Comment">// " ('<curr>')"</span> - actual_pretty[<span class="Constant">0</span>] = <span class="Constant">' '</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">1</span>] = <span class="Constant">'('</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">2</span>] = <span class="cSpecial">'\''</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">3</span>] = <span class="Normal">static_cast</span><<span class="Normal">unsigned</span> <span class="Normal">char</span>><span class="Delimiter">(</span>Memory[addr]<span class="Delimiter">),</span> actual_pretty[<span class="Constant">4</span>] = <span class="cSpecial">'\''</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">5</span>] = <span class="Constant">')'</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">6</span>] = <span class="cSpecial">'\0'</span><span class="Delimiter">;</span> + actual_pretty[<span class="Constant">0</span>] = <span class="Constant">' '</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">1</span>] = <span class="Constant">'('</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">2</span>] = <span class="cSpecial">'\''</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">3</span>] = static_cast<unsigned char><span class="Delimiter">(</span>Memory[addr]<span class="Delimiter">),</span> actual_pretty[<span class="Constant">4</span>] = <span class="cSpecial">'\''</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">5</span>] = <span class="Constant">')'</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">6</span>] = <span class="cSpecial">'\0'</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Current_scenario && !Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Current_scenario && !Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// genuine test in a mu file</span> raise << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span> << Current_scenario<span class="Delimiter">-></span>name << <span class="Constant">": expected screen location ("</span> << row << <span class="Constant">", "</span> << column << <span class="Constant">") to contain "</span> << curr << expected_pretty << <span class="Constant">" instead of "</span> << Memory[addr] << actual_pretty << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> dump_screen<span class="Delimiter">();</span> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> + else <span class="Delimiter">{</span> <span class="Comment">// just testing check_screen</span> raise << <span class="Constant">"expected screen location ("</span> << row << <span class="Constant">", "</span> << column << <span class="Constant">") to contain "</span> << curr << expected_pretty << <span class="Constant">" instead of "</span> << Memory[addr] << actual_pretty << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> Passed = <span class="Constant">false</span><span class="Delimiter">;</span> ++Num_failures<span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -301,43 +300,43 @@ Recipe_ordinal[<span class="Constant">"screen-should-contain-in-color" assert<span class="Delimiter">(</span>cursor<span class="Delimiter">.</span>at_end<span class="Delimiter">());</span> <span class="Delimiter">}</span> -raw_string_stream::raw_string_stream<span class="Delimiter">(</span><span class="Normal">const</span> string& backing<span class="Delimiter">)</span> :index<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">),</span> max<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>backing<span class="Delimiter">)),</span> buf<span class="Delimiter">(</span>backing<span class="Delimiter">.</span>c_str<span class="Delimiter">())</span> <span class="Delimiter">{}</span> +raw_string_stream::raw_string_stream<span class="Delimiter">(</span>const string& backing<span class="Delimiter">)</span> :index<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">),</span> max<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>backing<span class="Delimiter">)),</span> buf<span class="Delimiter">(</span>backing<span class="Delimiter">.</span>c_str<span class="Delimiter">())</span> <span class="Delimiter">{}</span> -<span class="Normal">bool</span> raw_string_stream::at_end<span class="Delimiter">()</span> <span class="Normal">const</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>index >= max<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>tb_utf8_char_length<span class="Delimiter">(</span>buf[index]<span class="Delimiter">)</span> > max-index<span class="Delimiter">)</span> <span class="Delimiter">{</span> - raise << <span class="Constant">"unicode string seems corrupted at index "</span><< index << <span class="Constant">" character "</span> << <span class="Normal">static_cast</span><<span class="Normal">int</span>><span class="Delimiter">(</span>buf[index]<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> +bool raw_string_stream::at_end<span class="Delimiter">()</span> const <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>index >= max<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>tb_utf8_char_length<span class="Delimiter">(</span>buf[index]<span class="Delimiter">)</span> > max-index<span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << <span class="Constant">"unicode string seems corrupted at index "</span><< index << <span class="Constant">" character "</span> << static_cast<int><span class="Delimiter">(</span>buf[index]<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">uint32_t</span> raw_string_stream::get<span class="Delimiter">()</span> <span class="Delimiter">{</span> +uint32_t raw_string_stream::get<span class="Delimiter">()</span> <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>index < max<span class="Delimiter">);</span> <span class="Comment">// caller must check bounds before calling 'get'</span> - <span class="Normal">uint32_t</span> result = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">int</span> length = tb_utf8_char_to_unicode<span class="Delimiter">(</span>&result<span class="Delimiter">,</span> &buf[index]<span class="Delimiter">);</span> + uint32_t result = <span class="Constant">0</span><span class="Delimiter">;</span> + int length = tb_utf8_char_to_unicode<span class="Delimiter">(</span>&result<span class="Delimiter">,</span> &buf[index]<span class="Delimiter">);</span> assert<span class="Delimiter">(</span>length != TB_EOF<span class="Delimiter">);</span> index += length<span class="Delimiter">;</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">uint32_t</span> raw_string_stream::peek<span class="Delimiter">()</span> <span class="Delimiter">{</span> +uint32_t raw_string_stream::peek<span class="Delimiter">()</span> <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>index < max<span class="Delimiter">);</span> <span class="Comment">// caller must check bounds before calling 'get'</span> - <span class="Normal">uint32_t</span> result = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">int</span> length = tb_utf8_char_to_unicode<span class="Delimiter">(</span>&result<span class="Delimiter">,</span> &buf[index]<span class="Delimiter">);</span> + uint32_t result = <span class="Constant">0</span><span class="Delimiter">;</span> + int length = tb_utf8_char_to_unicode<span class="Delimiter">(</span>&result<span class="Delimiter">,</span> &buf[index]<span class="Delimiter">);</span> assert<span class="Delimiter">(</span>length != TB_EOF<span class="Delimiter">);</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> raw_string_stream::skip_whitespace_and_comments<span class="Delimiter">()</span> <span class="Delimiter">{</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>!at_end<span class="Delimiter">())</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>isspace<span class="Delimiter">(</span>peek<span class="Delimiter">()))</span> get<span class="Delimiter">();</span> - <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>peek<span class="Delimiter">()</span> == <span class="Constant">'#'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +void raw_string_stream::skip_whitespace_and_comments<span class="Delimiter">()</span> <span class="Delimiter">{</span> + while <span class="Delimiter">(</span>!at_end<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>isspace<span class="Delimiter">(</span>peek<span class="Delimiter">()))</span> get<span class="Delimiter">();</span> + else if <span class="Delimiter">(</span>peek<span class="Delimiter">()</span> == <span class="Constant">'#'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// skip comment</span> get<span class="Delimiter">();</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>peek<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> get<span class="Delimiter">();</span> <span class="Comment">// implicitly also handles CRLF</span> + while <span class="Delimiter">(</span>peek<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> get<span class="Delimiter">();</span> <span class="Comment">// implicitly also handles CRLF</span> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Identifier">break</span><span class="Delimiter">;</span> + else <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> @@ -346,31 +345,31 @@ _DUMP_SCREEN<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"$dump-screen"</span>] = _DUMP_SCREEN<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> _DUMP_SCREEN: <span class="Delimiter">{</span> +case _DUMP_SCREEN: <span class="Delimiter">{</span> dump_screen<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> dump_screen<span class="Delimiter">()</span> <span class="Delimiter">{</span> +void dump_screen<span class="Delimiter">()</span> <span class="Delimiter">{</span> assert<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">// not supported</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> screen_location = Memory[SCREEN]<span class="Delimiter">;</span> - <span class="Normal">int</span> width_offset = find_element_name<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"screen"</span>]<span class="Delimiter">,</span> <span class="Constant">"num-columns"</span><span class="Delimiter">);</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> screen_width = Memory[screen_location+width_offset]<span class="Delimiter">;</span> - <span class="Normal">int</span> height_offset = find_element_name<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"screen"</span>]<span class="Delimiter">,</span> <span class="Constant">"num-rows"</span><span class="Delimiter">);</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> screen_height = Memory[screen_location+height_offset]<span class="Delimiter">;</span> - <span class="Normal">int</span> data_offset = find_element_name<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"screen"</span>]<span class="Delimiter">,</span> <span class="Constant">"data"</span><span class="Delimiter">);</span> + long long int screen_location = Memory[SCREEN]<span class="Delimiter">;</span> + int width_offset = find_element_name<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"screen"</span>]<span class="Delimiter">,</span> <span class="Constant">"num-columns"</span><span class="Delimiter">);</span> + long long int screen_width = Memory[screen_location+width_offset]<span class="Delimiter">;</span> + int height_offset = find_element_name<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"screen"</span>]<span class="Delimiter">,</span> <span class="Constant">"num-rows"</span><span class="Delimiter">);</span> + long long int screen_height = Memory[screen_location+height_offset]<span class="Delimiter">;</span> + int data_offset = find_element_name<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"screen"</span>]<span class="Delimiter">,</span> <span class="Constant">"data"</span><span class="Delimiter">);</span> assert<span class="Delimiter">(</span>data_offset >= <span class="Constant">0</span><span class="Delimiter">);</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> screen_data_location = screen_location+data_offset<span class="Delimiter">;</span> <span class="Comment">// type: address:array:character</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> screen_data_start = Memory[screen_data_location]<span class="Delimiter">;</span> <span class="Comment">// type: array:character</span> + long long int screen_data_location = screen_location+data_offset<span class="Delimiter">;</span> <span class="Comment">// type: address:array:character</span> + long long int screen_data_start = Memory[screen_data_location]<span class="Delimiter">;</span> <span class="Comment">// type: array:character</span> assert<span class="Delimiter">(</span>Memory[screen_data_start] == screen_width*screen_height<span class="Delimiter">);</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> curr = screen_data_start+<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Comment">// skip length</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> row = <span class="Constant">0</span><span class="Delimiter">;</span> row < screen_height<span class="Delimiter">;</span> ++row<span class="Delimiter">)</span> <span class="Delimiter">{</span> + long long int curr = screen_data_start+<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Comment">// skip length</span> + for <span class="Delimiter">(</span>long long int row = <span class="Constant">0</span><span class="Delimiter">;</span> row < screen_height<span class="Delimiter">;</span> ++row<span class="Delimiter">)</span> <span class="Delimiter">{</span> cerr << <span class="Constant">'.'</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> col = <span class="Constant">0</span><span class="Delimiter">;</span> col < screen_width<span class="Delimiter">;</span> ++col<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Memory[curr]<span class="Delimiter">)</span> + for <span class="Delimiter">(</span>long long int col = <span class="Constant">0</span><span class="Delimiter">;</span> col < screen_width<span class="Delimiter">;</span> ++col<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Memory[curr]<span class="Delimiter">)</span> cerr << to_unicode<span class="Delimiter">(</span>Memory[curr]<span class="Delimiter">);</span> - <span class="Normal">else</span> + else cerr << <span class="Constant">' '</span><span class="Delimiter">;</span> curr += <span class="Comment">/*</span><span class="Comment">size of screen-cell</span><span class="Comment">*/</span><span class="Constant">2</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> diff --git a/html/073scenario_screen_test.mu.html b/html/073scenario_screen_test.mu.html index 71c878ca..aa6f42b9 100644 --- a/html/073scenario_screen_test.mu.html +++ b/html/073scenario_screen_test.mu.html @@ -30,7 +30,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <pre id='vimCodeElement'> <span class="Comment"># To check our support for screens in scenarios, rewrite tests from print.mu</span> -<span class="muScenario">scenario</span> print-character-at-top-left2 [ +<span class="muScenario">scenario</span> print-character-at-top-left-2 [ assume-screen <span class="Constant">3/width</span>, <span class="Constant">2/height</span> run [ screen:address<span class="Special"> <- </span>print-character screen:address, <span class="Constant">97/a</span> @@ -41,7 +41,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<span class="muScenario">scenario</span> clear-line-erases-printed-characters2 [ +<span class="muScenario">scenario</span> clear-line-erases-printed-characters-2 [ assume-screen <span class="Constant">5/width</span>, <span class="Constant">3/height</span> run [ <span class="Comment"># print a character</span> diff --git a/html/074console.mu.html b/html/074console.mu.html index f362e5bd..04b12ea8 100644 --- a/html/074console.mu.html +++ b/html/074console.mu.html @@ -13,12 +13,12 @@ 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; } -.muControl { color: #c0a020; } .muRecipe { color: #ff8700; } -.Delimiter { color: #a04060; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .Special { color: #ff6060; } +.Delimiter { color: #a04060; } +.muControl { color: #c0a020; } --> </style> @@ -37,6 +37,7 @@ exclusive-container event [ text:character keycode:number <span class="Comment"># keys on keyboard without a unicode representation</span> touch:touch-event <span class="Comment"># mouse, track ball, etc.</span> + resize:resize-event <span class="Comment"># update the assume-console handler if you add more variants</span> ] @@ -46,6 +47,11 @@ container touch-event [ column:number ] +container resize-event [ + width:number + height:number +] + container console [ index:number data:address:array:event @@ -79,8 +85,7 @@ container console [ *idx<span class="Special"> <- </span>add *idx, <span class="Constant">1</span> <span class="muControl">reply</span> result, x/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">1/found</span>, <span class="Constant">0/quit</span> <span class="Delimiter">}</span> - <span class="Comment"># real event source is infrequent; avoid polling it too much</span> - switch + switch <span class="Comment"># real event source is infrequent; avoid polling it too much</span> result:event, found?:boolean<span class="Special"> <- </span>check-for-interaction <span class="muControl">reply</span> result, x/same-as-ingredient:<span class="Constant">0</span>, found?, <span class="Constant">0/quit</span> ] diff --git a/html/075scenario_console.cc.html b/html/075scenario_console.cc.html index 96de3221..16b68e11 100644 --- a/html/075scenario_console.cc.html +++ b/html/075scenario_console.cc.html @@ -13,14 +13,13 @@ 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; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } .CommentedCode { color: #6c6c6c; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } --> </style> @@ -64,13 +63,13 @@ scenario keyboard-in-scenario [ ] <span class="Delimiter">:(before "End Scenario Globals")</span> -<span class="Normal">const</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> CONSOLE = Next_predefined_global_for_scenarios++<span class="Delimiter">;</span> +const long long int CONSOLE = Next_predefined_global_for_scenarios++<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Special Scenario Variable Names(r)")</span> Name[r][<span class="Constant">"console"</span>] = CONSOLE<span class="Delimiter">;</span> <span class="Comment">//: allow naming just for 'console'</span> <span class="Delimiter">:(before "End is_special_name Cases")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>s == <span class="Constant">"console"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> +if <span class="Delimiter">(</span>s == <span class="Constant">"console"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Comment">//: Unlike assume-keyboard, assume-console is easiest to implement as just a</span> <span class="Comment">//: primitive recipe.</span> @@ -79,22 +78,22 @@ ASSUME_CONSOLE<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"assume-console"</span>] = ASSUME_CONSOLE<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> ASSUME_CONSOLE: <span class="Delimiter">{</span> +case ASSUME_CONSOLE: <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << "aaa: " << current_instruction().ingredients.at(0).name << '\n'; //? 2</span> <span class="Comment">// create a temporary recipe just for parsing; it won't contain valid instructions</span> istringstream in<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><span class="Delimiter">);</span> recipe r = slurp_recipe<span class="Delimiter">(</span>in<span class="Delimiter">);</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> num_events = count_events<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + long long int num_events = count_events<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="CommentedCode">//? cerr << "fff: " << num_events << '\n'; //? 3</span> <span class="Comment">// initialize the events</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> size = num_events*size_of_event<span class="Delimiter">()</span> + <span class="Comment">/*</span><span class="Comment">space for length</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> + long long int size = num_events*size_of_event<span class="Delimiter">()</span> + <span class="Comment">/*</span><span class="Comment">space for length</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> ensure_space<span class="Delimiter">(</span>size<span class="Delimiter">);</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> event_data_address = Current_routine<span class="Delimiter">-></span>alloc<span class="Delimiter">;</span> + long long int event_data_address = Current_routine<span class="Delimiter">-></span>alloc<span class="Delimiter">;</span> Memory[event_data_address] = num_events<span class="Delimiter">;</span> ++Current_routine<span class="Delimiter">-></span>alloc<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">const</span> instruction& curr = r<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"left-click"</span><span class="Delimiter">)</span> <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>r<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + const instruction& curr = r<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> + if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"left-click"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> Memory[Current_routine<span class="Delimiter">-></span>alloc] = <span class="Comment">/*</span><span class="Comment">tag for 'touch-event' variant of 'event' exclusive-container</span><span class="Comment">*/</span><span class="Constant">2</span><span class="Delimiter">;</span> Memory[Current_routine<span class="Delimiter">-></span>alloc+<span class="Constant">1</span>+<span class="Comment">/*</span><span class="Comment">offset of 'type' in 'mouse-event'</span><span class="Comment">*/</span><span class="Constant">0</span>] = TB_KEY_MOUSE_LEFT<span class="Delimiter">;</span> Memory[Current_routine<span class="Delimiter">-></span>alloc+<span class="Constant">1</span>+<span class="Comment">/*</span><span class="Comment">offset of 'row' in 'mouse-event'</span><span class="Comment">*/</span><span class="Constant">1</span>] = to_integer<span class="Delimiter">(</span>curr<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> @@ -102,24 +101,24 @@ Recipe_ordinal[<span class="Constant">"assume-console"</span>] = ASSUM <span class="CommentedCode">//? cerr << "AA left click: " << Memory[Current_routine->alloc+2] << ' ' << Memory[Current_routine->alloc+3] << '\n'; //? 1</span> Current_routine<span class="Delimiter">-></span>alloc += size_of_event<span class="Delimiter">();</span> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"press"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + else if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"press"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> Memory[Current_routine<span class="Delimiter">-></span>alloc] = <span class="Comment">/*</span><span class="Comment">tag for 'keycode' variant of 'event' exclusive-container</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> Memory[Current_routine<span class="Delimiter">-></span>alloc+<span class="Constant">1</span>] = to_integer<span class="Delimiter">(</span>curr<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="CommentedCode">//? cerr << "AA press: " << Memory[Current_routine->alloc+1] << '\n'; //? 3</span> Current_routine<span class="Delimiter">-></span>alloc += size_of_event<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Comment">// End Event Handlers</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> + else <span class="Delimiter">{</span> <span class="Comment">// keyboard input</span> assert<span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"type"</span><span class="Delimiter">);</span> - <span class="Normal">const</span> string& contents = curr<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="Normal">const</span> <span class="Normal">char</span>* raw_contents = contents<span class="Delimiter">.</span>c_str<span class="Delimiter">();</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> num_keyboard_events = unicode_length<span class="Delimiter">(</span>contents<span class="Delimiter">);</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> curr = <span class="Constant">0</span><span class="Delimiter">;</span> + const string& contents = curr<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> + const char* raw_contents = contents<span class="Delimiter">.</span>c_str<span class="Delimiter">();</span> + long long int num_keyboard_events = unicode_length<span class="Delimiter">(</span>contents<span class="Delimiter">);</span> + long long int curr = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="CommentedCode">//? cerr << "AAA: " << num_keyboard_events << '\n'; //? 1</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < num_keyboard_events<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < num_keyboard_events<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> Memory[Current_routine<span class="Delimiter">-></span>alloc] = <span class="Comment">/*</span><span class="Comment">tag for 'text' variant of 'event' exclusive-container</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">uint32_t</span> curr_character<span class="Delimiter">;</span> + uint32_t curr_character<span class="Delimiter">;</span> assert<span class="Delimiter">(</span>curr < SIZE<span class="Delimiter">(</span>contents<span class="Delimiter">));</span> tb_utf8_char_to_unicode<span class="Delimiter">(</span>&curr_character<span class="Delimiter">,</span> &raw_contents[curr]<span class="Delimiter">);</span> <span class="CommentedCode">//? cerr << "AA keyboard: " << curr_character << '\n'; //? 3</span> @@ -198,57 +197,57 @@ REPLACE_IN_CONSOLE<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"replace-in-console"</span>] = REPLACE_IN_CONSOLE<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> REPLACE_IN_CONSOLE: <span class="Delimiter">{</span> +case REPLACE_IN_CONSOLE: <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> <span class="CommentedCode">//? cerr << "console: " << Memory[CONSOLE] << '\n'; //? 1</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Memory[CONSOLE]<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!Memory[CONSOLE]<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << <span class="Constant">"console not initialized</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> console_data = Memory[Memory[CONSOLE]+<span class="Constant">1</span>]<span class="Delimiter">;</span> + long long int console_data = Memory[Memory[CONSOLE]+<span class="Constant">1</span>]<span class="Delimiter">;</span> <span class="CommentedCode">//? cerr << "console data starts at " << console_data << '\n'; //? 1</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> size = Memory[console_data]<span class="Delimiter">;</span> <span class="Comment">// array size</span> + long long int size = Memory[console_data]<span class="Delimiter">;</span> <span class="Comment">// array size</span> <span class="CommentedCode">//? cerr << "size of console data is " << size << '\n'; //? 1</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">,</span> curr = console_data+<span class="Constant">1</span><span class="Delimiter">;</span> i < size<span class="Delimiter">;</span> ++i<span class="Delimiter">,</span> curr+=size_of_event<span class="Delimiter">())</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">,</span> curr = console_data+<span class="Constant">1</span><span class="Delimiter">;</span> i < size<span class="Delimiter">;</span> ++i<span class="Delimiter">,</span> curr+=size_of_event<span class="Delimiter">())</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << curr << '\n'; //? 1</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Memory[curr] != <span class="Comment">/*</span><span class="Comment">text</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Memory[curr+<span class="Constant">1</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="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> n = <span class="Constant">0</span><span class="Delimiter">;</span> n < size_of_event<span class="Delimiter">();</span> ++n<span class="Delimiter">)</span> + if <span class="Delimiter">(</span>Memory[curr] != <span class="Comment">/*</span><span class="Comment">text</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>Memory[curr+<span class="Constant">1</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="Identifier">continue</span><span class="Delimiter">;</span> + for <span class="Delimiter">(</span>long long int n = <span class="Constant">0</span><span class="Delimiter">;</span> n < size_of_event<span class="Delimiter">();</span> ++n<span class="Delimiter">)</span> Memory[curr+n] = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span>n<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> count_events<span class="Delimiter">(</span><span class="Normal">const</span> recipe& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> result = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">const</span> instruction& curr = r<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> +long long int count_events<span class="Delimiter">(</span>const recipe& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + long long int result = <span class="Constant">0</span><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>r<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + const instruction& curr = r<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> <span class="CommentedCode">//? cerr << "aa: " << curr.name << '\n'; //? 3</span> <span class="CommentedCode">//? cerr << "bb: " << curr.ingredients.at(0).name << '\n'; //? 1</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"type"</span><span class="Delimiter">)</span> + if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"type"</span><span class="Delimiter">)</span> result += unicode_length<span class="Delimiter">(</span>curr<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="Normal">else</span> + else result++<span class="Delimiter">;</span> <span class="CommentedCode">//? cerr << "cc: " << result << '\n'; //? 1</span> <span class="Delimiter">}</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> size_of_event<span class="Delimiter">()</span> <span class="Delimiter">{</span> +long long int size_of_event<span class="Delimiter">()</span> <span class="Delimiter">{</span> <span class="Comment">// memoize result if already computed</span> - <span class="Normal">static</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> result = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>result<span class="Delimiter">)</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> + static long long int result = <span class="Constant">0</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>result<span class="Delimiter">)</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> vector<type_ordinal> type<span class="Delimiter">;</span> type<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"event"</span>]<span class="Delimiter">);</span> result = size_of<span class="Delimiter">(</span>type<span class="Delimiter">);</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> size_of_events<span class="Delimiter">()</span> <span class="Delimiter">{</span> +long long int size_of_events<span class="Delimiter">()</span> <span class="Delimiter">{</span> <span class="Comment">// memoize result if already computed</span> - <span class="Normal">static</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> result = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>result<span class="Delimiter">)</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> + static long long int result = <span class="Constant">0</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>result<span class="Delimiter">)</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> vector<type_ordinal> type<span class="Delimiter">;</span> assert<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"console"</span>]<span class="Delimiter">);</span> type<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"console"</span>]<span class="Delimiter">);</span> diff --git a/html/080trace_browser.cc.html b/html/080trace_browser.cc.html index 8a750a50..0cc056d9 100644 --- a/html/080trace_browser.cc.html +++ b/html/080trace_browser.cc.html @@ -13,13 +13,12 @@ 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; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.CommentedCode { color: #6c6c6c; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } -.CommentedCode { color: #6c6c6c; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } --> </style> @@ -36,31 +35,31 @@ _BROWSE_TRACE<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"$browse-trace"</span>] = _BROWSE_TRACE<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> _BROWSE_TRACE: <span class="Delimiter">{</span> +case _BROWSE_TRACE: <span class="Delimiter">{</span> start_trace_browser<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Globals")</span> -set<<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>> Visible<span class="Delimiter">;</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> Top_of_screen = <span class="Constant">0</span><span class="Delimiter">;</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> Last_printed_row = <span class="Constant">0</span><span class="Delimiter">;</span> -map<<span class="Normal">int</span><span class="Delimiter">,</span> <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span>> Trace_index<span class="Delimiter">;</span> <span class="Comment">// screen row -> trace index</span> +set<long long int> Visible<span class="Delimiter">;</span> +long long int Top_of_screen = <span class="Constant">0</span><span class="Delimiter">;</span> +long long int Last_printed_row = <span class="Constant">0</span><span class="Delimiter">;</span> +map<int<span class="Delimiter">,</span> long long int> Trace_index<span class="Delimiter">;</span> <span class="Comment">// screen row -> trace index</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> start_trace_browser<span class="Delimiter">()</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Trace_stream<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> +void start_trace_browser<span class="Delimiter">()</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!Trace_stream<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> cerr << <span class="Constant">"computing depth to display</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> min_depth = <span class="Constant">9999</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + long long int min_depth = <span class="Constant">9999</span><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>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> trace_line& curr_line = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth < min_depth<span class="Delimiter">)</span> min_depth = curr_line<span class="Delimiter">.</span>depth<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth < min_depth<span class="Delimiter">)</span> min_depth = curr_line<span class="Delimiter">.</span>depth<span class="Delimiter">;</span> <span class="Delimiter">}</span> cerr << <span class="Constant">"depth is "</span> << min_depth << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> cerr << <span class="Constant">"computing lines to display</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>depth == min_depth<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>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>depth == min_depth<span class="Delimiter">)</span> Visible<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>i<span class="Delimiter">);</span> <span class="Delimiter">}</span> tb_init<span class="Delimiter">();</span> @@ -68,62 +67,62 @@ map<<span class="Normal">int</span><span class="Delimiter">,</span> <span cla tb_event event<span class="Delimiter">;</span> Top_of_screen = <span class="Constant">0</span><span class="Delimiter">;</span> refresh_screen_rows<span class="Delimiter">();</span> - <span class="Normal">while</span> <span class="Delimiter">(</span><span class="Constant">true</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + while <span class="Delimiter">(</span><span class="Constant">true</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> render<span class="Delimiter">();</span> - <span class="Normal">do</span> <span class="Delimiter">{</span> + do <span class="Delimiter">{</span> tb_poll_event<span class="Delimiter">(</span>&event<span class="Delimiter">);</span> - <span class="Delimiter">}</span> <span class="Normal">while</span> <span class="Delimiter">(</span>event<span class="Delimiter">.</span>type != TB_EVENT_KEY<span class="Delimiter">);</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> key = event<span class="Delimiter">.</span>key ? event<span class="Delimiter">.</span>key : event<span class="Delimiter">.</span>ch<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>key == <span class="Constant">'q'</span> || key == <span class="Constant">'Q'</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>key == <span class="Constant">'j'</span> || key == TB_KEY_ARROW_DOWN<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Delimiter">}</span> while <span class="Delimiter">(</span>event<span class="Delimiter">.</span>type != TB_EVENT_KEY<span class="Delimiter">);</span> + long long int key = event<span class="Delimiter">.</span>key ? event<span class="Delimiter">.</span>key : event<span class="Delimiter">.</span>ch<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>key == <span class="Constant">'q'</span> || key == <span class="Constant">'Q'</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>key == <span class="Constant">'j'</span> || key == TB_KEY_ARROW_DOWN<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// move cursor one line down</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Display_row < Last_printed_row<span class="Delimiter">)</span> ++Display_row<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>Display_row < Last_printed_row<span class="Delimiter">)</span> ++Display_row<span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>key == <span class="Constant">'k'</span> || key == TB_KEY_ARROW_UP<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>key == <span class="Constant">'k'</span> || key == TB_KEY_ARROW_UP<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// move cursor one line up</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Display_row > <span class="Constant">0</span><span class="Delimiter">)</span> --Display_row<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>Display_row > <span class="Constant">0</span><span class="Delimiter">)</span> --Display_row<span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>key == <span class="Constant">'H'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>key == <span class="Constant">'H'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// move cursor to top of screen</span> Display_row = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>key == <span class="Constant">'M'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>key == <span class="Constant">'M'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// move cursor to center of screen</span> Display_row = tb_height<span class="Delimiter">()</span>/<span class="Constant">2</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>key == <span class="Constant">'L'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>key == <span class="Constant">'L'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// move cursor to bottom of screen</span> Display_row = tb_height<span class="Delimiter">()</span>-<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>key == <span class="Constant">'J'</span> || key == TB_KEY_PGDN<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>key == <span class="Constant">'J'</span> || key == TB_KEY_PGDN<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// page-down</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Trace_index<span class="Delimiter">.</span>find<span class="Delimiter">(</span>tb_height<span class="Delimiter">()</span>-<span class="Constant">1</span><span class="Delimiter">)</span> != Trace_index<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Trace_index<span class="Delimiter">.</span>find<span class="Delimiter">(</span>tb_height<span class="Delimiter">()</span>-<span class="Constant">1</span><span class="Delimiter">)</span> != Trace_index<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> Top_of_screen = Trace_index[tb_height<span class="Delimiter">()</span>-<span class="Constant">1</span>]+<span class="Constant">1</span><span class="Delimiter">;</span> refresh_screen_rows<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>key == <span class="Constant">'K'</span> || key == TB_KEY_PGUP<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>key == <span class="Constant">'K'</span> || key == TB_KEY_PGUP<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// page-up is more convoluted</span> <span class="CommentedCode">//? tb_shutdown(); //? 1</span> <span class="CommentedCode">//? cerr << "page-up: Top_of_screen is currently " << Top_of_screen << '\n'; //? 1</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> screen_row = tb_height<span class="Delimiter">();</span> screen_row > <span class="Constant">0</span> && Top_of_screen > <span class="Constant">0</span><span class="Delimiter">;</span> --screen_row<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>int screen_row = tb_height<span class="Delimiter">();</span> screen_row > <span class="Constant">0</span> && Top_of_screen > <span class="Constant">0</span><span class="Delimiter">;</span> --screen_row<span class="Delimiter">)</span> <span class="Delimiter">{</span> --Top_of_screen<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Top_of_screen <= <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>Top_of_screen > <span class="Constant">0</span> && Visible<span class="Delimiter">.</span>find<span class="Delimiter">(</span>Top_of_screen<span class="Delimiter">)</span> == Visible<span class="Delimiter">.</span>end<span class="Delimiter">())</span> + if <span class="Delimiter">(</span>Top_of_screen <= <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> + while <span class="Delimiter">(</span>Top_of_screen > <span class="Constant">0</span> && Visible<span class="Delimiter">.</span>find<span class="Delimiter">(</span>Top_of_screen<span class="Delimiter">)</span> == Visible<span class="Delimiter">.</span>end<span class="Delimiter">())</span> --Top_of_screen<span class="Delimiter">;</span> <span class="CommentedCode">//? cerr << "now " << Top_of_screen << '\n'; //? 1</span> <span class="Delimiter">}</span> <span class="CommentedCode">//? exit(0); //? 1</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Top_of_screen > <span class="Constant">0</span><span class="Delimiter">)</span> + if <span class="Delimiter">(</span>Top_of_screen > <span class="Constant">0</span><span class="Delimiter">)</span> refresh_screen_rows<span class="Delimiter">();</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>key == <span class="Constant">'G'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>key == <span class="Constant">'G'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// go to bottom of screen; largely like page-up, interestingly</span> Top_of_screen = SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> screen_row = tb_height<span class="Delimiter">();</span> screen_row > <span class="Constant">0</span> && Top_of_screen > <span class="Constant">0</span><span class="Delimiter">;</span> --screen_row<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>int screen_row = tb_height<span class="Delimiter">();</span> screen_row > <span class="Constant">0</span> && Top_of_screen > <span class="Constant">0</span><span class="Delimiter">;</span> --screen_row<span class="Delimiter">)</span> <span class="Delimiter">{</span> --Top_of_screen<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Top_of_screen <= <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>Top_of_screen > <span class="Constant">0</span> && Visible<span class="Delimiter">.</span>find<span class="Delimiter">(</span>Top_of_screen<span class="Delimiter">)</span> == Visible<span class="Delimiter">.</span>end<span class="Delimiter">())</span> + if <span class="Delimiter">(</span>Top_of_screen <= <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> + while <span class="Delimiter">(</span>Top_of_screen > <span class="Constant">0</span> && Visible<span class="Delimiter">.</span>find<span class="Delimiter">(</span>Top_of_screen<span class="Delimiter">)</span> == Visible<span class="Delimiter">.</span>end<span class="Delimiter">())</span> --Top_of_screen<span class="Delimiter">;</span> <span class="Delimiter">}</span> refresh_screen_rows<span class="Delimiter">();</span> @@ -131,29 +130,29 @@ map<<span class="Normal">int</span><span class="Delimiter">,</span> <span cla Display_row = Last_printed_row<span class="Delimiter">;</span> refresh_screen_rows<span class="Delimiter">();</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>key == TB_KEY_CARRIAGE_RETURN<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>key == TB_KEY_CARRIAGE_RETURN<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// expand lines under current by one level</span> <span class="CommentedCode">//? tb_shutdown();</span> assert<span class="Delimiter">(</span>Trace_index<span class="Delimiter">.</span>find<span class="Delimiter">(</span>Display_row<span class="Delimiter">)</span> != Trace_index<span class="Delimiter">.</span>end<span class="Delimiter">());</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> start_index = Trace_index[Display_row]<span class="Delimiter">;</span> + long long int start_index = Trace_index[Display_row]<span class="Delimiter">;</span> <span class="CommentedCode">//? cerr << "start_index is " << start_index << '\n';</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> index = <span class="Constant">0</span><span class="Delimiter">;</span> + long long int index = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Comment">// simultaneously compute end_index and min_depth</span> - <span class="Normal">int</span> min_depth = <span class="Constant">9999</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>index = start_index+<span class="Constant">1</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Visible<span class="Delimiter">.</span>find<span class="Delimiter">(</span>index<span class="Delimiter">)</span> != Visible<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span> + int min_depth = <span class="Constant">9999</span><span class="Delimiter">;</span> + for <span class="Delimiter">(</span>index = start_index+<span class="Constant">1</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Visible<span class="Delimiter">.</span>find<span class="Delimiter">(</span>index<span class="Delimiter">)</span> != Visible<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span> trace_line& curr_line = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> assert<span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth > Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>start_index<span class="Delimiter">).</span>depth<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth < min_depth<span class="Delimiter">)</span> min_depth = curr_line<span class="Delimiter">.</span>depth<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth < min_depth<span class="Delimiter">)</span> min_depth = curr_line<span class="Delimiter">.</span>depth<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="CommentedCode">//? cerr << "min_depth is " << min_depth << '\n';</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> end_index = index<span class="Delimiter">;</span> + long long int end_index = index<span class="Delimiter">;</span> <span class="CommentedCode">//? cerr << "end_index is " << end_index << '\n';</span> <span class="Comment">// mark as visible all intervening indices at min_depth</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>index = start_index<span class="Delimiter">;</span> index < end_index<span class="Delimiter">;</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>index = start_index<span class="Delimiter">;</span> index < end_index<span class="Delimiter">;</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> trace_line& curr_line = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth == min_depth<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth == min_depth<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="CommentedCode">//? cerr << "adding " << index << '\n';</span> Visible<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>index<span class="Delimiter">);</span> <span class="Delimiter">}</span> @@ -161,22 +160,22 @@ map<<span class="Normal">int</span><span class="Delimiter">,</span> <span cla <span class="CommentedCode">//? exit(0);</span> refresh_screen_rows<span class="Delimiter">();</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>key == TB_KEY_BACKSPACE || key == TB_KEY_BACKSPACE2<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>key == TB_KEY_BACKSPACE || key == TB_KEY_BACKSPACE2<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// collapse all lines under current</span> assert<span class="Delimiter">(</span>Trace_index<span class="Delimiter">.</span>find<span class="Delimiter">(</span>Display_row<span class="Delimiter">)</span> != Trace_index<span class="Delimiter">.</span>end<span class="Delimiter">());</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> start_index = Trace_index[Display_row]<span class="Delimiter">;</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> index = <span class="Constant">0</span><span class="Delimiter">;</span> + long long int start_index = Trace_index[Display_row]<span class="Delimiter">;</span> + long long int index = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Comment">// end_index is the next line at a depth same as or lower than start_index</span> - <span class="Normal">int</span> initial_depth = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>start_index<span class="Delimiter">).</span>depth<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>index = start_index+<span class="Constant">1</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Visible<span class="Delimiter">.</span>find<span class="Delimiter">(</span>index<span class="Delimiter">)</span> == Visible<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + int initial_depth = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>start_index<span class="Delimiter">).</span>depth<span class="Delimiter">;</span> + for <span class="Delimiter">(</span>index = start_index+<span class="Constant">1</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Visible<span class="Delimiter">.</span>find<span class="Delimiter">(</span>index<span class="Delimiter">)</span> == Visible<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> trace_line& curr_line = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth <= initial_depth<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth <= initial_depth<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> end_index = index<span class="Delimiter">;</span> + long long int end_index = index<span class="Delimiter">;</span> <span class="Comment">// mark as visible all intervening indices at min_depth</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>index = start_index+<span class="Constant">1</span><span class="Delimiter">;</span> index < end_index<span class="Delimiter">;</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>index = start_index+<span class="Constant">1</span><span class="Delimiter">;</span> index < end_index<span class="Delimiter">;</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> Visible<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>index<span class="Delimiter">);</span> <span class="Delimiter">}</span> refresh_screen_rows<span class="Delimiter">();</span> @@ -186,40 +185,40 @@ map<<span class="Normal">int</span><span class="Delimiter">,</span> <span cla <span class="Delimiter">}</span> <span class="Comment">// update Trace_indices for each screen_row on the basis of Top_of_screen and Visible</span> -<span class="Normal">void</span> refresh_screen_rows<span class="Delimiter">()</span> <span class="Delimiter">{</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> screen_row = <span class="Constant">0</span><span class="Delimiter">,</span> index = <span class="Constant">0</span><span class="Delimiter">;</span> +void refresh_screen_rows<span class="Delimiter">()</span> <span class="Delimiter">{</span> + long long int screen_row = <span class="Constant">0</span><span class="Delimiter">,</span> index = <span class="Constant">0</span><span class="Delimiter">;</span> Trace_index<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>screen_row = <span class="Constant">0</span><span class="Delimiter">,</span> index = Top_of_screen<span class="Delimiter">;</span> screen_row < tb_height<span class="Delimiter">()</span> && index < SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">);</span> ++screen_row<span class="Delimiter">,</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>screen_row = <span class="Constant">0</span><span class="Delimiter">,</span> index = Top_of_screen<span class="Delimiter">;</span> screen_row < tb_height<span class="Delimiter">()</span> && index < SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">);</span> ++screen_row<span class="Delimiter">,</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// skip lines without depth for now</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>Visible<span class="Delimiter">.</span>find<span class="Delimiter">(</span>index<span class="Delimiter">)</span> == Visible<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> + while <span class="Delimiter">(</span>Visible<span class="Delimiter">.</span>find<span class="Delimiter">(</span>index<span class="Delimiter">)</span> == Visible<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> ++index<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>index >= SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">))</span> <span class="Identifier">goto</span> done<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>index >= SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">))</span> <span class="Identifier">goto</span> done<span class="Delimiter">;</span> <span class="Delimiter">}</span> assert<span class="Delimiter">(</span>index < SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">));</span> Trace_index[screen_row] = index<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">done</span>:<span class="Delimiter">;</span> +done:<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> render<span class="Delimiter">()</span> <span class="Delimiter">{</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> screen_row = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>screen_row = <span class="Constant">0</span><span class="Delimiter">;</span> screen_row < tb_height<span class="Delimiter">();</span> ++screen_row<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Trace_index<span class="Delimiter">.</span>find<span class="Delimiter">(</span>screen_row<span class="Delimiter">)</span> == Trace_index<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span> +void render<span class="Delimiter">()</span> <span class="Delimiter">{</span> + long long int screen_row = <span class="Constant">0</span><span class="Delimiter">;</span> + for <span class="Delimiter">(</span>screen_row = <span class="Constant">0</span><span class="Delimiter">;</span> screen_row < tb_height<span class="Delimiter">();</span> ++screen_row<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>Trace_index<span class="Delimiter">.</span>find<span class="Delimiter">(</span>screen_row<span class="Delimiter">)</span> == Trace_index<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span> trace_line& curr_line = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>Trace_index[screen_row]<span class="Delimiter">);</span> ostringstream out<span class="Delimiter">;</span> out << std::setw<span class="Delimiter">(</span><span class="Constant">4</span><span class="Delimiter">)</span> << curr_line<span class="Delimiter">.</span>depth << <span class="Constant">' '</span> << curr_line<span class="Delimiter">.</span>label << <span class="Constant">": "</span> << curr_line<span class="Delimiter">.</span>contents<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>screen_row < tb_height<span class="Delimiter">()</span>-<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> delta = lines_hidden<span class="Delimiter">(</span>screen_row<span class="Delimiter">);</span> + if <span class="Delimiter">(</span>screen_row < tb_height<span class="Delimiter">()</span>-<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + long long int delta = lines_hidden<span class="Delimiter">(</span>screen_row<span class="Delimiter">);</span> <span class="Comment">// home-brew escape sequence for red</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>delta > <span class="Constant">999</span><span class="Delimiter">)</span> out << <span class="Constant">"{"</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>delta > <span class="Constant">999</span><span class="Delimiter">)</span> out << <span class="Constant">"{"</span><span class="Delimiter">;</span> out << <span class="Constant">" ("</span> << lines_hidden<span class="Delimiter">(</span>screen_row<span class="Delimiter">)</span> << <span class="Constant">")"</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>delta > <span class="Constant">999</span><span class="Delimiter">)</span> out << <span class="Constant">"}"</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>delta > <span class="Constant">999</span><span class="Delimiter">)</span> out << <span class="Constant">"}"</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> render_line<span class="Delimiter">(</span>screen_row<span class="Delimiter">,</span> out<span class="Delimiter">.</span>str<span class="Delimiter">());</span> <span class="Delimiter">}</span> <span class="Comment">// clear rest of screen</span> Last_printed_row = screen_row-<span class="Constant">1</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(;</span> screen_row < tb_height<span class="Delimiter">();</span> ++screen_row<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(;</span> screen_row < tb_height<span class="Delimiter">();</span> ++screen_row<span class="Delimiter">)</span> <span class="Delimiter">{</span> render_line<span class="Delimiter">(</span>screen_row<span class="Delimiter">,</span> <span class="Constant">"~"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Comment">// move cursor back to display row at the end</span> @@ -227,26 +226,26 @@ map<<span class="Normal">int</span><span class="Delimiter">,</span> <span cla tb_present<span class="Delimiter">();</span> <span class="Delimiter">}</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> lines_hidden<span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> screen_row<span class="Delimiter">)</span> <span class="Delimiter">{</span> +long long int lines_hidden<span class="Delimiter">(</span>long long int screen_row<span class="Delimiter">)</span> <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>Trace_index<span class="Delimiter">.</span>find<span class="Delimiter">(</span>screen_row<span class="Delimiter">)</span> != Trace_index<span class="Delimiter">.</span>end<span class="Delimiter">());</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Trace_index<span class="Delimiter">.</span>find<span class="Delimiter">(</span>screen_row+<span class="Constant">1</span><span class="Delimiter">)</span> == Trace_index<span class="Delimiter">.</span>end<span class="Delimiter">())</span> + if <span class="Delimiter">(</span>Trace_index<span class="Delimiter">.</span>find<span class="Delimiter">(</span>screen_row+<span class="Constant">1</span><span class="Delimiter">)</span> == Trace_index<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Identifier">return</span> SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">)</span>-Trace_index[screen_row]<span class="Delimiter">;</span> - <span class="Normal">else</span> + else <span class="Identifier">return</span> Trace_index[screen_row+<span class="Constant">1</span>] - Trace_index[screen_row]<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> render_line<span class="Delimiter">(</span><span class="Normal">int</span> screen_row<span class="Delimiter">,</span> <span class="Normal">const</span> string& s<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> col = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">int</span> color = TB_WHITE<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>col = <span class="Constant">0</span><span class="Delimiter">;</span> col < tb_width<span class="Delimiter">()</span> && col < SIZE<span class="Delimiter">(</span>s<span class="Delimiter">);</span> ++col<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">char</span> c = s<span class="Delimiter">.</span>at<span class="Delimiter">(</span>col<span class="Delimiter">);</span> <span class="Comment">// todo: unicode</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>c == <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> c = <span class="Constant">';'</span><span class="Delimiter">;</span> <span class="Comment">// replace newlines with semi-colons</span> +void render_line<span class="Delimiter">(</span>int screen_row<span class="Delimiter">,</span> const string& s<span class="Delimiter">)</span> <span class="Delimiter">{</span> + long long int col = <span class="Constant">0</span><span class="Delimiter">;</span> + int color = TB_WHITE<span class="Delimiter">;</span> + for <span class="Delimiter">(</span>col = <span class="Constant">0</span><span class="Delimiter">;</span> col < tb_width<span class="Delimiter">()</span> && col < SIZE<span class="Delimiter">(</span>s<span class="Delimiter">);</span> ++col<span class="Delimiter">)</span> <span class="Delimiter">{</span> + char c = s<span class="Delimiter">.</span>at<span class="Delimiter">(</span>col<span class="Delimiter">);</span> <span class="Comment">// todo: unicode</span> + if <span class="Delimiter">(</span>c == <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> c = <span class="Constant">';'</span><span class="Delimiter">;</span> <span class="Comment">// replace newlines with semi-colons</span> <span class="Comment">// escapes. hack: can't start a line with them.</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>c == <span class="Constant">'{'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> color = <span class="Comment">/*</span><span class="Comment">red</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> c = <span class="Constant">' '</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>c == <span class="Constant">'}'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> color = TB_WHITE<span class="Delimiter">;</span> c = <span class="Constant">' '</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> + if <span class="Delimiter">(</span>c == <span class="Constant">'{'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> color = <span class="Comment">/*</span><span class="Comment">red</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> c = <span class="Constant">' '</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> + if <span class="Delimiter">(</span>c == <span class="Constant">'}'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> color = TB_WHITE<span class="Delimiter">;</span> c = <span class="Constant">' '</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> tb_change_cell<span class="Delimiter">(</span>col<span class="Delimiter">,</span> screen_row<span class="Delimiter">,</span> c<span class="Delimiter">,</span> color<span class="Delimiter">,</span> TB_BLACK<span class="Delimiter">);</span> <span class="Delimiter">}</span> - <span class="Normal">for</span> <span class="Delimiter">(;</span> col < tb_width<span class="Delimiter">();</span> ++col<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(;</span> col < tb_width<span class="Delimiter">();</span> ++col<span class="Delimiter">)</span> <span class="Delimiter">{</span> tb_change_cell<span class="Delimiter">(</span>col<span class="Delimiter">,</span> screen_row<span class="Delimiter">,</span> <span class="Constant">' '</span><span class="Delimiter">,</span> TB_WHITE<span class="Delimiter">,</span> TB_BLACK<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> diff --git a/html/081run_interactive.cc.html b/html/081run_interactive.cc.html index c70e6213..7b711a4f 100644 --- a/html/081run_interactive.cc.html +++ b/html/081run_interactive.cc.html @@ -13,15 +13,14 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } -.traceContains { color: #008000; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } -.CommentedCode { color: #6c6c6c; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.Identifier { color: #804000; } +.traceContains { color: #008000; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } -.Identifier { color: #804000; } +.CommentedCode { color: #6c6c6c; } +.Constant { color: #00a0a0; } --> </style> @@ -38,7 +37,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">:(scenario run_interactive_code)</span> recipe main [ - <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span><span class="Normal">new</span> [<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>] + <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new [<span class="Constant">1</span>:number/<span class="Special">raw <- </span>copy <span class="Constant">34</span>] run-interactive <span class="Constant">2</span>:address:array:character ] <span class="traceContains">+mem: storing 34 in location 1</span> @@ -61,84 +60,162 @@ RUN_INTERACTIVE<span class="Delimiter">,</span> Recipe_ordinal[<span class="Constant">"run-interactive"</span>] = RUN_INTERACTIVE<span class="Delimiter">;</span> <span class="CommentedCode">//? cerr << "run-interactive: " << RUN_INTERACTIVE << '\n'; //? 1</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> RUN_INTERACTIVE: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case RUN_INTERACTIVE: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'run-interactive' requires exactly one ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> + 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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'run-interactive' should be a literal string, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">bool</span> 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> - <span class="Normal">if</span> <span class="Delimiter">(</span>!new_code_pushed_to_stack<span class="Delimiter">)</span> <span class="Delimiter">{</span> - products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">4</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>resize<span class="Delimiter">(</span><span class="Constant">5</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>trace_contents<span class="Delimiter">(</span><span class="Constant">"warn"</span><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> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">3</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>trace_contents<span class="Delimiter">(</span><span class="Constant">"app"</span><span class="Delimiter">));</span> - clean_up_interactive<span class="Delimiter">();</span> + products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">4</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> <span class="Comment">// completed</span> + cleanup_run_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> - <span class="Normal">else</span> <span class="Delimiter">{</span> + else <span class="Delimiter">{</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Comment">// not done with caller; don't increment current_step_index()</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Globals")</span> -<span class="Normal">bool</span> Running_interactive = <span class="Constant">false</span><span class="Delimiter">;</span> -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> Old_screen = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Comment">// we can support one iteration of screen inside screen</span> +bool Track_most_recent_products = <span class="Constant">false</span><span class="Delimiter">;</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> +Track_most_recent_products = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">:(code)</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> -<span class="Normal">bool</span> run_interactive<span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> address<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <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> +bool run_interactive<span class="Delimiter">(</span>long long int address<span class="Delimiter">)</span> <span class="Delimiter">{</span> + assert<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>] != <span class="Constant">0</span><span class="Delimiter">);</span> <span class="Comment">// try to sandbox the run as best you can</span> <span class="Comment">// todo: test this</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Current_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Comment">// not already sandboxed</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">1</span><span class="Delimiter">;</span> i < Reserved_for_tests<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> + if <span class="Delimiter">(</span>!Current_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</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>read_mu_string<span class="Delimiter">(</span>address<span class="Delimiter">)));</span> - <span class="Normal">if</span> <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> + 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> Recipe<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>Recipe_ordinal[<span class="Constant">"interactive"</span>]<span class="Delimiter">);</span> + Name[Recipe_ordinal[<span class="Constant">"interactive"</span>]]<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> + <span class="Comment">// stuff to undo later, in cleanup_run_interactive()</span> Hide_warnings = <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Trace_stream<span class="Delimiter">)</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 = <span class="Normal">new</span> trace_stream<span class="Delimiter">;</span> + Trace_stream = new trace_stream<span class="Delimiter">;</span> Trace_stream<span class="Delimiter">-></span>collect_layers<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">"warn"</span><span class="Delimiter">);</span> Trace_stream<span class="Delimiter">-></span>collect_layers<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">"app"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Comment">// call run(string) but without the scheduling</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 30, 5</span><span class="cSpecial">\n</span><span class="Constant">"</span> + + <span class="Constant">"local-scope</span><span class="cSpecial">\n</span><span class="Constant">"</span> + + <span class="Constant">"screen:address <- next-ingredient</span><span class="cSpecial">\n</span><span class="Constant">"</span> + + <span class="Constant">"$start-tracking-products</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">"$stop-tracking-products</span><span class="cSpecial">\n</span><span class="Constant">"</span> + + <span class="Constant">"reply screen</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> - <span class="Normal">if</span> <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> + 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> + <span class="Comment">// now call 'sandbox' which will run 'interactive' in a separate routine,</span> + <span class="Comment">// and wait for it</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">"sandbox"</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">:(before "End Load Recipes")</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="Comment">// just a dummy version to initialize the Recipe_ordinal and so on</span> +<span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span> + +<span class="Constant">"recipe sandbox [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + + <span class="Constant">"local-scope</span><span class="cSpecial">\n</span><span class="Constant">"</span> + + <span class="Constant">"screen:address/shared <- new-fake-screen 30, 5</span><span class="cSpecial">\n</span><span class="Constant">"</span> + + <span class="Constant">"r:number/routine_id <- start-running interactive:recipe, screen:address</span><span class="cSpecial">\n</span><span class="Constant">"</span> + + <span class="Constant">"limit-time r, 750/instructions</span><span class="cSpecial">\n</span><span class="Constant">"</span> + + <span class="Constant">"wait-for-routine r</span><span class="cSpecial">\n</span><span class="Constant">"</span> + + <span class="Constant">"sandbox-state:number <- routine-state r/routine_id</span><span class="cSpecial">\n</span><span class="Constant">"</span> + + <span class="Constant">"completed?:boolean <- equal sandbox-state, 1/completed</span><span class="cSpecial">\n</span><span class="Constant">"</span> + + <span class="Constant">"output:address:array:character <- $most-recent-products</span><span class="cSpecial">\n</span><span class="Constant">"</span> + + <span class="Constant">"warnings:address:array:character <- save-trace [warn]</span><span class="cSpecial">\n</span><span class="Constant">"</span> + + <span class="Constant">"stashes:address:array:character <- save-trace [app]</span><span class="cSpecial">\n</span><span class="Constant">"</span> + + <span class="Constant">"$cleanup-run-interactive</span><span class="cSpecial">\n</span><span class="Constant">"</span> + + <span class="Constant">"reply output, warnings, screen, stashes, completed?</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> +recently_added_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> + +<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> +_START_TRACKING_PRODUCTS<span class="Delimiter">,</span> +<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> +Recipe_ordinal[<span class="Constant">"$start-tracking-products"</span>] = _START_TRACKING_PRODUCTS<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> +case _START_TRACKING_PRODUCTS: <span class="Delimiter">{</span> + Track_most_recent_products = <span class="Constant">true</span><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> +_STOP_TRACKING_PRODUCTS<span class="Delimiter">,</span> +<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> +Recipe_ordinal[<span class="Constant">"$stop-tracking-products"</span>] = _STOP_TRACKING_PRODUCTS<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> +case _STOP_TRACKING_PRODUCTS: <span class="Delimiter">{</span> + Track_most_recent_products = <span class="Constant">false</span><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> +_MOST_RECENT_PRODUCTS<span class="Delimiter">,</span> +<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> +Recipe_ordinal[<span class="Constant">"$most-recent-products"</span>] = _MOST_RECENT_PRODUCTS<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> +case _MOST_RECENT_PRODUCTS: <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_mu_string<span class="Delimiter">(</span>Most_recent_products<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> +SAVE_TRACE<span class="Delimiter">,</span> +<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> +Recipe_ordinal[<span class="Constant">"save-trace"</span>] = SAVE_TRACE<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> +case SAVE_TRACE: <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>trace_contents<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>name<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> +_CLEANUP_RUN_INTERACTIVE<span class="Delimiter">,</span> +<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> +Recipe_ordinal[<span class="Constant">"$cleanup-run-interactive"</span>] = _CLEANUP_RUN_INTERACTIVE<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> +case _CLEANUP_RUN_INTERACTIVE: <span class="Delimiter">{</span> + cleanup_run_interactive<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +<span class="Delimiter">:(code)</span> +void cleanup_run_interactive<span class="Delimiter">()</span> <span class="Delimiter">{</span> + Hide_warnings = <span class="Constant">false</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>is_narrowly_collecting<span class="Delimiter">(</span><span class="Constant">"warn"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Comment">// hack</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="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> - <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span><span class="Normal">new</span> [add <span class="Constant">2</span><span class="Delimiter">,</span> <span class="Constant">2</span>] + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new [add <span class="Constant">2</span><span class="Delimiter">,</span> <span class="Constant">2</span>] <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>run-interactive <span class="Constant">1</span>:address:array:character <span class="Constant">10</span>:array:character<span class="Special"> <- </span>copy <span class="Constant">2</span>:address:array:character/lookup ] @@ -148,9 +225,9 @@ recipe main [ <span class="Delimiter">:(scenario "run_interactive_returns_string")</span> recipe main [ <span class="Comment"># try to interactively add 2 and 2</span> - <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span><span class="Normal">new</span> [ - <span class="Constant">100</span>:address:array:character<span class="Special"> <- </span><span class="Normal">new</span> [a] - <span class="Constant">101</span>:address:array:character<span class="Special"> <- </span><span class="Normal">new</span> [b] + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new [ + <span class="Constant">100</span>:address:array:character<span class="Special"> <- </span>new [a] + <span class="Constant">101</span>:address:array:character<span class="Special"> <- </span>new [b] <span class="Constant">102</span>:address:array:character<span class="Special"> <- </span>string-append <span class="Constant">100</span>:address:array:character<span class="Delimiter">,</span> <span class="Constant">101</span>:address:array:character ] <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>run-interactive <span class="Constant">1</span>:address:array:character @@ -163,7 +240,7 @@ recipe main [ <span class="Delimiter">:(scenario "run_interactive_returns_warnings")</span> recipe main [ <span class="Comment"># run a command that generates a warning</span> - <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span><span class="Normal">new</span> [get <span class="Constant">1234</span>:number<span class="Delimiter">,</span> foo:offset] + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new [get <span class="Constant">1234</span>:number<span class="Delimiter">,</span> foo:offset] <span class="Constant">2</span>:address:array:character<span class="Delimiter">,</span> <span class="Constant">3</span>:address:array:character<span class="Special"> <- </span>run-interactive <span class="Constant">1</span>:address:array:character <span class="Constant">10</span>:array:character<span class="Special"> <- </span>copy <span class="Constant">3</span>:address:array:character/lookup ] @@ -174,25 +251,25 @@ recipe main [ <span class="traceContains">+mem: storing 110 in location 14</span> <span class="Delimiter">:(before "End Globals")</span> -string Most_recent_results<span class="Delimiter">;</span> +string Most_recent_products<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Setup")</span> -Most_recent_results = <span class="Constant">""</span><span class="Delimiter">;</span> +Most_recent_products = <span class="Constant">""</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End of Instruction")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>Running_interactive<span class="Delimiter">)</span> <span class="Delimiter">{</span> - record_products<span class="Delimiter">(</span>current_instruction<span class="Delimiter">(),</span> products<span class="Delimiter">);</span> +if <span class="Delimiter">(</span>Track_most_recent_products<span class="Delimiter">)</span> <span class="Delimiter">{</span> + track_most_recent_products<span class="Delimiter">(</span>current_instruction<span class="Delimiter">(),</span> products<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -<span class="Normal">void</span> record_products<span class="Delimiter">(</span><span class="Normal">const</span> instruction& instruction<span class="Delimiter">,</span> <span class="Normal">const</span> vector<vector<<span class="Normal">double</span>> >& products<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void track_most_recent_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="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> + 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> - <span class="Normal">if</span> <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="Normal">if</span> <span class="Delimiter">(</span>is_mu_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="Normal">if</span> <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</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> + if <span class="Delimiter">(</span>is_mu_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> + if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span> tb_shutdown<span class="Delimiter">();</span> cerr << read_mu_string<span class="Delimiter">(</span>trace_contents<span class="Delimiter">(</span><span class="Constant">"warn"</span><span class="Delimiter">))</span> << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> cerr << SIZE<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> << <span class="Constant">": "</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> + 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> cerr << 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> cerr << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -202,114 +279,46 @@ Most_recent_results = <span class="Constant">""</span><span class="Del <span class="Delimiter">}</span> <span class="Comment">// End Record Product Special-cases</span> <span class="Delimiter">}</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> 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> + 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> - 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> -<span class="Normal">if</span> <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">4</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<<span class="Normal">double</span>> result<span class="Delimiter">;</span> - result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_mu_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> - <span class="Normal">if</span> <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<<span class="Normal">double</span>> warnings<span class="Delimiter">;</span> - warnings<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>trace_contents<span class="Delimiter">(</span><span class="Constant">"warn"</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><span class="Constant">1</span><span class="Delimiter">),</span> warnings<span class="Delimiter">);</span> - <span class="Delimiter">}</span> - <span class="Normal">if</span> <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<<span class="Normal">double</span>> screen<span class="Delimiter">;</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="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">)</span> >= <span class="Constant">4</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> -<span class="CommentedCode">//? cerr << "emitting trace\n"; //? 1</span> - vector<<span class="Normal">double</span>> trace<span class="Delimiter">;</span> - trace<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>trace_contents<span class="Delimiter">(</span><span class="Constant">"app"</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><span class="Constant">3</span><span class="Delimiter">),</span> trace<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> -<span class="Normal">bool</span> 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> -<span class="Normal">bool</span> 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> -<span class="Normal">if</span> <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> -<span class="Normal">if</span> <span class="Delimiter">(</span>must_clean_up_interactive<span class="Delimiter">)</span> clean_up_interactive<span class="Delimiter">();</span> -<span class="Delimiter">:(code)</span> -<span class="Normal">void</span> clean_up_interactive<span class="Delimiter">()</span> <span class="Delimiter">{</span> - Trace_stream<span class="Delimiter">-></span>newline<span class="Delimiter">();</span> <span class="Comment">// flush trace</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_layers isn't set anywhere else</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>is_narrowly_collecting<span class="Delimiter">(</span><span class="Constant">"warn"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> - <span class="Normal">delete</span> 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> + Most_recent_products = out<span class="Delimiter">.</span>str<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> string strip_comments<span class="Delimiter">(</span>string in<span class="Delimiter">)</span> <span class="Delimiter">{</span> ostringstream result<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>in<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> != <span class="Constant">'#'</span><span class="Delimiter">)</span> <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>in<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> != <span class="Constant">'#'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> result << in<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>i < SIZE<span class="Delimiter">(</span>in<span class="Delimiter">)</span> && in<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> + else <span class="Delimiter">{</span> + while <span class="Delimiter">(</span>i < SIZE<span class="Delimiter">(</span>in<span class="Delimiter">)</span> && in<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> ++i<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>i < SIZE<span class="Delimiter">(</span>in<span class="Delimiter">)</span> && in<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> ++i<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>i < SIZE<span class="Delimiter">(</span>in<span class="Delimiter">)</span> && in<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> ++i<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Identifier">return</span> result<span class="Delimiter">.</span>str<span class="Delimiter">();</span> <span class="Delimiter">}</span> -string read_mu_string<span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> address<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> size = Memory[address]<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>size == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">""</span><span class="Delimiter">;</span> - ostringstream tmp<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> curr = address+<span class="Constant">1</span><span class="Delimiter">;</span> curr <= address+size<span class="Delimiter">;</span> ++curr<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Comment">// todo: unicode</span> - tmp << <span class="Delimiter">(</span><span class="Normal">char</span><span class="Delimiter">)(</span><span class="Normal">int</span><span class="Delimiter">)</span>Memory[curr]<span class="Delimiter">;</span> - <span class="Delimiter">}</span> - <span class="Identifier">return</span> tmp<span class="Delimiter">.</span>str<span class="Delimiter">();</span> -<span class="Delimiter">}</span> - -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> stringified_value_of_location<span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> address<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> out << Memory[address]<span class="Delimiter">;</span> <span class="Identifier">return</span> new_mu_string<span class="Delimiter">(</span>out<span class="Delimiter">.</span>str<span class="Delimiter">());</span> <span class="Delimiter">}</span> -<span class="Normal">bool</span> is_mu_string<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Identifier">return</span> SIZE<span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">)</span> == <span class="Constant">3</span> - && x<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>] - && x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)</span> == Type_ordinal[<span class="Constant">"array"</span>] - && x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">)</span> == Type_ordinal[<span class="Constant">"character"</span>]<span class="Delimiter">;</span> -<span class="Delimiter">}</span> - -<span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> trace_contents<span class="Delimiter">(</span><span class="Normal">const</span> string& layer<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Trace_stream<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span> +long long int trace_contents<span class="Delimiter">(</span>const string& layer<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!Trace_stream<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span> <span class="CommentedCode">//? cerr << "trace stream exists\n"; //? 1</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span>layer<span class="Delimiter">)</span> <= <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span>layer<span class="Delimiter">)</span> <= <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span> <span class="CommentedCode">//? cerr << layer << " has something\n"; //? 1</span> ostringstream out<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>vector<trace_line>::iterator p = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>p<span class="Delimiter">-></span>label != layer<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + for <span class="Delimiter">(</span>vector<trace_line>::iterator p = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>p<span class="Delimiter">-></span>label != layer<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> out << p<span class="Delimiter">-></span>contents<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>*--p<span class="Delimiter">-></span>contents<span class="Delimiter">.</span>end<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> out << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>*--p<span class="Delimiter">-></span>contents<span class="Delimiter">.</span>end<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> out << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> assert<span class="Delimiter">(</span>!out<span class="Delimiter">.</span>str<span class="Delimiter">().</span>empty<span class="Delimiter">());</span> <span class="CommentedCode">//? cerr << layer << ":\n" << out.str() << "\n--\n"; //? 1</span> @@ -323,23 +332,27 @@ RELOAD<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> Recipe_ordinal[<span class="Constant">"reload"</span>] = RELOAD<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> -<span class="Normal">case</span> RELOAD: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case RELOAD: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'reload' requires exactly one ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> + 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 << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'reload' should be a literal string, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Trace_stream<span class="Delimiter">)</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 = <span class="Normal">new</span> trace_stream<span class="Delimiter">;</span> + Trace_stream = new trace_stream<span class="Delimiter">;</span> Trace_stream<span class="Delimiter">-></span>collect_layers<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">"warn"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> Hide_warnings = <span class="Constant">true</span><span class="Delimiter">;</span> Disable_redefine_warnings = <span class="Constant">true</span><span class="Delimiter">;</span> - load<span class="Delimiter">(</span>read_mu_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> + string code = read_mu_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> + vector<recipe_ordinal> recipes_reloaded = load<span class="Delimiter">(</span>code<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>recipes_reloaded<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + Name<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>recipes_reloaded<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> + <span class="Delimiter">}</span> transform_all<span class="Delimiter">();</span> Trace_stream<span class="Delimiter">-></span>newline<span class="Delimiter">();</span> <span class="Comment">// flush trace</span> Disable_redefine_warnings = <span class="Constant">false</span><span class="Delimiter">;</span> @@ -347,8 +360,8 @@ Recipe_ordinal[<span class="Constant">"reload"</span>] = RELOAD<span c 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>trace_contents<span class="Delimiter">(</span><span class="Constant">"warn"</span><span class="Delimiter">));</span> <span class="Comment">// hack: assume collect_layers isn't set anywhere else</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>is_narrowly_collecting<span class="Delimiter">(</span><span class="Constant">"warn"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> - <span class="Normal">delete</span> Trace_stream<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>is_narrowly_collecting<span class="Delimiter">(</span><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="Identifier">break</span><span class="Delimiter">;</span> diff --git a/html/082persist.cc.html b/html/082persist.cc.html index b5770552..04b4358d 100644 --- a/html/082persist.cc.html +++ b/html/082persist.cc.html @@ -13,14 +13,13 @@ 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; } -.Constant { color: #00a0a0; } .cSpecial { color: #008000; } +.CommentedCode { color: #6c6c6c; } .PreProc { color: #c000c0; } -.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } -.CommentedCode { color: #6c6c6c; } .Identifier { color: #804000; } +.Constant { color: #00a0a0; } --> </style> @@ -41,42 +40,42 @@ 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> -<span class="Normal">case</span> RESTORE: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case RESTORE: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'restore' requires exactly one ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> string filename<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal_string<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> + if <span class="Delimiter">(</span>is_literal_string<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> 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> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_string<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> + else if <span class="Delimiter">(</span>is_mu_string<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> filename = read_mu_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="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> + else <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'restore' should be a string, but got "</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> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Current_scenario<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Comment">// do nothing in tests</span> + if <span class="Delimiter">(</span>Current_scenario<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Comment">// do nothing in tests</span> string contents = slurp<span class="Delimiter">(</span><span class="Constant">"lesson/"</span>+filename<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="Normal">if</span> <span class="Delimiter">(</span>contents<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> + if <span class="Delimiter">(</span>contents<span class="Delimiter">.</span>empty<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> - <span class="Normal">else</span> + else 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_mu_string<span class="Delimiter">(</span>contents<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><span class="Normal">const</span> string& filename<span class="Delimiter">)</span> <span class="Delimiter">{</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> - <span class="Normal">if</span> <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> - <span class="Normal">const</span> <span class="Normal">int</span> N = <span class="Constant">1024</span><span class="Delimiter">;</span> - <span class="Normal">char</span> buf[N]<span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>!fin<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <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> @@ -91,24 +90,24 @@ 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> -<span class="Normal">case</span> SAVE: <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> +case SAVE: <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'save' requires exactly two ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Current_scenario<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Comment">// do nothing in tests</span> + if <span class="Delimiter">(</span>Current_scenario<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Comment">// do nothing in tests</span> string filename<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal_string<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> + if <span class="Delimiter">(</span>is_literal_string<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> 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> <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_string<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> + else if <span class="Delimiter">(</span>is_mu_string<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> filename = read_mu_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="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> + else <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'save' should be a string, but got "</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> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <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> <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> <span class="Delimiter">{</span> raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": second ingredient of 'save' should be an address:array:character, but got "</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> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -116,27 +115,21 @@ Recipe_ordinal[<span class="Constant">"save"</span>] = SAVE<span class string contents = read_mu_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> - <span class="Normal">if</span> <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> + 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> <span class="Comment">// explicitly say '--all' for git 1.9</span> - <span class="Normal">int</span> status = system<span class="Delimiter">(</span><span class="Constant">"cd lesson; git add --all .; git diff HEAD --exit-code >/dev/null || git commit -a -m . >/dev/null"</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>status != <span class="Constant">0</span><span class="Delimiter">)</span> + int status = system<span class="Delimiter">(</span><span class="Constant">"cd lesson; git add --all .; 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> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -<span class="Normal">bool</span> exists<span class="Delimiter">(</span><span class="Normal">const</span> string& filename<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">struct</span> stat dummy<span class="Delimiter">;</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> -string to_string<span class="Delimiter">(</span><span class="Normal">long</span> <span class="Normal">long</span> <span class="Normal">int</span> x<span class="Delimiter">)</span> <span class="Delimiter">{</span> - ostringstream tmp<span class="Delimiter">;</span> - tmp << x<span class="Delimiter">;</span> - <span class="Identifier">return</span> tmp<span class="Delimiter">.</span>str<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> diff --git a/html/999spaces.cc.html b/html/999spaces.cc.html index 9f5b995c..dbcc31d2 100644 --- a/html/999spaces.cc.html +++ b/html/999spaces.cc.html @@ -13,10 +13,10 @@ 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; } -.Delimiter { color: #a04060; } -.Constant { color: #00a0a0; } .Comment { color: #9090ff; } +.Delimiter { color: #a04060; } .SalientComment { color: #00ffff; } +.Constant { color: #00a0a0; } --> </style> diff --git a/html/callcc.mu.html b/html/callcc.mu.html index 5e817501..20ebd83c 100644 --- a/html/callcc.mu.html +++ b/html/callcc.mu.html @@ -13,11 +13,11 @@ 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; } -.muControl { color: #c0a020; } .muRecipe { color: #ff8700; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .Special { color: #ff6060; } +.muControl { color: #c0a020; } --> </style> diff --git a/html/channel.mu.html b/html/channel.mu.html index dbdaff6c..420eed5e 100644 --- a/html/channel.mu.html +++ b/html/channel.mu.html @@ -13,12 +13,12 @@ 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; } -.muControl { color: #c0a020; } .muRecipe { color: #ff8700; } -.Delimiter { color: #a04060; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .Special { color: #ff6060; } +.Delimiter { color: #a04060; } +.muControl { color: #c0a020; } --> </style> diff --git a/html/chessboard.mu.html b/html/chessboard.mu.html index 7d1ade89..0eb15641 100644 --- a/html/chessboard.mu.html +++ b/html/chessboard.mu.html @@ -13,15 +13,15 @@ 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; } -.muControl { color: #c0a020; } .muRecipe { color: #ff8700; } .SalientComment { color: #00ffff; } -.CommentedCode { color: #6c6c6c; } +.muScenario { color: #00af00; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .Special { color: #ff6060; } -.muScenario { color: #00af00; } +.CommentedCode { color: #6c6c6c; } .Delimiter { color: #a04060; } +.muControl { color: #c0a020; } --> </style> @@ -41,15 +41,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } open-console <span class="Comment"># take control of screen, keyboard and mouse</span> <span class="Comment"># The chessboard recipe takes keyboard and screen objects as 'ingredients'.</span> -<span class="Constant"> #</span> + <span class="Comment">#</span> <span class="Comment"># In mu it is good form (though not required) to explicitly show the</span> <span class="Comment"># hardware you rely on.</span> -<span class="Constant"> #</span> + <span class="Comment">#</span> <span class="Comment"># The chessboard also returns the same keyboard and screen objects. In mu it</span> <span class="Comment"># is good form to not modify ingredients of a recipe unless they are also</span> <span class="Comment"># results. Here we clearly modify both keyboard and screen, so we return</span> <span class="Comment"># both.</span> -<span class="Constant"> #</span> + <span class="Comment">#</span> <span class="Comment"># Here the console and screen are both 0, which usually indicates real</span> <span class="Comment"># hardware rather than a fake for testing as you'll see below.</span> <span class="Constant">0/screen</span>, <span class="Constant">0/console</span><span class="Special"> <- </span>chessboard <span class="Constant">0/screen</span>, <span class="Constant">0/console</span> @@ -443,7 +443,7 @@ container move [ <span class="Comment"># 'read-move' is waiting for input</span> wait-for-routine <span class="Constant">2</span>:number <span class="Constant">3</span>:number<span class="Special"> <- </span>routine-state <span class="Constant">2</span>:number/id - <span class="Constant">4</span>:boolean/waiting?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">2/waiting</span> + <span class="Constant">4</span>:boolean/waiting?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">3/waiting</span> assert <span class="Constant">4</span>: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> @@ -452,7 +452,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 <span class="Constant">2</span>:number <span class="Constant">3</span>:number<span class="Special"> <- </span>routine-state <span class="Constant">2</span>:number/id - <span class="Constant">4</span>:boolean/waiting?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">2/waiting</span> + <span class="Constant">4</span>:boolean/waiting?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">3/waiting</span> assert <span class="Constant">4</span>:boolean/waiting?, [ F read-move-blocking: routine failed to pause <span class="muRecipe">after</span> rank 'a'] <span class="Comment"># press '2'</span> @@ -461,7 +461,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 <span class="Constant">2</span>:number <span class="Constant">3</span>:number<span class="Special"> <- </span>routine-state <span class="Constant">2</span>:number/id - <span class="Constant">4</span>:boolean/waiting?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">2/waiting</span> + <span class="Constant">4</span>:boolean/waiting?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">3/waiting</span> assert <span class="Constant">4</span>:boolean/waiting?, [ F read-move-blocking: routine failed to pause <span class="muRecipe">after</span> file 'a2'] <span class="Comment"># press '-'</span> @@ -470,7 +470,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 <span class="Constant">2</span>:number <span class="Constant">3</span>:number<span class="Special"> <- </span>routine-state <span class="Constant">2</span>:number - <span class="Constant">4</span>:boolean/waiting?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">2/waiting</span> + <span class="Constant">4</span>:boolean/waiting?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">3/waiting</span> assert <span class="Constant">4</span>:boolean/waiting?/routine-state, [ F read-move-blocking: routine failed to pause <span class="muRecipe">after</span> hyphen 'a2-'] <span class="Comment"># press 'a'</span> @@ -479,7 +479,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 <span class="Constant">2</span>:number <span class="Constant">3</span>:number<span class="Special"> <- </span>routine-state <span class="Constant">2</span>:number - <span class="Constant">4</span>:boolean/waiting?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">2/waiting</span> + <span class="Constant">4</span>:boolean/waiting?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">3/waiting</span> assert <span class="Constant">4</span>:boolean/waiting?/routine-state, [ F read-move-blocking: routine failed to pause <span class="muRecipe">after</span> rank 'a2-a'] <span class="Comment"># press '4'</span> @@ -488,7 +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 <span class="Constant">2</span>:number <span class="Constant">3</span>:number<span class="Special"> <- </span>routine-state <span class="Constant">2</span>:number - <span class="Constant">4</span>:boolean/waiting?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">2/waiting</span> + <span class="Constant">4</span>:boolean/waiting?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">3/waiting</span> assert <span class="Constant">4</span>:boolean/waiting?, [ F read-move-blocking: routine failed to pause <span class="muRecipe">after</span> file 'a2-a4'] <span class="Comment"># press 'newline'</span> @@ -500,7 +500,7 @@ F read-move-blocking: routine failed to pause <span class="muRecipe">after</span <span class="Constant">4</span>:boolean/completed?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">1/completed</span> assert <span class="Constant">4</span>:boolean/completed?, [ F read-move-blocking: routine failed to terminate on newline] - trace <span class="Constant">[test]</span>, <span class="Constant">[reached end]</span> + trace <span class="Constant">1</span>, <span class="Constant">[test]</span>, <span class="Constant">[reached end]</span> ] trace-should-contain [ test: reached end @@ -515,7 +515,7 @@ F read-move-blocking: routine failed to terminate on newline] <span class="Comment"># 'read-move' is waiting for input</span> wait-for-routine <span class="Constant">2</span>:number <span class="Constant">3</span>:number<span class="Special"> <- </span>routine-state <span class="Constant">2</span>:number/id - <span class="Constant">4</span>:boolean/waiting?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">2/waiting</span> + <span class="Constant">4</span>:boolean/waiting?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">3/waiting</span> assert <span class="Constant">4</span>:boolean/waiting?, [ F read-move-quit: routine failed to pause <span class="muRecipe">after</span> coming up (<span class="muRecipe">before</span> any keys were pressed)] <span class="Comment"># press 'q'</span> @@ -527,7 +527,7 @@ F read-move-quit: routine failed to pause <span class="muRecipe">after</span> co <span class="Constant">4</span>:boolean/completed?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">1/completed</span> assert <span class="Constant">4</span>:boolean/completed?, [ F read-move-quit: routine failed to terminate on 'q'] - trace <span class="Constant">[test]</span>, <span class="Constant">[reached end]</span> + trace <span class="Constant">1</span>, <span class="Constant">[test]</span>, <span class="Constant">[reached end]</span> ] trace-should-contain [ test: reached end @@ -542,7 +542,7 @@ F read-move-quit: routine failed to terminate on 'q'] <span class="Comment"># 'read-move' is waiting for input</span> wait-for-routine <span class="Constant">2</span>:number <span class="Constant">3</span>:number<span class="Special"> <- </span>routine-state <span class="Constant">2</span>:number/id - <span class="Constant">4</span>:boolean/waiting?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">2/waiting</span> + <span class="Constant">4</span>:boolean/waiting?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">3/waiting</span> assert <span class="Constant">4</span>:boolean/waiting?, [ F read-move-file: routine failed to pause <span class="muRecipe">after</span> coming up (<span class="muRecipe">before</span> any keys were pressed)] <span class="Constant">1</span>:address:channel<span class="Special"> <- </span>write <span class="Constant">1</span>:address:channel, <span class="Constant">50/'2'</span> @@ -563,7 +563,7 @@ F read-move-file: routine failed to pause <span class="muRecipe">after</span> co <span class="Comment"># 'read-move' is waiting for input</span> wait-for-routine <span class="Constant">2</span>:number <span class="Constant">3</span>:number<span class="Special"> <- </span>routine-state <span class="Constant">2</span>:number/id - <span class="Constant">4</span>:boolean/waiting?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">2/waiting</span> + <span class="Constant">4</span>:boolean/waiting?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">3/waiting</span> assert <span class="Constant">4</span>:boolean/waiting?, [ F read-move-file: routine failed to pause <span class="muRecipe">after</span> coming up (<span class="muRecipe">before</span> any keys were pressed)] <span class="Constant">1</span>:address:channel<span class="Special"> <- </span>write <span class="Constant">1</span>:address:channel, <span class="Constant">97/a</span> @@ -585,7 +585,7 @@ F read-move-file: routine failed to pause <span class="muRecipe">after</span> co <span class="Comment"># 'read-move' is waiting for input</span> wait-for-routine <span class="Constant">2</span>:number <span class="Constant">3</span>:number<span class="Special"> <- </span>routine-state <span class="Constant">2</span>:number/id - <span class="Constant">4</span>:boolean/waiting?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">2/waiting</span> + <span class="Constant">4</span>:boolean/waiting?<span class="Special"> <- </span>equal <span class="Constant">3</span>:number/routine-state, <span class="Constant">3/waiting</span> assert <span class="Constant">4</span>:boolean/waiting?, [ F read-move-file: routine failed to pause <span class="muRecipe">after</span> coming up (<span class="muRecipe">before</span> any keys were pressed)] <span class="Constant">1</span>:address:channel<span class="Special"> <- </span>write <span class="Constant">1</span>:address:channel, <span class="Constant">10/newline</span> diff --git a/html/console.mu.html b/html/console.mu.html index e30185f7..7f46529b 100644 --- a/html/console.mu.html +++ b/html/console.mu.html @@ -13,12 +13,12 @@ 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; } -.muControl { color: #c0a020; } .muRecipe { color: #ff8700; } -.Constant { color: #00a0a0; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } +.Constant { color: #00a0a0; } +.muControl { color: #c0a020; } --> </style> diff --git a/html/counters.mu.html b/html/counters.mu.html index 122724c0..9a02adca 100644 --- a/html/counters.mu.html +++ b/html/counters.mu.html @@ -13,11 +13,11 @@ 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; } -.muControl { color: #c0a020; } .muRecipe { color: #ff8700; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .Special { color: #ff6060; } +.muControl { color: #c0a020; } --> </style> diff --git a/html/display.mu.html b/html/display.mu.html index 547e9b00..baf12e83 100644 --- a/html/display.mu.html +++ b/html/display.mu.html @@ -14,10 +14,10 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background- body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } .muRecipe { color: #ff8700; } -.CommentedCode { color: #6c6c6c; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .Special { color: #ff6060; } +.CommentedCode { color: #6c6c6c; } --> </style> diff --git a/html/edit.mu.html b/html/edit.mu.html index 98deff23..d50b41f2 100644 --- a/html/edit.mu.html +++ b/html/edit.mu.html @@ -13,15 +13,15 @@ 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; } -.muControl { color: #c0a020; } .muRecipe { color: #ff8700; } .SalientComment { color: #00ffff; } -.CommentedCode { color: #6c6c6c; } +.muScenario { color: #00af00; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .Special { color: #ff6060; } -.muScenario { color: #00af00; } +.CommentedCode { color: #6c6c6c; } .Delimiter { color: #a04060; } +.muControl { color: #c0a020; } --> </style> @@ -43,10 +43,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } open-console initial-recipe:address:array:character<span class="Special"> <- </span>restore <span class="Constant">[recipes.mu]</span> initial-sandbox:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span> + hide-screen <span class="Constant">0/screen</span> env:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment <span class="Constant">0/screen</span>, initial-recipe, initial-sandbox env<span class="Special"> <- </span>restore-sandboxes env render-all <span class="Constant">0/screen</span>, env - show-screen <span class="Constant">0/screen</span> event-loop <span class="Constant">0/screen</span>, <span class="Constant">0/console</span>, env <span class="Comment"># never gets here</span> ] @@ -83,7 +83,7 @@ container editor-data [ cursor-column:number ] -<span class="Comment"># editor:address, screen:address <- new-editor s:address:array:character, screen:address, left:number, right:number</span> +<span class="Comment"># editor:address, screen <- new-editor s:address:array:character, screen:address, left:number, right:number</span> <span class="Comment"># creates a new editor widget and renders its initial appearance to screen.</span> <span class="Comment"># top/left/right constrain the screen area available to the new editor.</span> <span class="Comment"># right is exclusive.</span> @@ -117,7 +117,8 @@ container editor-data [ y<span class="Special"> <- </span>get-address *result, <span class="Constant">before-cursor:offset</span> *y<span class="Special"> <- </span>copy *init <span class="Comment"># initial render to screen, just for some old tests</span> - _, screen<span class="Special"> <- </span>render screen, result + _, _, screen, result<span class="Special"> <- </span>render screen, result +<span class="Constant"> +editor-initialization</span> <span class="muControl">reply</span> result ] @@ -168,7 +169,7 @@ container editor-data [ ] ] -<span class="Comment"># bottom:number, screen:address <- render screen:address, editor:address:editor-data</span> +<span class="Comment"># last-row:number, last-column:number, screen, editor <- render screen:address, editor:address:editor-data</span> <span class="Comment">#</span> <span class="Comment"># Assumes cursor should be at coordinates (cursor-row, cursor-column) and</span> <span class="Comment"># updates before-cursor to match. Might also move coordinates if they're</span> @@ -177,14 +178,13 @@ container editor-data [ <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, <span class="Constant">1/top</span>, screen/same-as-ingredient:<span class="Constant">0</span> + <span class="muControl">reply-unless</span> editor, <span class="Constant">1/top</span>, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span> left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span> screen-height:number<span class="Special"> <- </span>screen-height screen right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span> - hide-screen screen <span class="Comment"># traversing editor</span> curr:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span> - prev:address:duplex-list<span class="Special"> <- </span>copy curr + prev:address:duplex-list<span class="Special"> <- </span>copy curr <span class="Comment"># just in case curr becomes null and we can't compute prev-duplex</span> curr<span class="Special"> <- </span>next-duplex curr <span class="Comment"># traversing screen</span> <span class="Constant"> +render-loop-initialization</span> @@ -194,7 +194,7 @@ container editor-data [ cursor-row:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-row:offset</span> cursor-column:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-column:offset</span> before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span> - move-cursor screen, row, column + screen<span class="Special"> <- </span>move-cursor screen, row, column <span class="Delimiter">{</span> <span class="Constant"> +next-character</span> <span class="muControl">break-unless</span> curr @@ -208,10 +208,10 @@ container editor-data [ <span class="muControl">break-unless</span> at-cursor-row? at-cursor?:boolean<span class="Special"> <- </span>equal column, *cursor-column <span class="muControl">break-unless</span> at-cursor? - *before-cursor<span class="Special"> <- </span>prev-duplex curr + *before-cursor<span class="Special"> <- </span>copy prev <span class="Delimiter">}</span> c:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span> -<span class="Constant"> +character-c-recived</span> +<span class="Constant"> +character-c-received</span> <span class="Delimiter">{</span> <span class="Comment"># newline? move to left rather than 0</span> newline?:boolean<span class="Special"> <- </span>equal c, <span class="Constant">10/newline</span> @@ -230,7 +230,7 @@ container editor-data [ <span class="Comment"># skip to next line</span> row<span class="Special"> <- </span>add row, <span class="Constant">1</span> column<span class="Special"> <- </span>copy left - move-cursor screen, row, column + screen<span class="Special"> <- </span>move-cursor screen, row, column curr<span class="Special"> <- </span>next-duplex curr prev<span class="Special"> <- </span>next-duplex prev <span class="muControl">loop</span> <span class="Constant">+next-character:label</span> @@ -244,7 +244,7 @@ container editor-data [ print-character screen, <span class="Constant">8617/loop-back-to-left</span>, <span class="Constant">245/grey</span> column<span class="Special"> <- </span>copy left row<span class="Special"> <- </span>add row, <span class="Constant">1</span> - move-cursor screen, row, column + screen<span class="Special"> <- </span>move-cursor screen, row, column <span class="Comment"># don't increment curr</span> <span class="muControl">loop</span> <span class="Constant">+next-character:label</span> <span class="Delimiter">}</span> @@ -267,24 +267,12 @@ container editor-data [ <span class="muControl">break-unless</span> before-cursor? *cursor-row<span class="Special"> <- </span>copy row *cursor-column<span class="Special"> <- </span>copy column - <span class="Comment"># line not wrapped but cursor outside bounds? wrap cursor</span> - <span class="Delimiter">{</span> - too-far-right?:boolean<span class="Special"> <- </span>greater-than *cursor-column, right - <span class="muControl">break-unless</span> too-far-right? - *cursor-column<span class="Special"> <- </span>copy left - *cursor-row<span class="Special"> <- </span>add *cursor-row, <span class="Constant">1</span> - above-screen-bottom?:boolean<span class="Special"> <- </span>lesser-than *cursor-row, screen-height - assert above-screen-bottom?, <span class="Constant">[unimplemented: wrapping cursor past bottom of screen]</span> - <span class="Delimiter">}</span> *before-cursor<span class="Special"> <- </span>copy prev <span class="Delimiter">}</span> - <span class="Comment"># clear rest of screen</span> - clear-line-delimited screen, column, right - clear-rest-of-screen screen, row, left, right - <span class="muControl">reply</span> row, screen/same-as-ingredient:<span class="Constant">0</span> + <span class="muControl">reply</span> row, column, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span> ] -<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"># row, screen <- 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"># clear rest of last line, but don't move cursor to next line</span> @@ -299,7 +287,7 @@ container editor-data [ row<span class="Special"> <- </span>add row, <span class="Constant">1</span> <span class="muControl">reply-unless</span> s, row/same-as-ingredient:<span class="Constant">5</span>, screen/same-as-ingredient:<span class="Constant">0</span> column:number<span class="Special"> <- </span>copy left - move-cursor screen, row, column + screen<span class="Special"> <- </span>move-cursor screen, row, column screen-height:number<span class="Special"> <- </span>screen-height screen i:number<span class="Special"> <- </span>copy <span class="Constant">0</span> len:number<span class="Special"> <- </span>length *s @@ -318,7 +306,7 @@ container editor-data [ print-character screen, <span class="Constant">8617/loop-back-to-left</span>, <span class="Constant">245/grey</span> column<span class="Special"> <- </span>copy left row<span class="Special"> <- </span>add row, <span class="Constant">1</span> - move-cursor screen, row, column + screen<span class="Special"> <- </span>move-cursor screen, row, column <span class="muControl">loop</span> <span class="Constant">+next-character:label</span> <span class="Comment"># retry i</span> <span class="Delimiter">}</span> i<span class="Special"> <- </span>add i, <span class="Constant">1</span> @@ -336,7 +324,7 @@ container editor-data [ <span class="Delimiter">}</span> row<span class="Special"> <- </span>add row, <span class="Constant">1</span> column<span class="Special"> <- </span>copy left - move-cursor screen, row, column + screen<span class="Special"> <- </span>move-cursor screen, row, column <span class="muControl">loop</span> <span class="Constant">+next-character:label</span> <span class="Delimiter">}</span> print-character screen, c, color @@ -357,9 +345,8 @@ container editor-data [ <span class="muRecipe">recipe</span> clear-line-delimited [ <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> + column:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> right:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - column:number<span class="Special"> <- </span>copy left <span class="Delimiter">{</span> done?:boolean<span class="Special"> <- </span>greater-than column, right <span class="muControl">break-if</span> done? @@ -369,6 +356,45 @@ container editor-data [ <span class="Delimiter">}</span> ] +<span class="muRecipe">recipe</span> clear-screen-from [ + <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> + column:number<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> + <span class="Comment"># if it's the real screen, use the optimized primitive</span> + <span class="Delimiter">{</span> + <span class="muControl">break-if</span> screen + clear-display-from row, column, left, right + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span> + <span class="Delimiter">}</span> + <span class="Comment"># if not, go the slower route</span> + screen<span class="Special"> <- </span>move-cursor screen, row, column + clear-line-delimited screen, column, right + clear-rest-of-screen screen, row, left, right + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span> +] + +<span class="muRecipe">recipe</span> clear-rest-of-screen [ + <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> + 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<span class="Special"> <- </span>add row, <span class="Constant">1</span> + screen<span class="Special"> <- </span>move-cursor screen, row, left + screen-height:number<span class="Special"> <- </span>screen-height screen + <span class="Delimiter">{</span> + at-bottom-of-screen?:boolean<span class="Special"> <- </span>greater-or-equal row, screen-height + <span class="muControl">break-if</span> at-bottom-of-screen? + screen<span class="Special"> <- </span>move-cursor screen, row, left + clear-line-delimited screen, left, right + row<span class="Special"> <- </span>add row, <span class="Constant">1</span> + <span class="muControl">loop</span> + <span class="Delimiter">}</span> +] + <span class="muScenario">scenario</span> editor-initially-prints-multiple-lines [ assume-screen <span class="Constant">5/width</span>, <span class="Constant">5/height</span> run [ @@ -506,11 +532,11 @@ container editor-data [ ] ] -<span class="muRecipe">after</span> +character-c-recived [ +<span class="muRecipe">after</span> +character-c-received [ color<span class="Special"> <- </span>get-color color, c ] -<span class="Comment"># color:number <- get-color color:number, c:character</span> +<span class="Comment"># color <- get-color color:number, c:character</span> <span class="Comment"># so far the previous color is all the information we need; that may change</span> <span class="muRecipe">recipe</span> get-color [ <span class="Constant">local-scope</span> @@ -596,59 +622,67 @@ container editor-data [ e:event, console:address, found?:boolean, quit?:boolean<span class="Special"> <- </span>read-event console <span class="muControl">loop-unless</span> found? <span class="muControl">break-if</span> quit? <span class="Comment"># only in tests</span> - trace <span class="Constant">[app]</span>, <span class="Constant">[next-event]</span> - <span class="Comment"># 'touch' event - send to both editors</span> + trace <span class="Constant">10</span>, <span class="Constant">[app]</span>, <span class="Constant">[next-event]</span> + <span class="Comment"># 'touch' event</span> t:address:touch-event<span class="Special"> <- </span>maybe-convert e, <span class="Constant">touch:variant</span> <span class="Delimiter">{</span> <span class="muControl">break-unless</span> t move-cursor-in-editor screen, editor, *t + <span class="muControl">loop</span> <span class="Constant">+next-event:label</span> <span class="Delimiter">}</span> <span class="Comment"># keyboard events</span> <span class="Delimiter">{</span> <span class="muControl">break-if</span> t - handle-keyboard-event screen, console, editor, e + screen, editor, go-render?:boolean<span class="Special"> <- </span>handle-keyboard-event screen, editor, e + <span class="Delimiter">{</span> + <span class="muControl">break-unless</span> go-render? + editor-render screen, editor + <span class="Delimiter">}</span> <span class="Delimiter">}</span> - <span class="Comment"># send any changes to screen</span> - row:number, screen<span class="Special"> <- </span>render screen, editor - <span class="Comment"># clear final line, in case we just processed a backspace</span> - left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span> - right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span> - row<span class="Special"> <- </span>add row, <span class="Constant">1</span> - move-cursor screen, row, left - clear-line-delimited screen, left, right <span class="muControl">loop</span> <span class="Delimiter">}</span> ] +<span class="Comment"># screen, editor, go-render?:boolean <- handle-keyboard-event screen:address, editor:address:editor-data, e:event</span> +<span class="Comment"># Process an event 'e' and try to minimally update the screen.</span> +<span class="Comment"># Set 'go-render?' to true to indicate the caller must perform a non-minimal update.</span> <span class="muRecipe">recipe</span> handle-keyboard-event [ <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 + <span class="muControl">reply-unless</span> editor, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span> + screen-width:number<span class="Special"> <- </span>screen-width screen + screen-height:number<span class="Special"> <- </span>screen-height screen + left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span> + right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span> + before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span> + cursor-row:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-row:offset</span> + cursor-column:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-column:offset</span> + save-row:number<span class="Special"> <- </span>copy *cursor-row + save-column:number<span class="Special"> <- </span>copy *cursor-column <span class="Comment"># character</span> <span class="Delimiter">{</span> c:address:character<span class="Special"> <- </span>maybe-convert e, <span class="Constant">text:variant</span> <span class="muControl">break-unless</span> c -<span class="CommentedCode">#? trace [app], [handle-keyboard-event: special character] #? 1</span> +<span class="CommentedCode">#? trace 10, [app], [handle-keyboard-event: special character] #? 1</span> <span class="Comment"># exceptions for special characters go here</span> <span class="Constant"> +handle-special-character</span> + <span class="Comment"># ignore any other special characters</span> + regular-character?:boolean<span class="Special"> <- </span>greater-or-equal *c, <span class="Constant">32/space</span> + newline?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">10/newline</span> + regular-character?<span class="Special"> <- </span>or regular-character?, newline? + <span class="muControl">reply-unless</span> regular-character?, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span> <span class="Comment"># otherwise type it in</span> - insert-at-cursor editor, *c, screen - <span class="muControl">reply</span> + editor, screen, go-render?:boolean<span class="Special"> <- </span>insert-at-cursor editor, *c, screen + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, go-render? <span class="Delimiter">}</span> <span class="Comment"># special key to modify the text or move the cursor</span> k:address:number<span class="Special"> <- </span>maybe-convert e:event, <span class="Constant">keycode:variant</span> assert k, <span class="Constant">[event was of unknown type; neither keyboard nor mouse]</span> - before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span> - cursor-row:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-row:offset</span> - cursor-column:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-column:offset</span> - screen-height:number<span class="Special"> <- </span>screen-height screen - left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span> - right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span> <span class="Comment"># handlers for each special key will go here</span> <span class="Constant"> +handle-special-key</span> + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span> ] <span class="Comment"># process click, return if it was on current editor</span> @@ -666,15 +700,108 @@ container editor-data [ right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span> too-far-right?:boolean<span class="Special"> <- </span>greater-than click-column, right <span class="muControl">reply-if</span> too-far-right?, <span class="Constant">0/false</span> - <span class="Comment"># update cursor</span> - cursor-row:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-row:offset</span> - *cursor-row<span class="Special"> <- </span>get t, <span class="Constant">row:offset</span> - cursor-column:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-column:offset</span> - *cursor-column<span class="Special"> <- </span>get t, <span class="Constant">column:offset</span> + <span class="Comment"># position cursor</span> +<span class="CommentedCode">#? trace 1, [print-character], [foo] #? 1</span> + click-row:number<span class="Special"> <- </span>get t, <span class="Constant">row:offset</span> + click-column:number<span class="Special"> <- </span>get t, <span class="Constant">column:offset</span> + editor<span class="Special"> <- </span>snap-cursor screen, editor, click-row, click-column +<span class="CommentedCode">#? trace 1, [print-character], [foo done] #? 1</span> <span class="Comment"># gain focus</span> <span class="muControl">reply</span> <span class="Constant">1/true</span> ] +<span class="Comment"># editor <- snap-cursor screen:address, editor:address:editor-data, target-row:number, target-column:number</span> +<span class="Comment">#</span> +<span class="Comment"># Variant of 'render' that only moves the cursor (coordinates and</span> +<span class="Comment"># before-cursor). If it's past the end of a line, it 'slides' it left. If it's</span> +<span class="Comment"># past the last line it positions at end of last line.</span> +<span class="muRecipe">recipe</span> snap-cursor [ + <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> + target-row:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + target-column:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="muControl">reply-unless</span> editor, <span class="Constant">1/top</span>, editor/same-as-ingredient:<span class="Constant">1</span> + left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span> + right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span> + screen-height:number<span class="Special"> <- </span>screen-height screen + <span class="Comment"># count newlines until screen row</span> + curr:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span> + prev:address:duplex-list<span class="Special"> <- </span>copy curr <span class="Comment"># just in case curr becomes null and we can't compute prev-duplex</span> + curr<span class="Special"> <- </span>next-duplex curr + row:number<span class="Special"> <- </span>copy <span class="Constant">1/top</span> + column:number<span class="Special"> <- </span>copy left + cursor-row:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-row:offset</span> + *cursor-row<span class="Special"> <- </span>copy target-row + cursor-column:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-column:offset</span> + *cursor-column<span class="Special"> <- </span>copy target-column + before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span> + <span class="Delimiter">{</span> +<span class="Constant"> +next-character</span> + <span class="muControl">break-unless</span> curr + off-screen?:boolean<span class="Special"> <- </span>greater-or-equal row, screen-height + <span class="muControl">break-if</span> off-screen? + <span class="Comment"># update editor-data.before-cursor</span> + <span class="Comment"># Doing so at the start of each iteration ensures it stays one step behind</span> + <span class="Comment"># the current character.</span> + <span class="Delimiter">{</span> + at-cursor-row?:boolean<span class="Special"> <- </span>equal row, *cursor-row + <span class="muControl">break-unless</span> at-cursor-row? + at-cursor?:boolean<span class="Special"> <- </span>equal column, *cursor-column + <span class="muControl">break-unless</span> at-cursor? + *before-cursor<span class="Special"> <- </span>copy prev + <span class="Delimiter">}</span> + c:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span> + <span class="Delimiter">{</span> + <span class="Comment"># newline? move to left rather than 0</span> + newline?:boolean<span class="Special"> <- </span>equal c, <span class="Constant">10/newline</span> + <span class="muControl">break-unless</span> newline? + <span class="Comment"># adjust cursor if necessary</span> + <span class="Delimiter">{</span> + at-cursor-row?:boolean<span class="Special"> <- </span>equal row, *cursor-row + <span class="muControl">break-unless</span> at-cursor-row? + left-of-cursor?:boolean<span class="Special"> <- </span>lesser-than column, *cursor-column + <span class="muControl">break-unless</span> left-of-cursor? + *cursor-column<span class="Special"> <- </span>copy column + *before-cursor<span class="Special"> <- </span>copy prev + <span class="Delimiter">}</span> + <span class="Comment"># skip to next line</span> + row<span class="Special"> <- </span>add row, <span class="Constant">1</span> + column<span class="Special"> <- </span>copy left + curr<span class="Special"> <- </span>next-duplex curr + prev<span class="Special"> <- </span>next-duplex prev + <span class="muControl">loop</span> <span class="Constant">+next-character:label</span> + <span class="Delimiter">}</span> + <span class="Delimiter">{</span> + <span class="Comment"># at right? wrap. even if there's only one more letter left; we need</span> + <span class="Comment"># room for clicking on the cursor after it.</span> + at-right?:boolean<span class="Special"> <- </span>equal column, right + <span class="muControl">break-unless</span> at-right? + column<span class="Special"> <- </span>copy left + row<span class="Special"> <- </span>add row, <span class="Constant">1</span> + <span class="Comment"># don't increment curr/prev</span> + <span class="muControl">loop</span> <span class="Constant">+next-character:label</span> + <span class="Delimiter">}</span> + curr<span class="Special"> <- </span>next-duplex curr + prev<span class="Special"> <- </span>next-duplex prev + column<span class="Special"> <- </span>add column, <span class="Constant">1</span> + <span class="muControl">loop</span> + <span class="Delimiter">}</span> + <span class="Comment"># is cursor to the right of the last line? move to end</span> + <span class="Delimiter">{</span> + at-cursor-row?:boolean<span class="Special"> <- </span>equal row, *cursor-row + cursor-outside-line?:boolean<span class="Special"> <- </span>lesser-or-equal column, *cursor-column + before-cursor-on-same-line?:boolean<span class="Special"> <- </span>and at-cursor-row?, cursor-outside-line? + above-cursor-row?:boolean<span class="Special"> <- </span>lesser-than row, *cursor-row + before-cursor?:boolean<span class="Special"> <- </span>or before-cursor-on-same-line?, above-cursor-row? + <span class="muControl">break-unless</span> before-cursor? + *cursor-row<span class="Special"> <- </span>copy row + *cursor-column<span class="Special"> <- </span>copy column + *before-cursor<span class="Special"> <- </span>copy prev + <span class="Delimiter">}</span> + <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">1</span> +] + <span class="muRecipe">recipe</span> insert-at-cursor [ <span class="Constant">local-scope</span> editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -687,16 +814,75 @@ container editor-data [ cursor-column:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-column:offset</span> left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span> right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span> + save-row:number<span class="Special"> <- </span>copy *cursor-row + save-column:number<span class="Special"> <- </span>copy *cursor-column + screen-width:number<span class="Special"> <- </span>screen-width screen + screen-height:number<span class="Special"> <- </span>screen-height screen <span class="Comment"># occasionally we'll need to mess with the cursor</span> <span class="Constant"> +insert-character-special-case</span> <span class="Comment"># but mostly we'll just move the cursor right</span> *cursor-column<span class="Special"> <- </span>add *cursor-column, <span class="Constant">1</span> + next:address:duplex-list<span class="Special"> <- </span>next-duplex *before-cursor + <span class="Delimiter">{</span> + <span class="Comment"># at end of all text? no need to scroll? just print the character and leave</span> + at-end?:boolean<span class="Special"> <- </span>equal next, <span class="Constant">0/null</span> + <span class="muControl">break-unless</span> at-end? + bottom:number<span class="Special"> <- </span>subtract screen-height, <span class="Constant">1</span> + at-bottom?:boolean<span class="Special"> <- </span>equal save-row, bottom + at-right?:boolean<span class="Special"> <- </span>equal save-column, right + overflow?:boolean<span class="Special"> <- </span>and at-bottom?, at-right? + <span class="muControl">break-if</span> overflow? + move-cursor screen, save-row, save-column + print-character screen, c + <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">2</span>, <span class="Constant">0/no-more-render</span> + <span class="Delimiter">}</span> + <span class="Delimiter">{</span> + <span class="Comment"># not at right margin? print the character and rest of line</span> + <span class="muControl">break-unless</span> next + at-right?:boolean<span class="Special"> <- </span>greater-or-equal *cursor-column, screen-width + <span class="muControl">break-if</span> at-right? + curr:address:duplex-list<span class="Special"> <- </span>copy *before-cursor + move-cursor screen, save-row, save-column + curr-column:number<span class="Special"> <- </span>copy save-column + <span class="Delimiter">{</span> + <span class="Comment"># hit right margin? give up and let caller render</span> + at-right?:boolean<span class="Special"> <- </span>greater-or-equal curr-column, screen-width + <span class="muControl">reply-if</span> at-right?, editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">2</span>, <span class="Constant">1/go-render</span> + <span class="muControl">break-unless</span> curr + <span class="Comment"># newline? done.</span> + currc:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span> + at-newline?:boolean<span class="Special"> <- </span>equal currc, <span class="Constant">10/newline</span> + <span class="muControl">break-if</span> at-newline? + print-character screen, currc + curr-column<span class="Special"> <- </span>add curr-column, <span class="Constant">1</span> + curr<span class="Special"> <- </span>next-duplex curr + <span class="muControl">loop</span> + <span class="Delimiter">}</span> + <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">2</span>, <span class="Constant">0/no-more-render</span> + <span class="Delimiter">}</span> + <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">2</span>, <span class="Constant">1/go-render</span> +] + +<span class="Comment"># helper for tests</span> +<span class="muRecipe">recipe</span> editor-render [ + <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> + left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span> + right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span> + row:number, column:number<span class="Special"> <- </span>render screen, editor + clear-line-delimited screen, column, right + row<span class="Special"> <- </span>add row, <span class="Constant">1</span> + draw-horizontal screen, row, left, right, <span class="Constant">9480/horizontal-dotted</span> + row<span class="Special"> <- </span>add row, <span class="Constant">1</span> + clear-screen-from screen, row, left, left, right ] <span class="muScenario">scenario</span> editor-handles-empty-event-queue [ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data assume-console <span class="Constant">[]</span> run [ editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data @@ -704,6 +890,7 @@ container editor-data [ screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> .abc .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] ] @@ -712,6 +899,8 @@ container editor-data [ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> assume-console [ left-click <span class="Constant">1</span>, <span class="Constant">1</span> <span class="Comment"># on the 'b'</span> ] @@ -723,18 +912,21 @@ container editor-data [ screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> .abc .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] memory-should-contain [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Comment"># cursor is at row 0..</span> <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Comment"># ..and column 1</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> ] <span class="muScenario">scenario</span> editor-handles-mouse-clicks-outside-text [ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> +<span class="Constant"> $clear-trace</span> assume-console [ left-click <span class="Constant">1</span>, <span class="Constant">7</span> <span class="Comment"># last line, to the right of text</span> ] @@ -747,6 +939,7 @@ container editor-data [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Comment"># cursor row</span> <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">3</span> <span class="Comment"># cursor column</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> ] <span class="muScenario">scenario</span> editor-handles-mouse-clicks-outside-text-2 [ @@ -754,6 +947,7 @@ container editor-data [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span> <span class="Constant">def]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> +<span class="Constant"> $clear-trace</span> assume-console [ left-click <span class="Constant">1</span>, <span class="Constant">7</span> <span class="Comment"># interior line, to the right of text</span> ] @@ -766,6 +960,7 @@ container editor-data [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Comment"># cursor row</span> <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">3</span> <span class="Comment"># cursor column</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> ] <span class="muScenario">scenario</span> editor-handles-mouse-clicks-outside-text-3 [ @@ -773,6 +968,7 @@ container editor-data [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span> <span class="Constant">def]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> +<span class="Constant"> $clear-trace</span> assume-console [ left-click <span class="Constant">3</span>, <span class="Constant">7</span> <span class="Comment"># below text</span> ] @@ -785,6 +981,7 @@ container editor-data [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">2</span> <span class="Comment"># cursor row</span> <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">3</span> <span class="Comment"># cursor column</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> ] <span class="muScenario">scenario</span> editor-handles-mouse-clicks-outside-column [ @@ -792,6 +989,8 @@ container editor-data [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> <span class="Comment"># editor occupies only left half of screen</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> assume-console [ <span class="Comment"># click on right half of screen</span> left-click <span class="Constant">3</span>, <span class="Constant">8</span> @@ -804,18 +1003,22 @@ container editor-data [ screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> .abc .</span> + <span class="Constant"> .┈┈┈┈┈ .</span> <span class="Constant"> . .</span> ] memory-should-contain [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Comment"># no change to cursor row</span> <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">0</span> <span class="Comment"># ..or column</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> ] <span class="muScenario">scenario</span> editor-inserts-characters-into-empty-editor [ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> assume-console [ type <span class="Constant">[abc]</span> ] @@ -825,14 +1028,19 @@ container editor-data [ screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> .abc .</span> + <span class="Constant"> .┈┈┈┈┈ .</span> <span class="Constant"> . .</span> ] + check-trace-count-for-label <span class="Constant">3</span>, <span class="Constant">[print-character]</span> ] <span class="muScenario">scenario</span> editor-inserts-characters-at-cursor [ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> + <span class="Comment"># type two letters at different places</span> assume-console [ type <span class="Constant">[0]</span> left-click <span class="Constant">1</span>, <span class="Constant">2</span> @@ -844,17 +1052,21 @@ container editor-data [ screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> .0adbc .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] + check-trace-count-for-label <span class="Constant">7</span>, <span class="Constant">[print-character]</span> <span class="Comment"># 4 for first letter, 3 for second</span> ] <span class="muScenario">scenario</span> editor-inserts-characters-at-cursor-2 [ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> assume-console [ left-click <span class="Constant">1</span>, <span class="Constant">5</span> <span class="Comment"># right of last line</span> - type <span class="Constant">[d]</span> <span class="Comment"># should append</span> + type <span class="Constant">[d]</span> ] run [ editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data @@ -862,17 +1074,45 @@ container editor-data [ screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> .abcd .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> + <span class="Constant"> . .</span> + ] + check-trace-count-for-label <span class="Constant">1</span>, <span class="Constant">[print-character]</span> +] + +<span class="muScenario">scenario</span> editor-inserts-characters-at-cursor-5 [ + assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span> +<span class="Constant">d]</span> + <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> + assume-console [ + left-click <span class="Constant">1</span>, <span class="Constant">5</span> <span class="Comment"># right of non-last line</span> + type <span class="Constant">[e]</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .abce .</span> + <span class="Constant"> .d .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] + check-trace-count-for-label <span class="Constant">1</span>, <span class="Constant">[print-character]</span> ] <span class="muScenario">scenario</span> editor-inserts-characters-at-cursor-3 [ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> assume-console [ left-click <span class="Constant">3</span>, <span class="Constant">5</span> <span class="Comment"># below all text</span> - type <span class="Constant">[d]</span> <span class="Comment"># should append</span> + type <span class="Constant">[d]</span> ] run [ editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data @@ -880,8 +1120,10 @@ container editor-data [ screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> .abcd .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] + check-trace-count-for-label <span class="Constant">1</span>, <span class="Constant">[print-character]</span> ] <span class="muScenario">scenario</span> editor-inserts-characters-at-cursor-4 [ @@ -889,9 +1131,11 @@ container editor-data [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span> <span class="Constant">d]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> assume-console [ left-click <span class="Constant">3</span>, <span class="Constant">5</span> <span class="Comment"># below all text</span> - type <span class="Constant">[e]</span> <span class="Comment"># should append</span> + type <span class="Constant">[e]</span> ] run [ editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data @@ -900,8 +1144,10 @@ container editor-data [ <span class="Constant"> . .</span> <span class="Constant"> .abc .</span> <span class="Constant"> .de .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] + check-trace-count-for-label <span class="Constant">1</span>, <span class="Constant">[print-character]</span> ] <span class="muScenario">scenario</span> editor-inserts-characters-at-cursor-5 [ @@ -909,9 +1155,11 @@ container editor-data [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span> <span class="Constant">d]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> assume-console [ left-click <span class="Constant">3</span>, <span class="Constant">5</span> <span class="Comment"># below all text</span> - type <span class="Constant">[ef]</span> <span class="Comment"># should append multiple characters in order</span> + type <span class="Constant">[ef]</span> ] run [ editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data @@ -920,14 +1168,17 @@ container editor-data [ <span class="Constant"> . .</span> <span class="Constant"> .abc .</span> <span class="Constant"> .def .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] + check-trace-count-for-label <span class="Constant">2</span>, <span class="Constant">[print-character]</span> ] <span class="muScenario">scenario</span> editor-moves-cursor-after-inserting-characters [ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ab]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data assume-console [ type <span class="Constant">[01]</span> ] @@ -937,6 +1188,7 @@ container editor-data [ screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> .01ab .</span> + <span class="Constant"> .┈┈┈┈┈ .</span> <span class="Constant"> . .</span> ] ] @@ -947,6 +1199,7 @@ container editor-data [ assume-screen <span class="Constant">5/width</span>, <span class="Constant">5/height</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data <span class="Comment"># type a letter</span> assume-console [ type <span class="Constant">[e]</span> @@ -958,6 +1211,7 @@ container editor-data [ screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> .eabc .</span> +<span class="Constant"> .┈┈┈┈┈.</span> <span class="Constant"> . .</span> <span class="Constant"> . .</span> ] @@ -973,6 +1227,7 @@ container editor-data [ <span class="Constant"> . .</span> <span class="Constant"> .efab↩.</span> <span class="Constant"> .c .</span> +<span class="Constant"> .┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] ] @@ -988,12 +1243,11 @@ container editor-data [ *cursor-row<span class="Special"> <- </span>add *cursor-row, <span class="Constant">1</span> <span class="Comment"># if we're out of the screen, scroll down</span> <span class="Delimiter">{</span> - screen-height:number<span class="Special"> <- </span>screen-height screen below-screen?:boolean<span class="Special"> <- </span>greater-or-equal *cursor-row, screen-height <span class="muControl">break-unless</span> below-screen? <span class="Constant"> +scroll-down</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> + <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">2</span>, <span class="Constant">1/go-render</span> <span class="Delimiter">}</span> ] @@ -1014,6 +1268,7 @@ container editor-data [ <span class="Constant"> . .</span> <span class="Constant"> .abcd↩ .</span> <span class="Constant"> .fe .</span> + <span class="Constant"> .┈┈┈┈┈ .</span> <span class="Constant"> . .</span> ] memory-should-contain [ @@ -1039,6 +1294,7 @@ container editor-data [ <span class="Constant"> . .</span> <span class="Constant"> .abcf↩ .</span> <span class="Constant"> .de .</span> + <span class="Constant"> .┈┈┈┈┈ .</span> <span class="Constant"> . .</span> ] memory-should-contain [ @@ -1047,7 +1303,16 @@ container editor-data [ ] ] -<span class="Comment"># if newline, move cursor to start of next line</span> +<span class="Comment"># if newline, move cursor to start of next line, and maybe align indent with previous line</span> + +container editor-data [ + indent:boolean +] + +<span class="muRecipe">after</span> +editor-initialization [ + indent:address:boolean<span class="Special"> <- </span>get-address *result, <span class="Constant">indent:offset</span> + *indent<span class="Special"> <- </span>copy <span class="Constant">1/true</span> +] <span class="muScenario">scenario</span> editor-moves-cursor-down-after-inserting-newline [ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> @@ -1064,6 +1329,7 @@ container editor-data [ <span class="Constant"> . .</span> <span class="Constant"> .0 .</span> <span class="Constant"> .1abc .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] ] @@ -1075,13 +1341,14 @@ container editor-data [ *cursor-row<span class="Special"> <- </span>add *cursor-row, <span class="Constant">1</span> *cursor-column<span class="Special"> <- </span>copy left <span class="Delimiter">{</span> - screen-height:number<span class="Special"> <- </span>screen-height screen below-screen?:boolean<span class="Special"> <- </span>greater-or-equal *cursor-row, screen-height <span class="Comment"># must be equal, never greater</span> <span class="muControl">break-unless</span> below-screen? <span class="Constant"> +scroll-down</span> *cursor-row<span class="Special"> <- </span>subtract *cursor-row, <span class="Constant">1</span> <span class="Comment"># bring back into screen range</span> <span class="Delimiter">}</span> <span class="Comment"># indent if necessary</span> + indent?:boolean<span class="Special"> <- </span>get *editor, <span class="Constant">indent:offset</span> + <span class="muControl">reply-unless</span> indent?, editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">2</span>, <span class="Constant">1/go-render</span> d:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">data:offset</span> end-of-previous-line:address:duplex-list<span class="Special"> <- </span>prev-duplex *before-cursor indent:number<span class="Special"> <- </span>line-indent end-of-previous-line, d @@ -1093,7 +1360,7 @@ container editor-data [ i<span class="Special"> <- </span>add i, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> + <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">2</span>, <span class="Constant">1/go-render</span> <span class="Delimiter">}</span> ] @@ -1146,6 +1413,7 @@ container editor-data [ <span class="Constant"> . .</span> <span class="Constant"> . 0 .</span> <span class="Constant"> . 1abc .</span> + <span class="Constant"> . ┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] ] @@ -1175,7 +1443,7 @@ container editor-data [ <span class="Constant"> . .</span> <span class="Constant"> .abcd↩ .</span> <span class="Constant"> .e .</span> - <span class="Constant"> . .</span> + <span class="Constant"> .┈┈┈┈┈ .</span> ] ] @@ -1203,6 +1471,52 @@ container editor-data [ ] ] +<span class="muScenario">scenario</span> editor-skips-indent-around-paste [ + assume-screen <span class="Constant">10/width</span>, <span class="Constant">10/height</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ab</span> +<span class="Constant"> cd</span> +<span class="Constant">ef]</span> + <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + <span class="Comment"># position cursor after 'cd' and hit 'newline' surrounded by paste markers</span> + assume-console [ + left-click <span class="Constant">2</span>, <span class="Constant">8</span> + press <span class="Constant">65507</span> <span class="Comment"># start paste</span> + type [ +] + press <span class="Constant">65506</span> <span class="Comment"># end paste</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + <span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span> + <span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span> + ] + <span class="Comment"># cursor should be below start of previous line</span> + memory-should-contain [ + <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">3</span> <span class="Comment"># cursor row</span> + <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">0</span> <span class="Comment"># cursor column (not indented)</span> + ] +] + +<span class="muRecipe">after</span> +handle-special-key [ + <span class="Delimiter">{</span> + paste-start?:boolean<span class="Special"> <- </span>equal *k, <span class="Constant">65507/paste-start</span> + <span class="muControl">break-unless</span> paste-start? + indent:address:boolean<span class="Special"> <- </span>get-address *editor, <span class="Constant">indent:offset</span> + *indent<span class="Special"> <- </span>copy <span class="Constant">0/false</span> + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span> + <span class="Delimiter">}</span> +] + +<span class="muRecipe">after</span> +handle-special-key [ + <span class="Delimiter">{</span> + paste-end?:boolean<span class="Special"> <- </span>equal *k, <span class="Constant">65506/paste-end</span> + <span class="muControl">break-unless</span> paste-end? + indent:address:boolean<span class="Special"> <- </span>get-address *editor, <span class="Constant">indent:offset</span> + *indent<span class="Special"> <- </span>copy <span class="Constant">1/true</span> + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span> + <span class="Delimiter">}</span> +] + <span class="SalientComment">## special shortcuts for manipulating the editor</span> <span class="Comment"># Some keys on the keyboard generate unicode characters, others generate</span> <span class="Comment"># terminfo key codes. We need to modify different places in the two cases.</span> @@ -1236,7 +1550,7 @@ container editor-data [ <span class="muControl">break-unless</span> tab? insert-at-cursor editor, <span class="Constant">32/space</span>, screen insert-at-cursor editor, <span class="Constant">32/space</span>, screen - <span class="muControl">reply</span> + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span> <span class="Delimiter">}</span> ] @@ -1246,6 +1560,8 @@ container editor-data [ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> assume-console [ left-click <span class="Constant">1</span>, <span class="Constant">1</span> type <span class="Constant">[«]</span> @@ -1260,34 +1576,67 @@ container editor-data [ screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> .bc .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] memory-should-contain [ <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Constant">5</span><span class="Special"> <- </span><span class="Constant">0</span> ] + check-trace-count-for-label <span class="Constant">3</span>, <span class="Constant">[print-character]</span> <span class="Comment"># length of original line to overwrite</span> ] <span class="muRecipe">after</span> +handle-special-character [ <span class="Delimiter">{</span> backspace?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">8/backspace</span> <span class="muControl">break-unless</span> backspace? - delete-before-cursor editor - <span class="muControl">reply</span> + editor, screen, go-render?:boolean<span class="Special"> <- </span>delete-before-cursor editor, screen + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, go-render? <span class="Delimiter">}</span> ] <span class="muRecipe">recipe</span> delete-before-cursor [ <span class="Constant">local-scope</span> editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span> <span class="Comment"># if at start of text (before-cursor at § sentinel), return</span> prev:address:duplex-list<span class="Special"> <- </span>prev-duplex *before-cursor - <span class="muControl">reply-unless</span> prev -<span class="CommentedCode">#? trace [app], [delete-before-cursor] #? 1</span> - editor<span class="Special"> <- </span>move-cursor-coordinates-left editor + <span class="muControl">reply-unless</span> prev, editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span> +<span class="CommentedCode">#? trace 10, [app], [delete-before-cursor] #? 1</span> + original-row:number<span class="Special"> <- </span>get *editor, <span class="Constant">cursor-row:offset</span> + editor, scroll?:boolean<span class="Special"> <- </span>move-cursor-coordinates-left editor remove-duplex *before-cursor *before-cursor<span class="Special"> <- </span>copy prev + <span class="muControl">reply-if</span> scroll?, editor/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">1/go-render</span> + screen-width:number<span class="Special"> <- </span>screen-width screen + cursor-row:number<span class="Special"> <- </span>get *editor, <span class="Constant">cursor-row:offset</span> + cursor-column:number<span class="Special"> <- </span>get *editor, <span class="Constant">cursor-column:offset</span> + <span class="Comment"># did we just backspace over a newline?</span> + same-row?:boolean<span class="Special"> <- </span>equal cursor-row, original-row + <span class="muControl">reply-unless</span> same-row?, editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span> + left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span> + right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span> + curr:address:duplex-list<span class="Special"> <- </span>next-duplex *before-cursor + screen<span class="Special"> <- </span>move-cursor screen, cursor-row, cursor-column + curr-column:number<span class="Special"> <- </span>copy cursor-column + <span class="Delimiter">{</span> + <span class="Comment"># hit right margin? give up and let caller render</span> + at-right?:boolean<span class="Special"> <- </span>greater-or-equal curr-column, screen-width + <span class="muControl">reply-if</span> at-right?, editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span> + <span class="muControl">break-unless</span> curr + <span class="Comment"># newline? done.</span> + currc:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span> + at-newline?:boolean<span class="Special"> <- </span>equal currc, <span class="Constant">10/newline</span> + <span class="muControl">break-if</span> at-newline? + screen<span class="Special"> <- </span>print-character screen, currc + curr-column<span class="Special"> <- </span>add curr-column, <span class="Constant">1</span> + curr<span class="Special"> <- </span>next-duplex curr + <span class="muControl">loop</span> + <span class="Delimiter">}</span> + <span class="Comment"># we're guaranteed not to be at the right margin</span> + screen<span class="Special"> <- </span>print-character screen, <span class="Constant">32/space</span> + <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span> ] <span class="muRecipe">recipe</span> move-cursor-coordinates-left [ @@ -1301,12 +1650,13 @@ container editor-data [ <span class="Delimiter">{</span> at-left-margin?:boolean<span class="Special"> <- </span>equal *cursor-column, left <span class="muControl">break-if</span> at-left-margin? -<span class="CommentedCode">#? trace [app], [decrementing cursor column] #? 1</span> +<span class="CommentedCode">#? trace 10, [app], [decrementing cursor column] #? 1</span> *cursor-column<span class="Special"> <- </span>subtract *cursor-column, <span class="Constant">1</span> - <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span> + <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">0/no-more-render</span> <span class="Delimiter">}</span> <span class="Comment"># if at left margin, we must move to previous row:</span> top-of-screen?:boolean<span class="Special"> <- </span>equal *cursor-row, <span class="Constant">1</span> <span class="Comment"># exclude menu bar</span> + go-render?:boolean<span class="Special"> <- </span>copy <span class="Constant">0/false</span> <span class="Delimiter">{</span> <span class="muControl">break-if</span> top-of-screen? *cursor-row<span class="Special"> <- </span>subtract *cursor-row, <span class="Constant">1</span> @@ -1314,6 +1664,7 @@ container editor-data [ <span class="Delimiter">{</span> <span class="muControl">break-unless</span> top-of-screen? <span class="Constant"> +scroll-up</span> + go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span> <span class="Delimiter">}</span> <span class="Delimiter">{</span> <span class="Comment"># case 1: if previous character was newline, figure out how long the previous line is</span> @@ -1321,17 +1672,17 @@ container editor-data [ previous-character-is-newline?:boolean<span class="Special"> <- </span>equal previous-character, <span class="Constant">10/newline</span> <span class="muControl">break-unless</span> previous-character-is-newline? <span class="Comment"># compute length of previous line</span> -<span class="CommentedCode">#? trace [app], [switching to previous line] #? 1</span> +<span class="CommentedCode">#? trace 10, [app], [switching to previous line] #? 1</span> d:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">data:offset</span> end-of-line:number<span class="Special"> <- </span>previous-line-length before-cursor, d *cursor-column<span class="Special"> <- </span>add left, end-of-line - <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span> + <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, go-render? <span class="Delimiter">}</span> <span class="Comment"># case 2: if previous-character was not newline, we're just at a wrapped line</span> -<span class="CommentedCode">#? trace [app], [wrapping to previous line] #? 1</span> +<span class="CommentedCode">#? trace 10, [app], [wrapping to previous line] #? 1</span> right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span> *cursor-column<span class="Special"> <- </span>subtract right, <span class="Constant">1</span> <span class="Comment"># leave room for wrap icon</span> - <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span> + <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, go-render? ] <span class="Comment"># takes a pointer 'curr' into the doubly-linked list and its sentinel, counts</span> @@ -1378,6 +1729,7 @@ container editor-data [ screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> .abcd .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] memory-should-contain [ @@ -1392,6 +1744,8 @@ container editor-data [ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> assume-console [ press <span class="Constant">65522</span> <span class="Comment"># delete</span> ] @@ -1401,8 +1755,11 @@ container editor-data [ screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> .bc .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] + check-trace-count-for-label <span class="Constant">3</span>, <span class="Constant">[print-character]</span> <span class="Comment"># length of original line to overwrite</span> +<span class="Constant"> $clear-trace</span> assume-console [ press <span class="Constant">65522</span> <span class="Comment"># delete</span> ] @@ -1412,17 +1769,43 @@ container editor-data [ screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> .c .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] + check-trace-count-for-label <span class="Constant">2</span>, <span class="Constant">[print-character]</span> <span class="Comment"># new length to overwrite</span> ] <span class="muRecipe">after</span> +handle-special-key [ <span class="Delimiter">{</span> delete?:boolean<span class="Special"> <- </span>equal *k, <span class="Constant">65522/delete</span> <span class="muControl">break-unless</span> delete? - curr:address:duplex-list<span class="Special"> <- </span>get **before-cursor, <span class="Constant">next:offset</span> - _<span class="Special"> <- </span>remove-duplex curr - <span class="muControl">reply</span> + curr:address:duplex-list<span class="Special"> <- </span>next-duplex *before-cursor + <span class="muControl">reply-unless</span> curr, editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span> + currc:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span> + remove-duplex curr + deleted-newline?:boolean<span class="Special"> <- </span>equal currc, <span class="Constant">10/newline</span> + <span class="muControl">reply-if</span> deleted-newline?, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span> + <span class="Comment"># wasn't a newline? render rest of line</span> + curr:address:duplex-list<span class="Special"> <- </span>next-duplex *before-cursor <span class="Comment"># refresh after remove-duplex above</span> + screen<span class="Special"> <- </span>move-cursor screen, *cursor-row, *cursor-column + curr-column:number<span class="Special"> <- </span>copy *cursor-column + <span class="Delimiter">{</span> + <span class="Comment"># hit right margin? give up and let caller render</span> + at-right?:boolean<span class="Special"> <- </span>greater-or-equal curr-column, screen-width + <span class="muControl">reply-if</span> at-right?, editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span> + <span class="muControl">break-unless</span> curr + <span class="Comment"># newline? done.</span> + currc:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span> + at-newline?:boolean<span class="Special"> <- </span>equal currc, <span class="Constant">10/newline</span> + <span class="muControl">break-if</span> at-newline? + screen<span class="Special"> <- </span>print-character screen, currc + curr-column<span class="Special"> <- </span>add curr-column, <span class="Constant">1</span> + curr<span class="Special"> <- </span>next-duplex curr + <span class="muControl">loop</span> + <span class="Delimiter">}</span> + <span class="Comment"># we're guaranteed not to be at the right margin</span> + screen<span class="Special"> <- </span>print-character screen, <span class="Constant">32/space</span> + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span> <span class="Delimiter">}</span> ] @@ -1432,6 +1815,8 @@ container editor-data [ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> assume-console [ press <span class="Constant">65514</span> <span class="Comment"># right arrow</span> type <span class="Constant">[0]</span> @@ -1442,8 +1827,10 @@ container editor-data [ screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> .a0bc .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] + check-trace-count-for-label <span class="Constant">3</span>, <span class="Constant">[print-character]</span> <span class="Comment"># 0 and following characters</span> ] <span class="muRecipe">after</span> +handle-special-key [ @@ -1463,10 +1850,11 @@ container editor-data [ *cursor-row<span class="Special"> <- </span>add *cursor-row, <span class="Constant">1</span> *cursor-column<span class="Special"> <- </span>copy left below-screen?:boolean<span class="Special"> <- </span>greater-or-equal *cursor-row, screen-height <span class="Comment"># must be equal</span> - <span class="muControl">reply-unless</span> below-screen? + screen<span class="Special"> <- </span>move-cursor screen, *cursor-row, *cursor-column + <span class="muControl">reply-unless</span> below-screen?, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span> <span class="Constant"> +scroll-down</span> *cursor-row<span class="Special"> <- </span>subtract *cursor-row, <span class="Constant">1</span> <span class="Comment"># bring back into screen range</span> - <span class="muControl">reply</span> + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span> <span class="Delimiter">}</span> <span class="Comment"># if the line wraps, move cursor to start of next row</span> <span class="Delimiter">{</span> @@ -1483,13 +1871,16 @@ container editor-data [ *cursor-row<span class="Special"> <- </span>add *cursor-row, <span class="Constant">1</span> *cursor-column<span class="Special"> <- </span>copy left below-screen?:boolean<span class="Special"> <- </span>greater-or-equal *cursor-row, screen-height <span class="Comment"># must be equal</span> - <span class="muControl">reply-unless</span> below-screen? + screen<span class="Special"> <- </span>move-cursor screen, *cursor-row, *cursor-column + <span class="muControl">reply-unless</span> below-screen?, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span> <span class="Constant"> +scroll-down</span> *cursor-row<span class="Special"> <- </span>subtract *cursor-row, <span class="Constant">1</span> <span class="Comment"># bring back into screen range</span> - <span class="muControl">reply</span> + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span> <span class="Delimiter">}</span> <span class="Comment"># otherwise move cursor one character right</span> *cursor-column<span class="Special"> <- </span>add *cursor-column, <span class="Constant">1</span> + screen<span class="Special"> <- </span>move-cursor screen, *cursor-row, *cursor-column + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span> <span class="Delimiter">}</span> ] @@ -1498,11 +1889,21 @@ container editor-data [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span> <span class="Constant">d]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> + <span class="Comment"># type right-arrow a few times to get to start of second line</span> assume-console [ press <span class="Constant">65514</span> <span class="Comment"># right arrow</span> press <span class="Constant">65514</span> <span class="Comment"># right arrow</span> press <span class="Constant">65514</span> <span class="Comment"># right arrow</span> press <span class="Constant">65514</span> <span class="Comment"># right arrow - next line</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> + <span class="Comment"># type something and ensure it goes where it should</span> + assume-console [ type <span class="Constant">[0]</span> ] run [ @@ -1512,8 +1913,10 @@ container editor-data [ <span class="Constant"> . .</span> <span class="Constant"> .abc .</span> <span class="Constant"> .0d .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] + check-trace-count-for-label <span class="Constant">2</span>, <span class="Constant">[print-character]</span> <span class="Comment"># new length of second line</span> ] <span class="muScenario">scenario</span> editor-moves-cursor-to-next-line-with-right-arrow-2 [ @@ -1521,6 +1924,7 @@ container editor-data [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span> <span class="Constant">d]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">1/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data assume-console [ press <span class="Constant">65514</span> <span class="Comment"># right arrow</span> press <span class="Constant">65514</span> <span class="Comment"># right arrow</span> @@ -1535,6 +1939,7 @@ container editor-data [ <span class="Constant"> . .</span> <span class="Constant"> . abc .</span> <span class="Constant"> . 0d .</span> + <span class="Constant"> . ┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] ] @@ -1543,6 +1948,8 @@ container editor-data [ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcdef]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> assume-console [ left-click <span class="Constant">1</span>, <span class="Constant">3</span> press <span class="Constant">65514</span> <span class="Comment"># right arrow</span> @@ -1556,12 +1963,14 @@ container editor-data [ <span class="Constant"> . .</span> <span class="Constant"> .abcd↩ .</span> <span class="Constant"> .ef .</span> + <span class="Constant"> .┈┈┈┈┈ .</span> <span class="Constant"> . .</span> ] memory-should-contain [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">2</span> <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">0</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> ] <span class="muScenario">scenario</span> editor-moves-cursor-to-next-wrapped-line-with-right-arrow-2 [ @@ -1569,6 +1978,8 @@ container editor-data [ <span class="Comment"># line just barely wrapping</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcde]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> <span class="Comment"># position cursor at last character before wrap and hit right-arrow</span> assume-console [ left-click <span class="Constant">1</span>, <span class="Constant">3</span> @@ -1596,12 +2007,15 @@ container editor-data [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">2</span> <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">1</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> ] <span class="muScenario">scenario</span> editor-moves-cursor-to-next-wrapped-line-with-right-arrow-3 [ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcdef]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">1/left</span>, <span class="Constant">6/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> assume-console [ left-click <span class="Constant">1</span>, <span class="Constant">4</span> press <span class="Constant">65514</span> <span class="Comment"># right arrow</span> @@ -1615,12 +2029,14 @@ container editor-data [ <span class="Constant"> . .</span> <span class="Constant"> . abcd↩ .</span> <span class="Constant"> . ef .</span> + <span class="Constant"> . ┈┈┈┈┈ .</span> <span class="Constant"> . .</span> ] memory-should-contain [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">2</span> <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">1</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> ] <span class="muScenario">scenario</span> editor-moves-cursor-to-next-line-with-right-arrow-at-end-of-line [ @@ -1628,6 +2044,8 @@ container editor-data [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span> <span class="Constant">d]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> assume-console [ left-click <span class="Constant">1</span>, <span class="Constant">3</span> press <span class="Constant">65514</span> <span class="Comment"># right arrow - next line</span> @@ -1640,8 +2058,10 @@ container editor-data [ <span class="Constant"> . .</span> <span class="Constant"> .abc .</span> <span class="Constant"> .0d .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] + check-trace-count-for-label <span class="Constant">2</span>, <span class="Constant">[print-character]</span> ] <span class="Comment"># left arrow</span> @@ -1650,6 +2070,8 @@ container editor-data [ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> assume-console [ left-click <span class="Constant">1</span>, <span class="Constant">2</span> press <span class="Constant">65515</span> <span class="Comment"># left arrow</span> @@ -1661,19 +2083,23 @@ container editor-data [ screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> .a0bc .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] + check-trace-count-for-label <span class="Constant">3</span>, <span class="Constant">[print-character]</span> ] <span class="muRecipe">after</span> +handle-special-key [ <span class="Delimiter">{</span> move-to-previous-character?:boolean<span class="Special"> <- </span>equal *k, <span class="Constant">65515/left-arrow</span> <span class="muControl">break-unless</span> move-to-previous-character? -<span class="CommentedCode">#? trace [app], [left arrow] #? 1</span> +<span class="CommentedCode">#? trace 10, [app], [left arrow] #? 1</span> <span class="Comment"># if not at start of text (before-cursor at § sentinel)</span> prev:address:duplex-list<span class="Special"> <- </span>prev-duplex *before-cursor - <span class="muControl">break-unless</span> prev - editor<span class="Special"> <- </span>move-cursor-coordinates-left editor + <span class="muControl">reply-unless</span> prev, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span> + editor, go-render?<span class="Special"> <- </span>move-cursor-coordinates-left editor + *before-cursor<span class="Special"> <- </span>copy prev + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, go-render? <span class="Delimiter">}</span> ] @@ -1683,6 +2109,8 @@ container editor-data [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span> <span class="Constant">d]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> <span class="Comment"># position cursor at start of second line (so there's no previous newline)</span> assume-console [ left-click <span class="Constant">2</span>, <span class="Constant">0</span> @@ -1697,6 +2125,7 @@ container editor-data [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">3</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> ] <span class="muScenario">scenario</span> editor-moves-cursor-to-previous-line-with-left-arrow-at-start-of-line-2 [ @@ -1706,6 +2135,8 @@ container editor-data [ <span class="Constant">def</span> <span class="Constant">g]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> <span class="Comment"># position cursor further down (so there's a newline before the character at</span> <span class="Comment"># the cursor)</span> assume-console [ @@ -1721,8 +2152,9 @@ container editor-data [ <span class="Constant"> .abc .</span> <span class="Constant"> .def0 .</span> <span class="Constant"> .g .</span> - <span class="Constant"> . .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> ] + check-trace-count-for-label <span class="Constant">1</span>, <span class="Constant">[print-character]</span> <span class="Comment"># just the '0'</span> ] <span class="muScenario">scenario</span> editor-moves-cursor-to-previous-line-with-left-arrow-at-start-of-line-3 [ @@ -1731,6 +2163,8 @@ container editor-data [ <span class="Constant">def</span> <span class="Constant">g]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> <span class="Comment"># position cursor at start of text</span> assume-console [ left-click <span class="Constant">1</span>, <span class="Constant">0</span> @@ -1745,8 +2179,9 @@ container editor-data [ <span class="Constant"> .0abc .</span> <span class="Constant"> .def .</span> <span class="Constant"> .g .</span> - <span class="Constant"> . .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> ] + check-trace-count-for-label <span class="Constant">4</span>, <span class="Constant">[print-character]</span> <span class="Comment"># length of first line</span> ] <span class="muScenario">scenario</span> editor-moves-cursor-to-previous-line-with-left-arrow-at-start-of-line-4 [ @@ -1756,6 +2191,8 @@ container editor-data [ d] <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> <span class="Comment"># position cursor right after empty line</span> assume-console [ left-click <span class="Constant">3</span>, <span class="Constant">0</span> @@ -1770,8 +2207,9 @@ d] <span class="Constant"> .abc .</span> <span class="Constant"> .0 .</span> <span class="Constant"> .d .</span> - <span class="Constant"> . .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> ] + check-trace-count-for-label <span class="Constant">1</span>, <span class="Constant">[print-character]</span> <span class="Comment"># just the '0'</span> ] <span class="muScenario">scenario</span> editor-moves-across-screen-lines-across-wrap-with-left-arrow [ @@ -1779,10 +2217,13 @@ d] <span class="Comment"># initialize editor with text containing an empty line</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcdef]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> .abcd↩ .</span> <span class="Constant"> .ef .</span> + <span class="Constant"> .┈┈┈┈┈ .</span> <span class="Constant"> . .</span> ] <span class="Comment"># position cursor right after empty line</span> @@ -1799,6 +2240,7 @@ d] <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Comment"># previous row</span> <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">3</span> <span class="Comment"># end of wrapped line</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> ] <span class="Comment"># up arrow</span> @@ -1808,6 +2250,8 @@ d] <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span> <span class="Constant">def]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> assume-console [ left-click <span class="Constant">2</span>, <span class="Constant">1</span> press <span class="Constant">65517</span> <span class="Comment"># up arrow</span> @@ -1821,6 +2265,20 @@ d] <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">1</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> + assume-console [ + type <span class="Constant">[0]</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .a0bc .</span> + <span class="Constant"> .def .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> + <span class="Constant"> . .</span> + ] ] <span class="muRecipe">after</span> +handle-special-key [ @@ -1832,24 +2290,53 @@ d] <span class="Comment"># if cursor not at top, move it</span> <span class="muControl">break-if</span> already-at-top? *cursor-row<span class="Special"> <- </span>subtract *cursor-row, <span class="Constant">1</span> + <span class="Comment"># scan back two newlines, then ahead to right column or until end of line</span> + prev:address:duplex-list<span class="Special"> <- </span>before-previous-line *before-cursor, editor + no-motion?:boolean<span class="Special"> <- </span>equal prev, *before-cursor + <span class="muControl">reply-if</span> no-motion?, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span> + tmp:address:duplex-list<span class="Special"> <- </span>copy prev + prev:address:duplex-list<span class="Special"> <- </span>before-previous-line tmp, editor + no-motion?:boolean<span class="Special"> <- </span>equal prev, *before-cursor + <span class="muControl">reply-if</span> no-motion?, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span> + *before-cursor<span class="Special"> <- </span>copy prev + target-column:number<span class="Special"> <- </span>copy *cursor-column + *cursor-column<span class="Special"> <- </span>copy left + <span class="Delimiter">{</span> + done?:boolean<span class="Special"> <- </span>greater-or-equal *cursor-column, target-column + <span class="muControl">break-if</span> done? + curr:address:duplex-list<span class="Special"> <- </span>next-duplex *before-cursor + <span class="muControl">break-unless</span> curr + currc:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span> + at-newline?:boolean<span class="Special"> <- </span>equal currc, <span class="Constant">10/newline</span> + not-at-start?:boolean<span class="Special"> <- </span>greater-than *cursor-column, left + line-done?:boolean<span class="Special"> <- </span>and at-newline?, not-at-start? + <span class="muControl">break-if</span> line-done? + <span class="Comment">#</span> + *before-cursor<span class="Special"> <- </span>copy curr + *cursor-column<span class="Special"> <- </span>add *cursor-column, <span class="Constant">1</span> + <span class="muControl">loop</span> + <span class="Delimiter">}</span> + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span> <span class="Delimiter">}</span> <span class="Delimiter">{</span> <span class="Comment"># if cursor already at top, scroll up</span> <span class="muControl">break-unless</span> already-at-top? <span class="Constant"> +scroll-up</span> + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span> <span class="Delimiter">}</span> - <span class="Comment"># that's it; render will adjust cursor-column as necessary</span> <span class="Delimiter">}</span> ] -<span class="muScenario">scenario</span> editor-adjusts-column-at-next-line [ +<span class="muScenario">scenario</span> editor-adjusts-column-at-previous-line [ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> - <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span> -<span class="Constant">de]</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ab</span> +<span class="Constant">def]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> assume-console [ - left-click <span class="Constant">1</span>, <span class="Constant">3</span> - press <span class="Constant">65516</span> <span class="Comment"># down arrow</span> + left-click <span class="Constant">2</span>, <span class="Constant">3</span> + press <span class="Constant">65517</span> <span class="Comment"># up arrow</span> ] run [ editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data @@ -1857,9 +2344,23 @@ d] <span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span> ] memory-should-contain [ - <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">2</span> + <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">2</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> + assume-console [ + type <span class="Constant">[0]</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .ab0 .</span> + <span class="Constant"> .def .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> + <span class="Constant"> . .</span> + ] ] <span class="Comment"># down arrow</span> @@ -1869,6 +2370,8 @@ d] <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span> <span class="Constant">def]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> <span class="Comment"># cursor starts out at (1, 0)</span> assume-console [ press <span class="Constant">65516</span> <span class="Comment"># down arrow</span> @@ -1883,6 +2386,20 @@ d] <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">2</span> <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">0</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> + assume-console [ + type <span class="Constant">[0]</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .abc .</span> + <span class="Constant"> .0def .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> + <span class="Constant"> . .</span> + ] ] <span class="muRecipe">after</span> +handle-special-key [ @@ -1895,24 +2412,50 @@ d] <span class="Comment"># if cursor not at top, move it</span> <span class="muControl">break-if</span> already-at-bottom? *cursor-row<span class="Special"> <- </span>add *cursor-row, <span class="Constant">1</span> + <span class="Comment"># scan to start of next line, then to right column or until end of line</span> + max:number<span class="Special"> <- </span>subtract right, left + next-line:address:duplex-list<span class="Special"> <- </span>before-start-of-next-line *before-cursor, max + no-motion?:boolean<span class="Special"> <- </span>equal next-line, *before-cursor + <span class="muControl">reply-if</span> no-motion?, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span> + *before-cursor<span class="Special"> <- </span>copy next-line + target-column:number<span class="Special"> <- </span>copy *cursor-column + *cursor-column<span class="Special"> <- </span>copy left + <span class="Delimiter">{</span> + done?:boolean<span class="Special"> <- </span>greater-or-equal *cursor-column, target-column + <span class="muControl">break-if</span> done? + curr:address:duplex-list<span class="Special"> <- </span>next-duplex *before-cursor + <span class="muControl">break-unless</span> curr + currc:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span> + at-newline?:boolean<span class="Special"> <- </span>equal currc, <span class="Constant">10/newline</span> + not-at-start?:boolean<span class="Special"> <- </span>greater-than *cursor-column, left + line-done?:boolean<span class="Special"> <- </span>and at-newline?, not-at-start? + <span class="muControl">break-if</span> line-done? + <span class="Comment">#</span> + *before-cursor<span class="Special"> <- </span>copy curr + *cursor-column<span class="Special"> <- </span>add *cursor-column, <span class="Constant">1</span> + <span class="muControl">loop</span> + <span class="Delimiter">}</span> + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span> <span class="Delimiter">}</span> <span class="Delimiter">{</span> <span class="Comment"># if cursor already at top, scroll up</span> <span class="muControl">break-unless</span> already-at-bottom? <span class="Constant"> +scroll-down</span> + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span> <span class="Delimiter">}</span> - <span class="Comment"># that's it; render will adjust cursor-column as necessary</span> <span class="Delimiter">}</span> ] -<span class="muScenario">scenario</span> editor-adjusts-column-at-previous-line [ +<span class="muScenario">scenario</span> editor-adjusts-column-at-next-line [ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> - <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ab</span> -<span class="Constant">def]</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span> +<span class="Constant">de]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> assume-console [ - left-click <span class="Constant">2</span>, <span class="Constant">3</span> - press <span class="Constant">65517</span> <span class="Comment"># up arrow</span> + left-click <span class="Constant">1</span>, <span class="Constant">3</span> + press <span class="Constant">65516</span> <span class="Comment"># down arrow</span> ] run [ editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data @@ -1920,9 +2463,23 @@ d] <span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span> ] memory-should-contain [ - <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span> + <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">2</span> <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">2</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> + assume-console [ + type <span class="Constant">[0]</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .abc .</span> + <span class="Constant"> .de0 .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> + <span class="Constant"> . .</span> + ] ] <span class="Comment"># ctrl-a/home - move cursor to start of line</span> @@ -1932,6 +2489,8 @@ d] <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> <span class="Constant">456]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> <span class="Comment"># start on second line, press ctrl-a</span> assume-console [ left-click <span class="Constant">2</span>, <span class="Constant">3</span> @@ -1949,6 +2508,7 @@ d] <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">2</span> <span class="Constant">5</span><span class="Special"> <- </span><span class="Constant">0</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> ] <span class="muRecipe">after</span> +handle-special-character [ @@ -1956,7 +2516,7 @@ d] ctrl-a?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">1/ctrl-a</span> <span class="muControl">break-unless</span> ctrl-a? move-to-start-of-line editor - <span class="muControl">reply</span> + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span> <span class="Delimiter">}</span> ] @@ -1965,7 +2525,7 @@ d] home?:boolean<span class="Special"> <- </span>equal *k, <span class="Constant">65521/home</span> <span class="muControl">break-unless</span> home? move-to-start-of-line editor - <span class="muControl">reply</span> + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span> <span class="Delimiter">}</span> ] @@ -1997,6 +2557,8 @@ d] <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> <span class="Constant">456]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> <span class="Comment"># start on first line (no newline before), press ctrl-a</span> assume-console [ left-click <span class="Constant">1</span>, <span class="Constant">3</span> @@ -2014,6 +2576,7 @@ d] <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Constant">5</span><span class="Special"> <- </span><span class="Constant">0</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> ] <span class="muScenario">scenario</span> editor-moves-to-start-of-line-with-home [ @@ -2021,6 +2584,7 @@ d] <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> <span class="Constant">456]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> +<span class="Constant"> $clear-trace</span> <span class="Comment"># start on second line, press 'home'</span> assume-console [ left-click <span class="Constant">2</span>, <span class="Constant">3</span> @@ -2036,6 +2600,7 @@ d] <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">2</span> <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">0</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> ] <span class="muScenario">scenario</span> editor-moves-to-start-of-line-with-home-2 [ @@ -2043,6 +2608,8 @@ d] <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> <span class="Constant">456]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> <span class="Comment"># start on first line (no newline before), press 'home'</span> assume-console [ left-click <span class="Constant">1</span>, <span class="Constant">3</span> @@ -2058,15 +2625,18 @@ d] <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">0</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> ] <span class="Comment"># ctrl-e/end - move cursor to end of line</span> -<span class="muScenario">scenario</span> editor-moves-to-start-of-line-with-ctrl-e [ +<span class="muScenario">scenario</span> editor-moves-to-end-of-line-with-ctrl-e [ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> <span class="Constant">456]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> <span class="Comment"># start on first line, press ctrl-e</span> assume-console [ left-click <span class="Constant">1</span>, <span class="Constant">1</span> @@ -2084,6 +2654,7 @@ d] <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Constant">5</span><span class="Special"> <- </span><span class="Constant">3</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> <span class="Comment"># editor inserts future characters at cursor</span> assume-console [ type <span class="Constant">[z]</span> @@ -2101,8 +2672,10 @@ d] <span class="Constant"> . .</span> <span class="Constant"> .123z .</span> <span class="Constant"> .456 .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] + check-trace-count-for-label <span class="Constant">1</span>, <span class="Constant">[print-character]</span> ] <span class="muRecipe">after</span> +handle-special-character [ @@ -2110,7 +2683,7 @@ d] ctrl-e?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">5/ctrl-e</span> <span class="muControl">break-unless</span> ctrl-e? move-to-end-of-line editor - <span class="muControl">reply</span> + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span> <span class="Delimiter">}</span> ] @@ -2119,7 +2692,7 @@ d] end?:boolean<span class="Special"> <- </span>equal *k, <span class="Constant">65520/end</span> <span class="muControl">break-unless</span> end? move-to-end-of-line editor - <span class="muControl">reply</span> + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span> <span class="Delimiter">}</span> ] @@ -2139,8 +2712,6 @@ d] *cursor-column<span class="Special"> <- </span>add *cursor-column, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> - <span class="Comment"># move one past final character</span> - *cursor-column<span class="Special"> <- </span>add *cursor-column, <span class="Constant">1</span> ] <span class="muScenario">scenario</span> editor-moves-to-end-of-line-with-ctrl-e-2 [ @@ -2148,6 +2719,8 @@ d] <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> <span class="Constant">456]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> <span class="Comment"># start on second line (no newline after), press ctrl-e</span> assume-console [ left-click <span class="Constant">2</span>, <span class="Constant">1</span> @@ -2165,6 +2738,7 @@ d] <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">2</span> <span class="Constant">5</span><span class="Special"> <- </span><span class="Constant">3</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> ] <span class="muScenario">scenario</span> editor-moves-to-end-of-line-with-end [ @@ -2172,6 +2746,8 @@ d] <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> <span class="Constant">456]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> <span class="Comment"># start on first line, press 'end'</span> assume-console [ left-click <span class="Constant">1</span>, <span class="Constant">1</span> @@ -2187,6 +2763,7 @@ d] <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">3</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> ] <span class="muScenario">scenario</span> editor-moves-to-end-of-line-with-end-2 [ @@ -2194,6 +2771,8 @@ d] <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span> <span class="Constant">456]</span> <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data +<span class="Constant"> $clear-trace</span> <span class="Comment"># start on second line (no newline after), press 'end'</span> assume-console [ left-click <span class="Constant">2</span>, <span class="Constant">1</span> @@ -2209,6 +2788,7 @@ d] <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">2</span> <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">3</span> ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> ] <span class="Comment"># ctrl-u - delete text from start of line until (but not at) cursor</span> @@ -2233,6 +2813,7 @@ d] <span class="Constant"> . .</span> <span class="Constant"> .123 .</span> <span class="Constant"> .6 .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] ] @@ -2242,7 +2823,7 @@ d] ctrl-u?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">21/ctrl-u</span> <span class="muControl">break-unless</span> ctrl-u? delete-to-start-of-line editor - <span class="muControl">reply</span> + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span> <span class="Delimiter">}</span> ] @@ -2299,6 +2880,7 @@ d] <span class="Constant"> . .</span> <span class="Constant"> .3 .</span> <span class="Constant"> .456 .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] ] @@ -2323,6 +2905,7 @@ d] <span class="Constant"> . .</span> <span class="Constant"> . .</span> <span class="Constant"> .456 .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] ] @@ -2347,6 +2930,7 @@ d] <span class="Constant"> . .</span> <span class="Constant"> .123 .</span> <span class="Constant"> . .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] ] @@ -2373,6 +2957,7 @@ d] <span class="Constant"> . .</span> <span class="Constant"> .1 .</span> <span class="Constant"> .456 .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] ] @@ -2382,7 +2967,7 @@ d] ctrl-k?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">11/ctrl-k</span> <span class="muControl">break-unless</span> ctrl-k? delete-to-end-of-line editor - <span class="muControl">reply</span> + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span> <span class="Delimiter">}</span> ] @@ -2431,6 +3016,7 @@ d] <span class="Constant"> . .</span> <span class="Constant"> .123 .</span> <span class="Constant"> .4 .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] ] @@ -2455,6 +3041,7 @@ d] <span class="Constant"> . .</span> <span class="Constant"> .12 .</span> <span class="Constant"> .456 .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] ] @@ -2479,6 +3066,7 @@ d] <span class="Constant"> . .</span> <span class="Constant"> .123 .</span> <span class="Constant"> .456 .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] ] @@ -2503,6 +3091,7 @@ d] <span class="Constant"> . .</span> <span class="Constant"> .123 .</span> <span class="Constant"> .45 .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] ] @@ -2527,324 +3116,11 @@ d] <span class="Constant"> . .</span> <span class="Constant"> .123 .</span> <span class="Constant"> .456 .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> <span class="Constant"> . .</span> ] ] -<span class="Comment"># ctrl-f/page-down - render next page if it exists</span> - -<span class="muScenario">scenario</span> editor-can-scroll [ - assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span> - <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span> -<span class="Constant">b</span> -<span class="Constant">c</span> -<span class="Constant">d]</span> - <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> - screen-should-contain [ - <span class="Constant"> . .</span> - <span class="Constant"> .a .</span> - <span class="Constant"> .b .</span> - <span class="Constant"> .c .</span> - ] - <span class="Comment"># scroll down</span> - assume-console [ - press <span class="Constant">65518</span> <span class="Comment"># page-down</span> - ] - run [ - editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data - ] - <span class="Comment"># screen shows next page</span> - screen-should-contain [ - <span class="Constant"> . .</span> - <span class="Constant"> .c .</span> - <span class="Constant"> .d .</span> - <span class="Constant"> . .</span> - ] -] - -<span class="muRecipe">after</span> +handle-special-character [ - <span class="Delimiter">{</span> - ctrl-f?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">6/ctrl-f</span> - <span class="muControl">break-unless</span> ctrl-f? - page-down editor - <span class="muControl">reply</span> - <span class="Delimiter">}</span> -] - -<span class="muRecipe">after</span> +handle-special-key [ - <span class="Delimiter">{</span> - page-down?:boolean<span class="Special"> <- </span>equal *k, <span class="Constant">65518/page-down</span> - <span class="muControl">break-unless</span> page-down? - page-down editor - <span class="muControl">reply</span> - <span class="Delimiter">}</span> -] - -<span class="Comment"># Cache old pointers to top-of-page in a list as you scroll past them, so that</span> -<span class="Comment"># page-up later doesn't have to recompute them.</span> -<span class="Comment"># This only works because we can never ever have edits outside the current</span> -<span class="Comment"># page. Any edits outside the current page might invalidate pointers to old</span> -<span class="Comment"># pages.</span> -container editor-data [ - previous-page:address:list:address:duplex-list:character -] - -<span class="Comment"># page-down skips entire wrapped lines, so it can't scroll past lines</span> -<span class="Comment"># taking up the entire screen</span> -<span class="muRecipe">recipe</span> page-down [ - <span class="Constant">local-scope</span> - editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - <span class="Comment"># if editor contents don't overflow screen, do nothing</span> - bottom-of-screen:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">bottom-of-screen:offset</span> - <span class="muControl">reply-unless</span> bottom-of-screen, editor/same-as-ingredient:<span class="Constant">0</span> - <span class="Comment"># if not, position cursor at final character</span> - before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span> - *before-cursor<span class="Special"> <- </span>prev-duplex bottom-of-screen - <span class="Comment"># keep one line in common with previous page</span> - <span class="Delimiter">{</span> - last:character<span class="Special"> <- </span>get **before-cursor, <span class="Constant">value:offset</span> - newline?:boolean<span class="Special"> <- </span>equal last, <span class="Constant">10/newline</span> - <span class="muControl">break-unless</span> newline?:boolean - *before-cursor<span class="Special"> <- </span>prev-duplex *before-cursor - <span class="Delimiter">}</span> - <span class="Comment"># save top-of-screen to previous-page list</span> - top-of-screen:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span> - previous-page:address:address:list:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">previous-page:offset</span> - *previous-page<span class="Special"> <- </span>push *top-of-screen, *previous-page - <span class="Comment"># move cursor and top-of-screen to start of that line</span> - move-to-start-of-line editor - *top-of-screen<span class="Special"> <- </span>copy *before-cursor - <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span> -] - -<span class="muScenario">scenario</span> editor-does-not-scroll-past-end [ - assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span> - <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span> -<span class="Constant">b]</span> - <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> - screen-should-contain [ - <span class="Constant"> . .</span> - <span class="Constant"> .a .</span> - <span class="Constant"> .b .</span> - <span class="Constant"> . .</span> - ] - <span class="Comment"># scroll down</span> - assume-console [ - press <span class="Constant">65518</span> <span class="Comment"># page-down</span> - ] - run [ - editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data - ] - <span class="Comment"># screen remains unmodified</span> - screen-should-contain [ - <span class="Constant"> . .</span> - <span class="Constant"> .a .</span> - <span class="Constant"> .b .</span> - <span class="Constant"> . .</span> - ] -] - -<span class="muScenario">scenario</span> editor-starts-next-page-at-start-of-wrapped-line [ - <span class="Comment"># screen has 1 line for menu + 3 lines for text</span> - assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span> - <span class="Comment"># editor contains a long last line</span> - <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span> -<span class="Constant">b</span> -<span class="Constant">cdefgh]</span> - <span class="Comment"># editor screen triggers wrap of last line</span> - <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">4/right</span> - <span class="Comment"># some part of last line is not displayed</span> - screen-should-contain [ - <span class="Constant"> . .</span> - <span class="Constant"> .a .</span> - <span class="Constant"> .b .</span> - <span class="Constant"> .cde↩ .</span> - ] - <span class="Comment"># scroll down</span> - assume-console [ - press <span class="Constant">65518</span> <span class="Comment"># page-down</span> - ] - run [ - editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data - ] - <span class="Comment"># screen shows entire wrapped line</span> - screen-should-contain [ - <span class="Constant"> . .</span> - <span class="Constant"> .cde↩ .</span> - <span class="Constant"> .fgh .</span> - <span class="Constant"> . .</span> - ] -] - -<span class="muScenario">scenario</span> editor-starts-next-page-at-start-of-wrapped-line-2 [ - <span class="Comment"># screen has 1 line for menu + 3 lines for text</span> - assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span> - <span class="Comment"># editor contains a very long line that occupies last two lines of screen</span> - <span class="Comment"># and still has something left over</span> - <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span> -<span class="Constant">bcdefgh]</span> - <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">4/right</span> - <span class="Comment"># some part of last line is not displayed</span> - screen-should-contain [ - <span class="Constant"> . .</span> - <span class="Constant"> .a .</span> - <span class="Constant"> .bcd↩ .</span> - <span class="Constant"> .efg↩ .</span> - ] - <span class="Comment"># scroll down</span> - assume-console [ - press <span class="Constant">65518</span> <span class="Comment"># page-down</span> - ] - run [ - editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data - ] - <span class="Comment"># screen shows entire wrapped line</span> - screen-should-contain [ - <span class="Constant"> . .</span> - <span class="Constant"> .bcd↩ .</span> - <span class="Constant"> .efg↩ .</span> - <span class="Constant"> .h .</span> - ] -] - -<span class="Comment"># ctrl-b/page-up - render previous page if it exists</span> - -<span class="muScenario">scenario</span> editor-can-scroll-up [ - assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span> - <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span> -<span class="Constant">b</span> -<span class="Constant">c</span> -<span class="Constant">d]</span> - <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> - screen-should-contain [ - <span class="Constant"> . .</span> - <span class="Constant"> .a .</span> - <span class="Constant"> .b .</span> - <span class="Constant"> .c .</span> - ] - <span class="Comment"># scroll down</span> - assume-console [ - press <span class="Constant">65518</span> <span class="Comment"># page-down</span> - ] - run [ - editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data - ] - <span class="Comment"># screen shows next page</span> - screen-should-contain [ - <span class="Constant"> . .</span> - <span class="Constant"> .c .</span> - <span class="Constant"> .d .</span> - <span class="Constant"> . .</span> - ] - <span class="Comment"># scroll back up</span> - assume-console [ - press <span class="Constant">65519</span> <span class="Comment"># page-up</span> - ] - run [ - editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data - ] - <span class="Comment"># screen shows original page again</span> - screen-should-contain [ - <span class="Constant"> . .</span> - <span class="Constant"> .a .</span> - <span class="Constant"> .b .</span> - <span class="Constant"> .c .</span> - ] -] - -<span class="muRecipe">after</span> +handle-special-character [ - <span class="Delimiter">{</span> - ctrl-b?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">2/ctrl-f</span> - <span class="muControl">break-unless</span> ctrl-b? - page-up editor - <span class="muControl">reply</span> - <span class="Delimiter">}</span> -] - -<span class="muRecipe">after</span> +handle-special-key [ - <span class="Delimiter">{</span> - page-up?:boolean<span class="Special"> <- </span>equal *k, <span class="Constant">65519/page-up</span> - <span class="muControl">break-unless</span> page-up? - page-up editor - <span class="muControl">reply</span> - <span class="Delimiter">}</span> -] - -<span class="muRecipe">recipe</span> page-up [ - <span class="Constant">local-scope</span> - editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - previous-page:address:address:list:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">previous-page:offset</span> - <span class="muControl">reply-unless</span> *previous-page, editor/same-as-ingredient:<span class="Constant">0</span> - top-of-screen:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span> - *top-of-screen<span class="Special"> <- </span>first *previous-page - *previous-page<span class="Special"> <- </span>rest *previous-page - <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span> -] - -<span class="muScenario">scenario</span> editor-can-scroll-up-multiple-pages [ - <span class="Comment"># screen has 1 line for menu + 3 lines</span> - assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span> - <span class="Comment"># initialize editor with 8 lines</span> - <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span> -<span class="Constant">b</span> -<span class="Constant">c</span> -<span class="Constant">d</span> -<span class="Constant">e</span> -<span class="Constant">f</span> -<span class="Constant">g</span> -<span class="Constant">h]</span> - <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> - screen-should-contain [ - <span class="Constant"> . .</span> - <span class="Constant"> .a .</span> - <span class="Constant"> .b .</span> - <span class="Constant"> .c .</span> - ] - <span class="Comment"># scroll down two pages</span> - assume-console [ - press <span class="Constant">65518</span> <span class="Comment"># page-down</span> - press <span class="Constant">65518</span> <span class="Comment"># page-down</span> - ] - run [ - editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data - ] - <span class="Comment"># screen shows third page</span> - screen-should-contain [ - <span class="Constant"> . .</span> - <span class="Constant"> .e .</span> - <span class="Constant"> .f .</span> - <span class="Constant"> .g .</span> - ] - <span class="Comment"># scroll up</span> - assume-console [ - press <span class="Constant">65519</span> <span class="Comment"># page-up</span> - ] - run [ - editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data - ] - <span class="Comment"># screen shows second page</span> - screen-should-contain [ - <span class="Constant"> . .</span> - <span class="Constant"> .c .</span> - <span class="Constant"> .d .</span> - <span class="Constant"> .e .</span> - ] - <span class="Comment"># scroll up again</span> - assume-console [ - press <span class="Constant">65519</span> <span class="Comment"># page-up</span> - ] - run [ - editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data - ] - <span class="Comment"># screen shows original page again</span> - screen-should-contain [ - <span class="Constant"> . .</span> - <span class="Constant"> .a .</span> - <span class="Constant"> .b .</span> - <span class="Constant"> .c .</span> - ] -] - <span class="Comment"># cursor-down can scroll if necessary</span> <span class="muScenario">scenario</span> editor-can-scroll-down-using-arrow-keys [ @@ -2880,22 +3156,31 @@ container editor-data [ ] <span class="muRecipe">after</span> +scroll-down [ -<span class="CommentedCode">#? $print [scroll down], 10/newline #? 1</span> +<span class="CommentedCode">#? $print [scroll down], 10/newline #? 2</span> top-of-screen:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span> left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span> right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span> max:number<span class="Special"> <- </span>subtract right, left - *top-of-screen<span class="Special"> <- </span>start-of-next-line *top-of-screen, max + *top-of-screen<span class="Special"> <- </span>before-start-of-next-line *top-of-screen, max ] <span class="Comment"># takes a pointer into the doubly-linked list, scans ahead at most 'max'</span> -<span class="Comment"># positions until just past the next newline</span> -<span class="muRecipe">recipe</span> start-of-next-line [ +<span class="Comment"># positions until the next newline</span> +<span class="Comment"># beware: never return null pointer.</span> +<span class="muRecipe">recipe</span> before-start-of-next-line [ <span class="Constant">local-scope</span> original:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span> max:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> count:number<span class="Special"> <- </span>copy <span class="Constant">0</span> curr:address:duplex-list<span class="Special"> <- </span>copy original + <span class="Comment"># skip the initial newline if it exists</span> + <span class="Delimiter">{</span> + c:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span> + at-newline?:boolean<span class="Special"> <- </span>equal c, <span class="Constant">10/newline</span> + <span class="muControl">break-unless</span> at-newline? + curr<span class="Special"> <- </span>next-duplex curr + count<span class="Special"> <- </span>add count, <span class="Constant">1</span> + <span class="Delimiter">}</span> <span class="Delimiter">{</span> <span class="muControl">reply-unless</span> curr, original done?:boolean<span class="Special"> <- </span>greater-or-equal count, max @@ -3108,6 +3393,36 @@ container editor-data [ ] ] +<span class="muScenario">scenario</span> editor-combines-page-and-line-scroll [ + <span class="Comment"># screen has 1 line for menu + 3 lines</span> + assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span> + <span class="Comment"># initialize editor with a few pages of lines</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span> +<span class="Constant">b</span> +<span class="Constant">c</span> +<span class="Constant">d</span> +<span class="Constant">e</span> +<span class="Constant">f</span> +<span class="Constant">g]</span> + <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span> + <span class="Comment"># scroll down one page and one line</span> + assume-console [ + press <span class="Constant">65518</span> <span class="Comment"># page-down</span> + left-click <span class="Constant">3</span>, <span class="Constant">0</span> + press <span class="Constant">65516</span> <span class="Comment"># down-arrow</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + <span class="Comment"># screen scrolls down 3 lines</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .d .</span> + <span class="Constant"> .e .</span> + <span class="Constant"> .f .</span> + ] +] + <span class="Comment"># cursor-up can scroll if necessary</span> <span class="muScenario">scenario</span> editor-can-scroll-up-using-arrow-keys [ @@ -3145,45 +3460,54 @@ container editor-data [ <span class="muRecipe">after</span> +scroll-up [ <span class="CommentedCode">#? $print [scroll up], 10/newline #? 1</span> top-of-screen:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span> - left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span> - right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span> - max:number<span class="Special"> <- </span>subtract right, left - *top-of-screen<span class="Special"> <- </span>start-of-previous-line *top-of-screen, max + *top-of-screen<span class="Special"> <- </span>before-previous-line *top-of-screen, editor ] -<span class="Comment"># takes a pointer into the doubly-linked list, scans back at most 'max'</span> -<span class="Comment"># positions to previous newline. Returns original pointer if falls off edge of</span> -<span class="Comment"># list.</span> -<span class="muRecipe">recipe</span> start-of-previous-line [ +<span class="Comment"># takes a pointer into the doubly-linked list, scans back to before start of</span> +<span class="Comment"># previous *wrapped* line</span> +<span class="Comment"># beware: never return null pointer</span> +<span class="muRecipe">recipe</span> before-previous-line [ <span class="Constant">local-scope</span> - original:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - max:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - count:number<span class="Special"> <- </span>copy <span class="Constant">0</span> - curr:address:duplex-list<span class="Special"> <- </span>copy original - <span class="muControl">reply-unless</span> curr, original - <span class="Comment"># if top is at start of line, don't count the previous newline</span> + curr:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + c:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span> +<span class="CommentedCode">#? $print [curr at ], c, 10/newline #? 1</span> + <span class="Comment"># compute max, number of characters to skip</span> + <span class="Comment"># 1 + len%(width-1)</span> + <span class="Comment"># except rotate second term to vary from 1 to width-1 rather than 0 to width-2</span> + editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span> + right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span> + max-line-length:number<span class="Special"> <- </span>subtract right, left, <span class="Constant">-1/exclusive-right</span>, <span class="Constant">1/wrap-icon</span> + sentinel:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">data:offset</span> + len:number<span class="Special"> <- </span>previous-line-length curr, sentinel +<span class="CommentedCode">#? $print [previous line: ], len, 10/newline #? 1</span> <span class="Delimiter">{</span> - c:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span> - at-newline?:boolean<span class="Special"> <- </span>equal c, <span class="Constant">10/newline</span> - <span class="muControl">break-unless</span> at-newline? - max<span class="Special"> <- </span>subtract max, <span class="Constant">1</span> + <span class="muControl">break-if</span> len + <span class="Comment"># empty line; just skip this newline</span> + prev:address:duplex-list<span class="Special"> <- </span>prev-duplex curr + <span class="muControl">reply-unless</span> prev, curr + <span class="muControl">reply</span> prev <span class="Delimiter">}</span> - <span class="Comment"># skip newline at original</span> - curr<span class="Special"> <- </span>prev-duplex curr - count<span class="Special"> <- </span>add count, <span class="Constant">1</span> - <span class="Comment"># now skip before until previous newline</span> + _, max:number<span class="Special"> <- </span>divide-with-remainder len, max-line-length + <span class="Comment"># remainder 0 => scan one width-worth</span> + <span class="Delimiter">{</span> + <span class="muControl">break-if</span> max +<span class="CommentedCode">#? $print [remainder 0; scan one width], 10/newline #? 1</span> + max<span class="Special"> <- </span>copy max-line-length + <span class="Delimiter">}</span> + max<span class="Special"> <- </span>add max, <span class="Constant">1</span> +<span class="CommentedCode">#? $print [skipping ], max, [ characters], 10/newline #? 1</span> + count:number<span class="Special"> <- </span>copy <span class="Constant">0</span> + <span class="Comment"># skip 'max' characters</span> <span class="Delimiter">{</span> - <span class="muControl">reply-unless</span> curr, original done?:boolean<span class="Special"> <- </span>greater-or-equal count, max <span class="muControl">break-if</span> done? - c:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span> - at-newline?:boolean<span class="Special"> <- </span>equal c, <span class="Constant">10/newline</span> - <span class="muControl">break-if</span> at-newline? - curr<span class="Special"> <- </span>prev-duplex curr + prev:address:duplex-list<span class="Special"> <- </span>prev-duplex curr + <span class="muControl">break-unless</span> prev + curr<span class="Special"> <- </span>copy prev count<span class="Special"> <- </span>add count, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> - <span class="muControl">reply-unless</span> curr, original <span class="muControl">reply</span> curr ] @@ -3253,7 +3577,7 @@ container editor-data [ <span class="Constant"> .k .</span> <span class="Constant"> .l .</span> <span class="Constant"> .m .</span> - <span class="Constant"> . .</span> + <span class="Constant"> .┈┈┈┈┈ .</span> ] <span class="Comment"># move up one line</span> assume-console [ @@ -3302,6 +3626,102 @@ container editor-data [ ] ] +<span class="Comment"># same as editor-scrolls-up-past-wrapped-line-using-arrow-keys but length</span> +<span class="Comment"># slightly off, just to prevent over-training</span> +<span class="muScenario">scenario</span> editor-scrolls-up-past-wrapped-line-using-arrow-keys-3 [ + <span class="Comment"># screen has 1 line for menu + 3 lines</span> + assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span> + <span class="Comment"># initialize editor with a long, wrapped line and more than a screen of</span> + <span class="Comment"># other lines</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcdef</span> +<span class="Constant">g</span> +<span class="Constant">h</span> +<span class="Constant">i]</span> + <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">6/right</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .abcde↩ .</span> + <span class="Constant"> .f .</span> + <span class="Constant"> .g .</span> + ] + <span class="Comment"># position cursor at top of second page, just below wrapped line</span> + assume-console [ + press <span class="Constant">65518</span> <span class="Comment"># page-down</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .g .</span> + <span class="Constant"> .h .</span> + <span class="Constant"> .i .</span> + ] + <span class="Comment"># now move up one line</span> + assume-console [ + press <span class="Constant">65517</span> <span class="Comment"># up-arrow</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + <span class="Comment"># screen shows partial wrapped line</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .f .</span> + <span class="Constant"> .g .</span> + <span class="Constant"> .h .</span> + ] +] + +<span class="Comment"># check empty lines</span> +<span class="muScenario">scenario</span> editor-scrolls-up-past-wrapped-line-using-arrow-keys-4 [ + assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span> + <span class="Comment"># initialize editor with some lines around an empty line</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span> +<span class="Constant">b</span> + +c +d +e] + <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">6/right</span> + assume-console [ + press <span class="Constant">65518</span> <span class="Comment"># page-down</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> . .</span> + <span class="Constant"> .c .</span> + <span class="Constant"> .d .</span> + ] + assume-console [ + press <span class="Constant">65518</span> <span class="Comment"># page-down</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .d .</span> + <span class="Constant"> .e .</span> + <span class="Constant"> .┈┈┈┈┈┈ .</span> + ] + assume-console [ + press <span class="Constant">65519</span> <span class="Comment"># page-up</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> . .</span> + <span class="Constant"> .c .</span> + <span class="Constant"> .d .</span> + ] +] + <span class="muScenario">scenario</span> editor-scrolls-up-on-left-arrow [ <span class="Comment"># screen has 1 line for menu + 3 lines</span> assume-screen <span class="Constant">5/width</span>, <span class="Constant">4/height</span> @@ -3347,6 +3767,588 @@ container editor-data [ ] ] +<span class="muScenario">scenario</span> editor-can-scroll-up-to-start-of-file [ + <span class="Comment"># screen has 1 line for menu + 3 lines</span> + assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span> + <span class="Comment"># initialize editor with >3 lines</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span> +<span class="Constant">b</span> +<span class="Constant">c</span> +<span class="Constant">d]</span> + <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .a .</span> + <span class="Constant"> .b .</span> + <span class="Constant"> .c .</span> + ] + <span class="Comment"># position cursor at top of second page, then try to move up to start of</span> + <span class="Comment"># text</span> + assume-console [ + press <span class="Constant">65518</span> <span class="Comment"># page-down</span> + press <span class="Constant">65517</span> <span class="Comment"># up-arrow</span> + press <span class="Constant">65517</span> <span class="Comment"># up-arrow</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + <span class="Comment"># screen slides by one line</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .a .</span> + <span class="Constant"> .b .</span> + <span class="Constant"> .c .</span> + ] + <span class="Comment"># try to move up again</span> + assume-console [ + press <span class="Constant">65517</span> <span class="Comment"># up-arrow</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + <span class="Comment"># screen remains unchanged</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .a .</span> + <span class="Constant"> .b .</span> + <span class="Constant"> .c .</span> + ] +] + +<span class="Comment"># ctrl-f/page-down - render next page if it exists</span> + +<span class="muScenario">scenario</span> editor-can-scroll [ + assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span> +<span class="Constant">b</span> +<span class="Constant">c</span> +<span class="Constant">d]</span> + <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .a .</span> + <span class="Constant"> .b .</span> + <span class="Constant"> .c .</span> + ] + <span class="Comment"># scroll down</span> + assume-console [ + press <span class="Constant">65518</span> <span class="Comment"># page-down</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + <span class="Comment"># screen shows next page</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .c .</span> + <span class="Constant"> .d .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> + ] +] + +<span class="muRecipe">after</span> +handle-special-character [ + <span class="Delimiter">{</span> + ctrl-f?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">6/ctrl-f</span> + <span class="muControl">break-unless</span> ctrl-f? + page-down editor + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span> + <span class="Delimiter">}</span> +] + +<span class="muRecipe">after</span> +handle-special-key [ + <span class="Delimiter">{</span> + page-down?:boolean<span class="Special"> <- </span>equal *k, <span class="Constant">65518/page-down</span> + <span class="muControl">break-unless</span> page-down? + page-down editor + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span> + <span class="Delimiter">}</span> +] + +<span class="Comment"># page-down skips entire wrapped lines, so it can't scroll past lines</span> +<span class="Comment"># taking up the entire screen</span> +<span class="muRecipe">recipe</span> page-down [ + <span class="Constant">local-scope</span> + editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Comment"># if editor contents don't overflow screen, do nothing</span> + bottom-of-screen:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">bottom-of-screen:offset</span> + <span class="muControl">reply-unless</span> bottom-of-screen, editor/same-as-ingredient:<span class="Constant">0</span> + <span class="Comment"># if not, position cursor at final character</span> + before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span> + *before-cursor<span class="Special"> <- </span>prev-duplex bottom-of-screen + <span class="Comment"># keep one line in common with previous page</span> + <span class="Delimiter">{</span> + last:character<span class="Special"> <- </span>get **before-cursor, <span class="Constant">value:offset</span> + newline?:boolean<span class="Special"> <- </span>equal last, <span class="Constant">10/newline</span> + <span class="muControl">break-unless</span> newline?:boolean + *before-cursor<span class="Special"> <- </span>prev-duplex *before-cursor + <span class="Delimiter">}</span> + <span class="Comment"># move cursor and top-of-screen to start of that line</span> + move-to-start-of-line editor + top-of-screen:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span> + *top-of-screen<span class="Special"> <- </span>copy *before-cursor + <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span> +] + +<span class="muScenario">scenario</span> editor-does-not-scroll-past-end [ + assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span> +<span class="Constant">b]</span> + <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + editor-render screen, <span class="Constant">2</span>:address:editor-data + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .a .</span> + <span class="Constant"> .b .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> + ] + <span class="Comment"># scroll down</span> + assume-console [ + press <span class="Constant">65518</span> <span class="Comment"># page-down</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + <span class="Comment"># screen remains unmodified</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .a .</span> + <span class="Constant"> .b .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> + ] +] + +<span class="muScenario">scenario</span> editor-starts-next-page-at-start-of-wrapped-line [ + <span class="Comment"># screen has 1 line for menu + 3 lines for text</span> + assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span> + <span class="Comment"># editor contains a long last line</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span> +<span class="Constant">b</span> +<span class="Constant">cdefgh]</span> + <span class="Comment"># editor screen triggers wrap of last line</span> + <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">4/right</span> + <span class="Comment"># some part of last line is not displayed</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .a .</span> + <span class="Constant"> .b .</span> + <span class="Constant"> .cde↩ .</span> + ] + <span class="Comment"># scroll down</span> + assume-console [ + press <span class="Constant">65518</span> <span class="Comment"># page-down</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + <span class="Comment"># screen shows entire wrapped line</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .cde↩ .</span> + <span class="Constant"> .fgh .</span> + <span class="Constant"> .┈┈┈┈ .</span> + ] +] + +<span class="muScenario">scenario</span> editor-starts-next-page-at-start-of-wrapped-line-2 [ + <span class="Comment"># screen has 1 line for menu + 3 lines for text</span> + assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span> + <span class="Comment"># editor contains a very long line that occupies last two lines of screen</span> + <span class="Comment"># and still has something left over</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span> +<span class="Constant">bcdefgh]</span> + <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">4/right</span> + <span class="Comment"># some part of last line is not displayed</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .a .</span> + <span class="Constant"> .bcd↩ .</span> + <span class="Constant"> .efg↩ .</span> + ] + <span class="Comment"># scroll down</span> + assume-console [ + press <span class="Constant">65518</span> <span class="Comment"># page-down</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + <span class="Comment"># screen shows entire wrapped line</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .bcd↩ .</span> + <span class="Constant"> .efg↩ .</span> + <span class="Constant"> .h .</span> + ] +] + +<span class="Comment"># ctrl-b/page-up - render previous page if it exists</span> + +<span class="muScenario">scenario</span> editor-can-scroll-up [ + assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span> +<span class="Constant">b</span> +<span class="Constant">c</span> +<span class="Constant">d]</span> + <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .a .</span> + <span class="Constant"> .b .</span> + <span class="Constant"> .c .</span> + ] + <span class="Comment"># scroll down</span> + assume-console [ + press <span class="Constant">65518</span> <span class="Comment"># page-down</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + <span class="Comment"># screen shows next page</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .c .</span> + <span class="Constant"> .d .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span> + ] + <span class="Comment"># scroll back up</span> + assume-console [ + press <span class="Constant">65519</span> <span class="Comment"># page-up</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + <span class="Comment"># screen shows original page again</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .a .</span> + <span class="Constant"> .b .</span> + <span class="Constant"> .c .</span> + ] +] + +<span class="muRecipe">after</span> +handle-special-character [ + <span class="Delimiter">{</span> + ctrl-b?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">2/ctrl-f</span> + <span class="muControl">break-unless</span> ctrl-b? + editor<span class="Special"> <- </span>page-up editor, screen-height + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span> + <span class="Delimiter">}</span> +] + +<span class="muRecipe">after</span> +handle-special-key [ + <span class="Delimiter">{</span> + page-up?:boolean<span class="Special"> <- </span>equal *k, <span class="Constant">65519/page-up</span> + <span class="muControl">break-unless</span> page-up? + editor<span class="Special"> <- </span>page-up editor, screen-height + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span> + <span class="Delimiter">}</span> +] + +<span class="muRecipe">recipe</span> page-up [ + <span class="Constant">local-scope</span> + editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + screen-height:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + max:number<span class="Special"> <- </span>subtract screen-height, <span class="Constant">1/menu-bar</span>, <span class="Constant">1/overlapping-line</span> + count:number<span class="Special"> <- </span>copy <span class="Constant">0</span> + top-of-screen:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span> + <span class="Delimiter">{</span> +<span class="CommentedCode">#? $print [- ], count, [ vs ], max, 10/newline #? 1</span> + done?:boolean<span class="Special"> <- </span>greater-or-equal count, max + <span class="muControl">break-if</span> done? + prev:address:duplex-list<span class="Special"> <- </span>before-previous-line *top-of-screen, editor + <span class="muControl">break-unless</span> prev + *top-of-screen<span class="Special"> <- </span>copy prev + count<span class="Special"> <- </span>add count, <span class="Constant">1</span> + <span class="muControl">loop</span> + <span class="Delimiter">}</span> + <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span> +] + +<span class="muScenario">scenario</span> editor-can-scroll-up-multiple-pages [ + <span class="Comment"># screen has 1 line for menu + 3 lines</span> + assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span> + <span class="Comment"># initialize editor with 8 lines</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span> +<span class="Constant">b</span> +<span class="Constant">c</span> +<span class="Constant">d</span> +<span class="Constant">e</span> +<span class="Constant">f</span> +<span class="Constant">g</span> +<span class="Constant">h]</span> + <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .a .</span> + <span class="Constant"> .b .</span> + <span class="Constant"> .c .</span> + ] + <span class="Comment"># scroll down two pages</span> + assume-console [ + press <span class="Constant">65518</span> <span class="Comment"># page-down</span> + press <span class="Constant">65518</span> <span class="Comment"># page-down</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + <span class="Comment"># screen shows third page</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .e .</span> + <span class="Constant"> .f .</span> + <span class="Constant"> .g .</span> + ] + <span class="Comment"># scroll up</span> + assume-console [ + press <span class="Constant">65519</span> <span class="Comment"># page-up</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + <span class="Comment"># screen shows second page</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .c .</span> + <span class="Constant"> .d .</span> + <span class="Constant"> .e .</span> + ] + <span class="Comment"># scroll up again</span> + assume-console [ + press <span class="Constant">65519</span> <span class="Comment"># page-up</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + <span class="Comment"># screen shows original page again</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .a .</span> + <span class="Constant"> .b .</span> + <span class="Constant"> .c .</span> + ] +] + +<span class="muScenario">scenario</span> editor-can-scroll-up-wrapped-lines [ + <span class="Comment"># screen has 1 line for menu + 5 lines for text</span> + assume-screen <span class="Constant">10/width</span>, <span class="Constant">6/height</span> + <span class="Comment"># editor contains a long line in the first page</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span> +<span class="Constant">b</span> +<span class="Constant">cdefgh</span> +<span class="Constant">i</span> +<span class="Constant">j</span> +<span class="Constant">k</span> +<span class="Constant">l</span> +<span class="Constant">m</span> +<span class="Constant">n</span> +<span class="Constant">o]</span> + <span class="Comment"># editor screen triggers wrap of last line</span> + <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">4/right</span> + <span class="Comment"># some part of last line is not displayed</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .a .</span> + <span class="Constant"> .b .</span> + <span class="Constant"> .cde↩ .</span> + <span class="Constant"> .fgh .</span> + <span class="Constant"> .i .</span> + ] + <span class="Comment"># scroll down a page and a line</span> + assume-console [ + press <span class="Constant">65518</span> <span class="Comment"># page-down</span> + left-click <span class="Constant">5</span>, <span class="Constant">0</span> + press <span class="Constant">65516</span> <span class="Comment"># down-arrow</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + <span class="Comment"># screen shows entire wrapped line</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .j .</span> + <span class="Constant"> .k .</span> + <span class="Constant"> .l .</span> + <span class="Constant"> .m .</span> + <span class="Constant"> .n .</span> + ] + <span class="Comment"># now scroll up one page</span> + assume-console [ + press <span class="Constant">65519</span> <span class="Comment"># page-up</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + <span class="Comment"># screen resets</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .b .</span> + <span class="Constant"> .cde↩ .</span> + <span class="Constant"> .fgh .</span> + <span class="Constant"> .i .</span> + <span class="Constant"> .j .</span> + ] +] + +<span class="muScenario">scenario</span> editor-can-scroll-up-wrapped-lines-2 [ + <span class="Comment"># screen has 1 line for menu + 3 lines for text</span> + assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span> + <span class="Comment"># editor contains a very long line that occupies last two lines of screen</span> + <span class="Comment"># and still has something left over</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span> +<span class="Constant">bcdefgh]</span> + <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">4/right</span> + <span class="Comment"># some part of last line is not displayed</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .a .</span> + <span class="Constant"> .bcd↩ .</span> + <span class="Constant"> .efg↩ .</span> + ] + <span class="Comment"># scroll down</span> + assume-console [ + press <span class="Constant">65518</span> <span class="Comment"># page-down</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + <span class="Comment"># screen shows entire wrapped line</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .bcd↩ .</span> + <span class="Constant"> .efg↩ .</span> + <span class="Constant"> .h .</span> + ] + <span class="Comment"># scroll back up</span> + assume-console [ + press <span class="Constant">65519</span> <span class="Comment"># page-up</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + <span class="Comment"># screen resets</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .a .</span> + <span class="Constant"> .bcd↩ .</span> + <span class="Constant"> .efg↩ .</span> + ] +] + +<span class="muScenario">scenario</span> editor-can-scroll-up-past-nonempty-lines [ + assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span> + <span class="Comment"># text with empty line in second screen</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[axx</span> +<span class="Constant">bxx</span> +<span class="Constant">cxx</span> +<span class="Constant">dxx</span> +<span class="Constant">exx</span> +<span class="Constant">fxx</span> +<span class="Constant">gxx</span> +<span class="Constant">hxx</span> +<span class="Constant">]</span> + <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">4/right</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .axx .</span> + <span class="Constant"> .bxx .</span> + <span class="Constant"> .cxx .</span> + ] + assume-console [ + press <span class="Constant">65518</span> <span class="Comment"># page-down</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .cxx .</span> + <span class="Constant"> .dxx .</span> + <span class="Constant"> .exx .</span> + ] + assume-console [ + press <span class="Constant">65518</span> <span class="Comment"># page-down</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .exx .</span> + <span class="Constant"> .fxx .</span> + <span class="Constant"> .gxx .</span> + ] + <span class="Comment"># scroll back up past empty line</span> + assume-console [ + press <span class="Constant">65519</span> <span class="Comment"># page-up</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .cxx .</span> + <span class="Constant"> .dxx .</span> + <span class="Constant"> .exx .</span> + ] +] + +<span class="muScenario">scenario</span> editor-can-scroll-up-past-empty-lines [ + assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span> + <span class="Comment"># text with empty line in second screen</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[axy</span> +<span class="Constant">bxy</span> +<span class="Constant">cxy</span> + +dxy +exy +fxy +gxy +] + <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">4/right</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .axy .</span> + <span class="Constant"> .bxy .</span> + <span class="Constant"> .cxy .</span> + ] + assume-console [ + press <span class="Constant">65518</span> <span class="Comment"># page-down</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .cxy .</span> + <span class="Constant"> . .</span> + <span class="Constant"> .dxy .</span> + ] + assume-console [ + press <span class="Constant">65518</span> <span class="Comment"># page-down</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .dxy .</span> + <span class="Constant"> .exy .</span> + <span class="Constant"> .fxy .</span> + ] + <span class="Comment"># scroll back up past empty line</span> + assume-console [ + press <span class="Constant">65519</span> <span class="Comment"># page-up</span> + ] + run [ + editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data + ] + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .cxy .</span> + <span class="Constant"> . .</span> + <span class="Constant"> .dxy .</span> + ] +] + <span class="SalientComment">## putting the environment together out of editors</span> container programming-environment-data [ @@ -3370,7 +4372,7 @@ container programming-environment-data [ button-start:number<span class="Special"> <- </span>subtract width, <span class="Constant">20</span> button-on-screen?:boolean<span class="Special"> <- </span>greater-or-equal button-start, <span class="Constant">0</span> assert button-on-screen?, <span class="Constant">[screen too narrow for menu]</span> - move-cursor screen, <span class="Constant">0/row</span>, button-start + screen<span class="Special"> <- </span>move-cursor screen, <span class="Constant">0/row</span>, button-start run-button:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ run (F4) ]</span> print-string screen, run-button, <span class="Constant">255/white</span>, <span class="Constant">161/reddish</span> <span class="Comment"># dotted line down the middle</span> @@ -3381,10 +4383,9 @@ container programming-environment-data [ *recipes<span class="Special"> <- </span>new-editor initial-recipe-contents, screen, <span class="Constant">0/left</span>, divider/right <span class="Comment"># sandbox editor on the right</span> new-left:number<span class="Special"> <- </span>add divider, <span class="Constant">1</span> - new-right:number<span class="Special"> <- </span>add new-left, <span class="Constant">5</span> current-sandbox:address:address:editor-data<span class="Special"> <- </span>get-address *result, <span class="Constant">current-sandbox:offset</span> *current-sandbox<span class="Special"> <- </span>new-editor initial-sandbox-contents, screen, new-left, width/right - screen<span class="Special"> <- </span>render-all screen, result +<span class="Constant"> +programming-environment-initialization</span> <span class="muControl">reply</span> result ] @@ -3402,7 +4403,8 @@ container programming-environment-data [ e:event, console, found?:boolean, quit?:boolean<span class="Special"> <- </span>read-event console <span class="muControl">loop-unless</span> found? <span class="muControl">break-if</span> quit? <span class="Comment"># only in tests</span> - trace <span class="Constant">[app]</span>, <span class="Constant">[next-event]</span> + trace <span class="Constant">10</span>, <span class="Constant">[app]</span>, <span class="Constant">[next-event]</span> +<span class="Constant"> +handle-event</span> <span class="Comment"># check for global events that will trigger regardless of which editor has focus</span> <span class="Delimiter">{</span> k:address:number<span class="Special"> <- </span>maybe-convert e:event, <span class="Constant">keycode:variant</span> @@ -3413,15 +4415,6 @@ container programming-environment-data [ c:address:character<span class="Special"> <- </span>maybe-convert e:event, <span class="Constant">text:variant</span> <span class="muControl">break-unless</span> c <span class="Constant"> +global-type</span> - <span class="Comment"># ctrl-n? - switch focus</span> - <span class="Delimiter">{</span> - ctrl-n?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">14/ctrl-n</span> - <span class="muControl">break-unless</span> ctrl-n? - *sandbox-in-focus?<span class="Special"> <- </span>not *sandbox-in-focus? - update-cursor screen, recipes, current-sandbox, *sandbox-in-focus? - show-screen screen - <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 sides, see what picks it up</span> <span class="Delimiter">{</span> @@ -3437,29 +4430,79 @@ container programming-environment-data [ <span class="Comment"># send to both editors</span> _<span class="Special"> <- </span>move-cursor-in-editor screen, recipes, *t *sandbox-in-focus?<span class="Special"> <- </span>move-cursor-in-editor screen, current-sandbox, *t - render-minimal screen, env + screen<span class="Special"> <- </span>update-cursor screen, recipes, current-sandbox, *sandbox-in-focus? + <span class="muControl">loop</span> <span class="Constant">+next-event:label</span> + <span class="Delimiter">}</span> + <span class="Comment"># 'resize' event - redraw editor</span> + <span class="Comment"># todo: test this after supporting resize in assume-console</span> + <span class="Delimiter">{</span> + r:address:resize-event<span class="Special"> <- </span>maybe-convert e:event, <span class="Constant">resize:variant</span> + <span class="muControl">break-unless</span> r + <span class="Comment"># if more events, we're still resizing; wait until we stop</span> + more-events?:boolean<span class="Special"> <- </span>has-more-events? console + <span class="muControl">break-if</span> more-events? + env<span class="Special"> <- </span>resize screen, env + screen<span class="Special"> <- </span>render-all screen, env <span class="muControl">loop</span> <span class="Constant">+next-event:label</span> <span class="Delimiter">}</span> <span class="Comment"># if it's not global and not a touch event, send to appropriate editor</span> <span class="Delimiter">{</span> + hide-screen screen <span class="Delimiter">{</span> <span class="muControl">break-if</span> *sandbox-in-focus? - handle-keyboard-event screen, console, recipes, e:event + screen, recipes, render?:boolean<span class="Special"> <- </span>handle-keyboard-event screen, recipes, e:event + <span class="Delimiter">{</span> + <span class="muControl">break-unless</span> render? + screen<span class="Special"> <- </span>render-recipes screen, env + <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">{</span> <span class="muControl">break-unless</span> *sandbox-in-focus? - handle-keyboard-event screen, console, current-sandbox, e:event + screen, current-sandbox, render?:boolean<span class="Special"> <- </span>handle-keyboard-event screen, current-sandbox, e:event + <span class="Delimiter">{</span> + <span class="muControl">break-unless</span> render?:boolean + screen<span class="Special"> <- </span>render-sandbox-side screen, env + <span class="Delimiter">}</span> <span class="Delimiter">}</span> - <span class="Comment"># optimization: refresh screen only if no more events</span> - <span class="Comment"># todo: test this</span> - more-events?:boolean<span class="Special"> <- </span>has-more-events? console - <span class="muControl">break-if</span> more-events? - render-minimal screen, env + screen<span class="Special"> <- </span>update-cursor screen, recipes, current-sandbox, *sandbox-in-focus? + show-screen screen <span class="Delimiter">}</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> ] +<span class="muRecipe">recipe</span> resize [ + <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> + <span class="Comment"># hack: clear screen to update screen dimensions</span> + clear-screen screen + width:number<span class="Special"> <- </span>screen-width screen + height:number<span class="Special"> <- </span>screen-height screen + <span class="Comment"># top menu</span> + draw-horizontal screen, <span class="Constant">0</span>, <span class="Constant">0/left</span>, width, <span class="Constant">32/space</span>, <span class="Constant">0/black</span>, <span class="Constant">238/grey</span> + button-start:number<span class="Special"> <- </span>subtract width, <span class="Constant">20</span> + button-on-screen?:boolean<span class="Special"> <- </span>greater-or-equal button-start, <span class="Constant">0</span> + assert button-on-screen?, <span class="Constant">[screen too narrow for menu]</span> + screen<span class="Special"> <- </span>move-cursor screen, <span class="Constant">0/row</span>, button-start + run-button:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ run (F4) ]</span> + print-string screen, run-button, <span class="Constant">255/white</span>, <span class="Constant">161/reddish</span> + <span class="Comment"># dotted line down the middle</span> + divider:number, _<span class="Special"> <- </span>divide-with-remainder width, <span class="Constant">2</span> + draw-vertical screen, divider, <span class="Constant">1/top</span>, height, <span class="Constant">9482/vertical-dotted</span> + <span class="Comment"># update recipe editor</span> + recipes:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">recipes:offset</span> + right:address:number<span class="Special"> <- </span>get-address *recipes, <span class="Constant">right:offset</span> + *right<span class="Special"> <- </span>subtract divider, <span class="Constant">1</span> + <span class="Comment"># update sandbox editor</span> + current-sandbox:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">current-sandbox:offset</span> + left:address:number<span class="Special"> <- </span>get-address *current-sandbox, <span class="Constant">left:offset</span> + right:address:number<span class="Special"> <- </span>get-address *current-sandbox, <span class="Constant">right:offset</span> + *left<span class="Special"> <- </span>add divider, <span class="Constant">1</span> + *right<span class="Special"> <- </span>subtract width, <span class="Constant">1</span> + <span class="muControl">reply</span> env/same-as-ingredient:<span class="Constant">1</span> +] + <span class="muScenario">scenario</span> point-at-multiple-editors [ <span class="Constant"> $close-trace</span> assume-screen <span class="Constant">30/width</span>, <span class="Constant">5/height</span> @@ -3493,6 +4536,7 @@ container programming-environment-data [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[def]</span> <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character + render-all screen, <span class="Constant">3</span>:address:programming-environment-data <span class="Comment"># type one letter in each of them</span> assume-console [ left-click <span class="Constant">1</span>, <span class="Constant">1</span> @@ -3519,7 +4563,7 @@ container programming-environment-data [ ] <span class="Comment"># show the cursor at the right window</span> run [ - screen:address<span class="Special"> <- </span>print-character screen:address, <span class="Constant">9251/␣</span> + print-character screen:address, <span class="Constant">9251/␣/cursor</span> ] screen-should-contain [ <span class="Constant"> . run (F4) .</span> @@ -3536,6 +4580,7 @@ container programming-environment-data [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[def]</span> <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character + render-all screen, <span class="Constant">3</span>:address:programming-environment-data ] <span class="Comment"># divider isn't messed up</span> screen-should-contain [ @@ -3552,12 +4597,13 @@ container programming-environment-data [ assume-screen <span class="Constant">30/width</span>, <span class="Constant">5/height</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[def]</span> + <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character + render-all screen, <span class="Constant">3</span>:address:programming-environment-data <span class="Comment"># initialize programming environment and highlight cursor</span> assume-console <span class="Constant">[]</span> run [ - <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data - screen:address<span class="Special"> <- </span>print-character screen:address, <span class="Constant">9251/␣</span> + print-character screen:address, <span class="Constant">9251/␣</span> ] <span class="Comment"># is cursor at the right place?</span> screen-should-contain [ @@ -3571,9 +4617,8 @@ container programming-environment-data [ type <span class="Constant">[z]</span> ] run [ - <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data - screen:address<span class="Special"> <- </span>print-character screen:address, <span class="Constant">9251/␣</span> + print-character screen:address, <span class="Constant">9251/␣</span> ] <span class="Comment"># cursor should still be right</span> screen-should-contain [ @@ -3591,17 +4636,25 @@ container programming-environment-data [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span> <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span> <span class="Constant">def]</span> + <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character + render-all screen, <span class="Constant">3</span>:address:programming-environment-data + screen-should-contain [ + <span class="Constant"> . run (F4) .</span> + <span class="Constant"> . ┊abc .</span> + <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊def .</span> + <span class="Constant"> . ┊━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ .</span> + ] <span class="Comment"># position cursor at start of second line and hit backspace</span> assume-console [ left-click <span class="Constant">2</span>, <span class="Constant">16</span> type <span class="Constant">[«]</span> ] - <span class="Constant">3</span>:event/backspace<span class="Special"> <- </span>merge <span class="Constant">0/text</span>, <span class="Constant">8/backspace</span>, <span class="Constant">0/dummy</span>, <span class="Constant">0/dummy</span> - replace-in-console <span class="Constant">171/«</span>, <span class="Constant">3</span>:event/backspace + <span class="Constant">4</span>:event/backspace<span class="Special"> <- </span>merge <span class="Constant">0/text</span>, <span class="Constant">8/backspace</span>, <span class="Constant">0/dummy</span>, <span class="Constant">0/dummy</span> + replace-in-console <span class="Constant">171/«</span>, <span class="Constant">4</span>:event/backspace run [ - <span class="Constant">4</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character - event-loop screen:address, console:address, <span class="Constant">4</span>:address:programming-environment-data - screen:address<span class="Special"> <- </span>print-character screen:address, <span class="Constant">9251/␣</span> + event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data + print-character screen:address, <span class="Constant">9251/␣</span> ] <span class="Comment"># cursor moves to end of old line</span> screen-should-contain [ @@ -3616,12 +4669,36 @@ container programming-environment-data [ <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> + hide-screen screen + <span class="Comment"># top menu</span> + width:number<span class="Special"> <- </span>screen-width screen + draw-horizontal screen, <span class="Constant">0</span>, <span class="Constant">0/left</span>, width, <span class="Constant">32/space</span>, <span class="Constant">0/black</span>, <span class="Constant">238/grey</span> + button-start:number<span class="Special"> <- </span>subtract width, <span class="Constant">20</span> + button-on-screen?:boolean<span class="Special"> <- </span>greater-or-equal button-start, <span class="Constant">0</span> + assert button-on-screen?, <span class="Constant">[screen too narrow for menu]</span> + screen<span class="Special"> <- </span>move-cursor screen, <span class="Constant">0/row</span>, button-start + run-button:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ run (F4) ]</span> + print-string screen, run-button, <span class="Constant">255/white</span>, <span class="Constant">161/reddish</span> + <span class="Comment"># error message</span> + recipe-warnings:address:array:character<span class="Special"> <- </span>get *env, <span class="Constant">recipe-warnings:offset</span> + <span class="Delimiter">{</span> + <span class="muControl">break-unless</span> recipe-warnings + status:address:array:character<span class="Special"> <- </span>new <span class="Constant">[errors found]</span> + update-status screen, status, <span class="Constant">1/red</span> + <span class="Delimiter">}</span> + <span class="Comment"># dotted line down the middle</span> + divider:number, _<span class="Special"> <- </span>divide-with-remainder width, <span class="Constant">2</span> + height:number<span class="Special"> <- </span>screen-height screen + draw-vertical screen, divider, <span class="Constant">1/top</span>, height, <span class="Constant">9482/vertical-dotted</span> + <span class="Comment">#</span> screen<span class="Special"> <- </span>render-recipes screen, env screen<span class="Special"> <- </span>render-sandbox-side screen, env + <span class="Comment">#</span> recipes:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">recipes:offset</span> current-sandbox:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">current-sandbox:offset</span> sandbox-in-focus?:boolean<span class="Special"> <- </span>get *env, <span class="Constant">sandbox-in-focus?:offset</span> - update-cursor screen, recipes, current-sandbox, sandbox-in-focus? + screen<span class="Special"> <- </span>update-cursor screen, recipes, current-sandbox, sandbox-in-focus? + <span class="Comment">#</span> show-screen screen <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span> ] @@ -3630,6 +4707,7 @@ container programming-environment-data [ <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> + hide-screen screen recipes:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">recipes:offset</span> current-sandbox:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">current-sandbox:offset</span> sandbox-in-focus?:boolean<span class="Special"> <- </span>get *env, <span class="Constant">sandbox-in-focus?:offset</span> @@ -3645,7 +4723,7 @@ container programming-environment-data [ cursor-row:number<span class="Special"> <- </span>get *current-sandbox, <span class="Constant">cursor-row:offset</span> cursor-column:number<span class="Special"> <- </span>get *current-sandbox, <span class="Constant">cursor-column:offset</span> <span class="Delimiter">}</span> - move-cursor screen, cursor-row, cursor-column + screen<span class="Special"> <- </span>move-cursor screen, cursor-row, cursor-column show-screen screen <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span> ] @@ -3658,7 +4736,8 @@ container programming-environment-data [ <span class="Comment"># render recipes</span> left:number<span class="Special"> <- </span>get *recipes, <span class="Constant">left:offset</span> right:number<span class="Special"> <- </span>get *recipes, <span class="Constant">right:offset</span> - row:number, screen<span class="Special"> <- </span>render screen, recipes + row:number, column:number, screen<span class="Special"> <- </span>render screen, recipes + clear-line-delimited screen, column, right recipe-warnings:address:array:character<span class="Special"> <- </span>get *env, <span class="Constant">recipe-warnings:offset</span> <span class="Delimiter">{</span> <span class="Comment"># print any warnings</span> @@ -3672,31 +4751,11 @@ container programming-environment-data [ <span class="Delimiter">}</span> <span class="Comment"># draw dotted line after recipes</span> draw-horizontal screen, row, left, right, <span class="Constant">9480/horizontal-dotted</span> - clear-rest-of-screen screen, row, left, right - <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span> -] - -<span class="muRecipe">recipe</span> clear-rest-of-screen [ - <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> - 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<span class="Special"> <- </span>add row, <span class="Constant">1</span> - move-cursor screen, row, left - screen-height:number<span class="Special"> <- </span>screen-height screen - <span class="Delimiter">{</span> - at-bottom-of-screen?:boolean<span class="Special"> <- </span>greater-or-equal row, screen-height - <span class="muControl">break-if</span> at-bottom-of-screen? - move-cursor screen, row, left - clear-line-delimited screen, left, right - row<span class="Special"> <- </span>add row, <span class="Constant">1</span> - <span class="muControl">loop</span> - <span class="Delimiter">}</span> + clear-screen-from screen, row, left, left, right + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span> ] -<span class="Comment"># helper for testing a single editor</span> - <span class="muRecipe">recipe</span> update-cursor [ <span class="Constant">local-scope</span> screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -3717,7 +4776,151 @@ container programming-environment-data [ cursor-row:number<span class="Special"> <- </span>get *current-sandbox, <span class="Constant">cursor-row:offset</span> cursor-column:number<span class="Special"> <- </span>get *current-sandbox, <span class="Constant">cursor-column:offset</span> <span class="Delimiter">}</span> - move-cursor screen, cursor-row, cursor-column + screen<span class="Special"> <- </span>move-cursor screen, cursor-row, cursor-column + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span> +] + +<span class="Comment"># ctrl-l - redraw screen (just in case it printed junk somehow)</span> + +<span class="muRecipe">after</span> +global-type [ + <span class="Delimiter">{</span> + ctrl-l?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">12/ctrl-l</span> + <span class="muControl">break-unless</span> ctrl-l? + screen<span class="Special"> <- </span>render-all screen, env:address:programming-environment-data + <span class="muControl">loop</span> <span class="Constant">+next-event:label</span> + <span class="Delimiter">}</span> +] + +<span class="Comment"># ctrl-n - switch focus</span> +<span class="Comment"># todo: test this</span> + +<span class="muRecipe">after</span> +global-type [ + <span class="Delimiter">{</span> + ctrl-n?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">14/ctrl-n</span> + <span class="muControl">break-unless</span> ctrl-n? + *sandbox-in-focus?<span class="Special"> <- </span>not *sandbox-in-focus? + screen<span class="Special"> <- </span>update-cursor screen, recipes, current-sandbox, *sandbox-in-focus? + <span class="muControl">loop</span> <span class="Constant">+next-event:label</span> + <span class="Delimiter">}</span> +] + +<span class="Comment"># ctrl-x - maximize/unmaximize the side with focus</span> + +<span class="muScenario">scenario</span> maximize-side [ +<span class="Constant"> $close-trace</span> + assume-screen <span class="Constant">30/width</span>, <span class="Constant">5/height</span> + <span class="Comment"># initialize both halves of screen</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> + <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[def]</span> + <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character + screen<span class="Special"> <- </span>render-all screen, <span class="Constant">3</span>:address:programming-environment-data + screen-should-contain [ + <span class="Constant"> . run (F4) .</span> + <span class="Constant"> .abc ┊def .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ .</span> + ] + <span class="Comment"># hit ctrl-x</span> + assume-console [ + type <span class="Constant">[x]</span> + ] + <span class="Constant">4</span>:event/ctrl-x<span class="Special"> <- </span>merge <span class="Constant">0/text</span>, <span class="Constant">24/ctrl-x</span>, <span class="Constant">0/dummy</span>, <span class="Constant">0/dummy</span> + replace-in-console <span class="Constant">120/x</span>, <span class="Constant">4</span>:event/ctrl-x + run [ + event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data + ] + <span class="Comment"># only left side visible</span> + screen-should-contain [ + <span class="Constant"> . run (F4) .</span> + <span class="Constant"> .abc .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈.</span> + <span class="Constant"> . .</span> + ] + <span class="Comment"># hit any key to toggle back</span> + assume-console [ + press <span class="Constant">24</span> <span class="Comment"># ctrl-x</span> + ] + run [ + event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data + ] + screen-should-contain [ + <span class="Constant"> . run (F4) .</span> + <span class="Constant"> .abc ┊def .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ .</span> + ] +] + +container programming-environment-data [ + maximized?:boolean +] + +<span class="muRecipe">after</span> +global-type [ + <span class="Delimiter">{</span> + ctrl-x?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">24/ctrl-x</span> + <span class="muControl">break-unless</span> ctrl-x? + screen, console<span class="Special"> <- </span>maximize screen, console, env:address:programming-environment-data + <span class="muControl">loop</span> <span class="Constant">+next-event:label</span> + <span class="Delimiter">}</span> +] + +<span class="muRecipe">recipe</span> maximize [ + <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> + hide-screen screen + <span class="Comment"># maximize one of the sides</span> + maximized?:address:boolean<span class="Special"> <- </span>get-address *env, <span class="Constant">maximized?:offset</span> + *maximized?<span class="Special"> <- </span>copy <span class="Constant">1/true</span> + <span class="Comment">#</span> + sandbox-in-focus?:boolean<span class="Special"> <- </span>get *env, <span class="Constant">sandbox-in-focus?:offset</span> + <span class="Delimiter">{</span> + <span class="muControl">break-if</span> sandbox-in-focus? + editor:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">recipes:offset</span> + right:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">right:offset</span> + *right<span class="Special"> <- </span>screen-width screen + *right<span class="Special"> <- </span>subtract *right, <span class="Constant">1</span> + screen<span class="Special"> <- </span>render-recipes screen, env + <span class="Delimiter">}</span> + <span class="Delimiter">{</span> + <span class="muControl">break-unless</span> sandbox-in-focus? + editor:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">current-sandbox:offset</span> + left:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">left:offset</span> + *left<span class="Special"> <- </span>copy <span class="Constant">0</span> + screen<span class="Special"> <- </span>render-sandbox-side screen, env + <span class="Delimiter">}</span> + show-screen screen + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, console/same-as-ingredient:<span class="Constant">1</span> +] + +<span class="Comment"># when maximized, wait for any event and simply unmaximize</span> +<span class="muRecipe">after</span> +handle-event [ + <span class="Delimiter">{</span> + maximized?:address:boolean<span class="Special"> <- </span>get-address *env, <span class="Constant">maximized?:offset</span> + <span class="muControl">break-unless</span> *maximized? + *maximized?<span class="Special"> <- </span>copy <span class="Constant">0/false</span> + <span class="Comment"># undo maximize</span> + <span class="Delimiter">{</span> + <span class="muControl">break-if</span> *sandbox-in-focus? + editor:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">recipes:offset</span> + right:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">right:offset</span> + *right<span class="Special"> <- </span>screen-width screen + *right<span class="Special"> <- </span>divide *right, <span class="Constant">2</span> + *right<span class="Special"> <- </span>subtract *right, <span class="Constant">1</span> + <span class="Delimiter">}</span> + <span class="Delimiter">{</span> + <span class="muControl">break-unless</span> *sandbox-in-focus? + editor:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">current-sandbox:offset</span> + left:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">left:offset</span> + *left<span class="Special"> <- </span>screen-width screen + *left<span class="Special"> <- </span>divide *left, <span class="Constant">2</span> + *left<span class="Special"> <- </span>add *left, <span class="Constant">1</span> + <span class="Delimiter">}</span> + render-all screen, env + show-screen screen + <span class="muControl">loop</span> <span class="Constant">+next-event:label</span> + <span class="Delimiter">}</span> ] <span class="SalientComment">## running code from the editor and creating sandboxes</span> @@ -3730,6 +4933,7 @@ container sandbox-data [ expected-response:address:array:character <span class="Comment"># coordinates to track clicks</span> starting-row-on-screen:number + code-ending-row-on-screen:number response-starting-row-on-screen:number display-trace?:boolean screen:address:screen <span class="Comment"># prints in the sandbox go here</span> @@ -3819,11 +5023,17 @@ container sandbox-data [ <span class="Delimiter">{</span> do-run?:boolean<span class="Special"> <- </span>equal *k, <span class="Constant">65532/F4</span> <span class="muControl">break-unless</span> do-run? - run-sandboxes env + status:address:array:character<span class="Special"> <- </span>new <span class="Constant">[running... ]</span> + screen<span class="Special"> <- </span>update-status screen, status, <span class="Constant">245/grey</span> + screen, error?:boolean<span class="Special"> <- </span>run-sandboxes env, screen <span class="Comment"># F4 might update warnings and results on both sides</span> screen<span class="Special"> <- </span>render-all screen, env - update-cursor screen, recipes, current-sandbox, *sandbox-in-focus? - show-screen screen + <span class="Delimiter">{</span> + <span class="muControl">break-if</span> error? + status:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ ]</span> + screen<span class="Special"> <- </span>update-status screen, status, <span class="Constant">245/grey</span> + <span class="Delimiter">}</span> + screen<span class="Special"> <- </span>update-cursor screen, recipes, current-sandbox, *sandbox-in-focus? <span class="muControl">loop</span> <span class="Constant">+next-event:label</span> <span class="Delimiter">}</span> ] @@ -3831,6 +5041,7 @@ container sandbox-data [ <span class="muRecipe">recipe</span> run-sandboxes [ <span class="Constant">local-scope</span> env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> recipes:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">recipes:offset</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 @@ -3838,7 +5049,12 @@ container sandbox-data [ recipe-warnings:address:address:array:character<span class="Special"> <- </span>get-address *env, <span class="Constant">recipe-warnings:offset</span> *recipe-warnings<span class="Special"> <- </span>reload in <span class="Comment"># if recipe editor has errors, stop</span> - <span class="muControl">reply-if</span> *recipe-warnings + <span class="Delimiter">{</span> + <span class="muControl">break-unless</span> *recipe-warnings + status:address:array:character<span class="Special"> <- </span>new <span class="Constant">[errors found]</span> + update-status screen, status, <span class="Constant">1/red</span> + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/errors-found</span> + <span class="Delimiter">}</span> <span class="Comment"># check contents of right editor (sandbox)</span> current-sandbox:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">current-sandbox:offset</span> <span class="Delimiter">{</span> @@ -3871,10 +5087,27 @@ container sandbox-data [ warnings:address:address:array:character<span class="Special"> <- </span>get-address *curr, <span class="Constant">warnings:offset</span> trace:address:address:array:character<span class="Special"> <- </span>get-address *curr, <span class="Constant">trace:offset</span> fake-screen:address:address:screen<span class="Special"> <- </span>get-address *curr, <span class="Constant">screen:offset</span> - *response, *warnings, *fake-screen, *trace<span class="Special"> <- </span>run-interactive *data + *response, *warnings, *fake-screen, *trace, completed?:boolean<span class="Special"> <- </span>run-interactive *data + <span class="Delimiter">{</span> + <span class="muControl">break-if</span> *warnings + <span class="muControl">break-if</span> completed?:boolean + *warnings<span class="Special"> <- </span>new <span class="Constant">[took too long!</span> +<span class="Constant">]</span> + <span class="Delimiter">}</span> curr<span class="Special"> <- </span>get *curr, <span class="Constant">next-sandbox:offset</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-errors-found</span> +] + +<span class="muRecipe">recipe</span> update-status [ + <span class="Constant">local-scope</span> + screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + msg: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> + screen<span class="Special"> <- </span>move-cursor screen, <span class="Constant">0</span>, <span class="Constant">2</span> + screen<span class="Special"> <- </span>print-string screen, msg, color, <span class="Constant">238/grey/background</span> + <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span> ] <span class="muRecipe">recipe</span> save-sandboxes [ @@ -3907,27 +5140,17 @@ container sandbox-data [ <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> -<span class="CommentedCode">#? trace [app], [render sandbox side] #? 1</span> +<span class="CommentedCode">#? trace 10, [app], [render sandbox side] #? 1</span> current-sandbox:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">current-sandbox:offset</span> left:number<span class="Special"> <- </span>get *current-sandbox, <span class="Constant">left:offset</span> right:number<span class="Special"> <- </span>get *current-sandbox, <span class="Constant">right:offset</span> - row:number, screen<span class="Special"> <- </span>render screen, current-sandbox + row:number, column:number, screen, current-sandbox<span class="Special"> <- </span>render screen, current-sandbox + clear-screen-from screen, row, column, left, right row<span class="Special"> <- </span>add row, <span class="Constant">1</span> draw-horizontal screen, row, left, right, <span class="Constant">9473/horizontal-double</span> sandbox:address:sandbox-data<span class="Special"> <- </span>get *env, <span class="Constant">sandbox:offset</span> row, screen<span class="Special"> <- </span>render-sandboxes screen, sandbox, left, right, row - <span class="Comment"># clear rest of screen</span> - row<span class="Special"> <- </span>add row, <span class="Constant">1</span> - move-cursor screen, row, left - screen-height:number<span class="Special"> <- </span>screen-height screen - <span class="Delimiter">{</span> - at-bottom-of-screen?:boolean<span class="Special"> <- </span>greater-or-equal row, screen-height - <span class="muControl">break-if</span> at-bottom-of-screen? - move-cursor screen, row, left - clear-line-delimited screen, left, right - row<span class="Special"> <- </span>add row, <span class="Constant">1</span> - <span class="muControl">loop</span> - <span class="Delimiter">}</span> + clear-rest-of-screen screen, row, left, left, right <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span> ] @@ -3944,7 +5167,7 @@ container sandbox-data [ <span class="muControl">reply-if</span> at-bottom?:boolean, row/same-as-ingredient:<span class="Constant">4</span>, screen/same-as-ingredient:<span class="Constant">0</span> <span class="Comment"># render sandbox menu</span> row<span class="Special"> <- </span>add row, <span class="Constant">1</span> - move-cursor screen, row, left + screen<span class="Special"> <- </span>move-cursor screen, row, left clear-line-delimited screen, left, right print-character screen, <span class="Constant">120/x</span>, <span class="Constant">245/grey</span> <span class="Comment"># save menu row so we can detect clicks to it later</span> @@ -3953,6 +5176,8 @@ container sandbox-data [ <span class="Comment"># render sandbox contents</span> sandbox-data:address:array:character<span class="Special"> <- </span>get *sandbox, <span class="Constant">data:offset</span> row, screen<span class="Special"> <- </span>render-string screen, sandbox-data, left, right, <span class="Constant">7/white</span>, row + code-ending-row:address:number<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">code-ending-row-on-screen:offset</span> + *code-ending-row<span class="Special"> <- </span>copy row <span class="Comment"># render sandbox warnings, screen or response, in that order</span> response-starting-row:address:number<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">response-starting-row-on-screen:offset</span> sandbox-response:address:array:character<span class="Special"> <- </span>get *sandbox, <span class="Constant">response:offset</span> @@ -4021,7 +5246,7 @@ container sandbox-data [ <span class="muControl">reply</span> env/same-as-ingredient:<span class="Constant">0</span> ] -<span class="Comment"># row:number, screen:address <- render-screen screen:address, sandbox-screen:address, left:number, right:number, row:number</span> +<span class="Comment"># row, screen <- 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 [ @@ -4039,7 +5264,7 @@ container sandbox-data [ row<span class="Special"> <- </span>render-string screen, header, left, right, <span class="Constant">245/grey</span>, row <span class="Comment"># newline</span> row<span class="Special"> <- </span>add row, <span class="Constant">1</span> - move-cursor screen, row, left + screen<span class="Special"> <- </span>move-cursor screen, row, left <span class="Comment"># start printing s</span> column:number<span class="Special"> <- </span>copy left s-width:number<span class="Special"> <- </span>screen-width s @@ -4056,7 +5281,7 @@ container sandbox-data [ done?<span class="Special"> <- </span>greater-or-equal row, screen-height <span class="muControl">break-if</span> done? column<span class="Special"> <- </span>copy left - move-cursor screen, row, column + screen<span class="Special"> <- </span>move-cursor screen, row, column <span class="Comment"># initial leader for each row: two spaces and a '.'</span> print-character screen, <span class="Constant">32/space</span>, <span class="Constant">245/grey</span> print-character screen, <span class="Constant">32/space</span>, <span class="Constant">245/grey</span> @@ -4230,11 +5455,11 @@ container sandbox-data [ ] <span class="muScenario">scenario</span> run-instruction-manages-screen-per-sandbox [ - $close-trace <span class="Comment"># trace too long for github #? 1</span> + $close-trace <span class="Comment"># trace too long for github</span> assume-screen <span class="Constant">100/width</span>, <span class="Constant">20/height</span> <span class="Comment"># left editor is empty</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span> - <span class="Comment"># right editor contains an illegal instruction</span> + <span class="Comment"># right editor contains an instruction</span> <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[print-integer screen:address, 4]</span> <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character <span class="Comment"># run the code in the editor</span> @@ -4244,8 +5469,39 @@ container sandbox-data [ run [ event-loop screen:address, console:address, <span class="Constant">3</span>: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> + <span class="Comment"># check that it prints a little toy screen</span> + screen-should-contain [ + <span class="Constant"> . run (F4) .</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="muScenario">scenario</span> sandbox-with-print-can-be-edited [ +<span class="Constant"> $close-trace</span> + assume-screen <span class="Constant">100/width</span>, <span class="Constant">20/height</span> + <span class="Comment"># left editor is empty</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span> + <span class="Comment"># right editor contains an instruction</span> + <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[print-integer screen:address, 4]</span> + <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character + <span class="Comment"># run the sandbox</span> + assume-console [ + press <span class="Constant">65532</span> <span class="Comment"># F4</span> + ] + run [ + event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data + ] screen-should-contain [ <span class="Constant"> . run (F4) .</span> <span class="Constant"> . ┊ .</span> @@ -4261,6 +5517,51 @@ container sandbox-data [ <span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> <span class="Constant"> . ┊ .</span> ] + <span class="Comment"># edit the sandbox</span> + assume-console [ + left-click <span class="Constant">3</span>, <span class="Constant">70</span> + ] + run [ + event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data + ] + screen-should-contain [ + <span class="Constant"> . run (F4) .</span> + <span class="Constant"> . ┊print-integer screen:address, 4 .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ .</span> + <span class="Constant"> . ┊ .</span> + ] +] + +<span class="muScenario">scenario</span> sandbox-can-handle-infinite-loop [ +<span class="Constant"> $close-trace</span> + assume-screen <span class="Constant">100/width</span>, <span class="Constant">20/height</span> + <span class="Comment"># left editor is empty</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[recipe foo [</span> +<span class="Constant"> {</span> +<span class="Constant"> loop</span> +<span class="Constant"> }</span> +<span class="Constant">]</span>] + <span class="Comment"># right editor contains an instruction</span> + <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span> + <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character + <span class="Comment"># run the sandbox</span> + assume-console [ + press <span class="Constant">65532</span> <span class="Comment"># F4</span> + ] + run [ + event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data + ] + screen-should-contain [ + <span class="Constant"> . run (F4) .</span> + <span class="Constant"> .recipe foo [ ┊ .</span> + <span class="Constant"> . { ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . loop ┊ x.</span> + <span class="Constant"> . } ┊foo .</span> + <span class="Constant"> .] ┊took too long! .</span> +<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ .</span> + ] ] <span class="muRecipe">recipe</span> editor-contents [ @@ -4368,8 +5669,9 @@ container sandbox-data [ sandbox:address:sandbox-data<span class="Special"> <- </span>extract-sandbox env, click-row text:address:array:character<span class="Special"> <- </span>get *sandbox, <span class="Constant">data:offset</span> current-sandbox<span class="Special"> <- </span>insert-text current-sandbox, text + hide-screen screen screen<span class="Special"> <- </span>render-sandbox-side screen, env - update-cursor screen, recipes, current-sandbox, *sandbox-in-focus? + screen<span class="Special"> <- </span>update-cursor screen, recipes, current-sandbox, *sandbox-in-focus? show-screen screen <span class="muControl">loop</span> <span class="Constant">+next-event:label</span> <span class="Delimiter">}</span> @@ -4482,9 +5784,10 @@ container sandbox-data [ <span class="Delimiter">{</span> was-delete?:boolean<span class="Special"> <- </span>delete-sandbox *t, env <span class="muControl">break-unless</span> was-delete? -<span class="CommentedCode">#? trace [app], [delete clicked] #? 1</span> +<span class="CommentedCode">#? trace 10, [app], [delete clicked] #? 1</span> + hide-screen screen screen<span class="Special"> <- </span>render-sandbox-side screen, env - update-cursor screen, recipes, current-sandbox, *sandbox-in-focus? + screen<span class="Special"> <- </span>update-cursor screen, recipes, current-sandbox, *sandbox-in-focus? show-screen screen <span class="muControl">loop</span> <span class="Constant">+next-event:label</span> <span class="Delimiter">}</span> @@ -4611,6 +5914,7 @@ container sandbox-data [ <span class="Comment"># toggle its expected-response, and save session</span> sandbox<span class="Special"> <- </span>toggle-expected-response sandbox save-sandboxes env + hide-screen screen screen<span class="Special"> <- </span>render-sandbox-side screen, env, <span class="Constant">1/clear</span> <span class="Comment"># no change in cursor</span> show-screen screen @@ -4639,11 +5943,9 @@ container sandbox-data [ <span class="Delimiter">}</span> <span class="Comment"># return sandbox if click is in its output region</span> response-starting-row:number<span class="Special"> <- </span>get *sandbox, <span class="Constant">response-starting-row-on-screen:offset</span> + <span class="muControl">reply-unless</span> response-starting-row, <span class="Constant">0/no-click-in-sandbox-output</span> click-in-response?:boolean<span class="Special"> <- </span>greater-or-equal click-row, response-starting-row - <span class="Delimiter">{</span> - <span class="muControl">break-if</span> click-in-response? - <span class="muControl">reply</span> <span class="Constant">0/no-click-in-sandbox-output</span> - <span class="Delimiter">}</span> + <span class="muControl">reply-unless</span> click-in-response?, <span class="Constant">0/no-click-in-sandbox-output</span> <span class="muControl">reply</span> sandbox ] @@ -4690,7 +5992,7 @@ container sandbox-data [ <span class="Comment"># basic recipe</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span> <span class="Constant">recipe foo [</span> -<span class="Constant"> trace [abc]</span> +<span class="Constant"> stash [abc]</span> ]] <span class="Comment"># run it</span> <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span> @@ -4703,7 +6005,7 @@ container sandbox-data [ <span class="Constant"> . run (F4) .</span> <span class="Constant"> . ┊ .</span> <span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━.</span> - <span class="Constant"> . trace [abc] ┊ x.</span> + <span class="Constant"> . stash [abc] ┊ x.</span> <span class="Constant"> .] ┊foo .</span> <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━.</span> <span class="Constant"> . ┊ .</span> @@ -4720,7 +6022,7 @@ container sandbox-data [ <span class="Constant"> . run (F4) .</span> <span class="Constant"> . ┊ .</span> <span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━.</span> - <span class="Constant"> . trace [abc] ┊ x.</span> + <span class="Constant"> . stash [abc] ┊ x.</span> <span class="Constant"> .] ┊foo .</span> <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊abc .</span> <span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━.</span> @@ -4748,7 +6050,7 @@ container sandbox-data [ <span class="Constant"> . run (F4) .</span> <span class="Constant"> . ┊ .</span> <span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━.</span> - <span class="Constant"> . trace [abc] ┊ x.</span> + <span class="Constant"> . stash [abc] ┊ x.</span> <span class="Constant"> .] ┊foo .</span> <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━.</span> <span class="Constant"> . ┊ .</span> @@ -4761,7 +6063,7 @@ container sandbox-data [ <span class="Comment"># basic recipe</span> <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span> <span class="Constant">recipe foo [</span> -<span class="Constant"> trace [abc]</span> +<span class="Constant"> stash [abc]</span> add <span class="Constant">2</span>, <span class="Constant">2</span> ]] <span class="Comment"># run it</span> @@ -4775,7 +6077,7 @@ container sandbox-data [ <span class="Constant"> . run (F4) .</span> <span class="Constant"> . ┊ .</span> <span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━.</span> - <span class="Constant"> . trace [abc] ┊ x.</span> + <span class="Constant"> . stash [abc] ┊ x.</span> <span class="Constant"> . add 2, 2 ┊foo .</span> <span class="Constant"> .] ┊4 .</span> <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━.</span> @@ -4793,7 +6095,7 @@ container sandbox-data [ <span class="Constant"> . run (F4) .</span> <span class="Constant"> . ┊ .</span> <span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━.</span> - <span class="Constant"> . trace [abc] ┊ x.</span> + <span class="Constant"> . stash [abc] ┊ x.</span> <span class="Constant"> . add 2, 2 ┊foo .</span> <span class="Constant"> .] ┊abc .</span> <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 .</span> @@ -4822,6 +6124,7 @@ container sandbox-data [ <span class="Comment"># toggle its display-trace? property</span> x:address:boolean<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">display-trace?:offset</span> *x<span class="Special"> <- </span>not *x + hide-screen screen screen<span class="Special"> <- </span>render-sandbox-side screen, env, <span class="Constant">1/clear</span> <span class="Comment"># no change in cursor</span> show-screen screen @@ -4849,8 +6152,8 @@ container sandbox-data [ <span class="muControl">loop</span> <span class="Delimiter">}</span> <span class="Comment"># return sandbox if click is in its code region</span> - response-starting-row:number<span class="Special"> <- </span>get *sandbox, <span class="Constant">response-starting-row-on-screen:offset</span> - click-above-response?:boolean<span class="Special"> <- </span>lesser-than click-row, response-starting-row + code-ending-row:number<span class="Special"> <- </span>get *sandbox, <span class="Constant">code-ending-row-on-screen:offset</span> + click-above-response?:boolean<span class="Special"> <- </span>lesser-or-equal click-row, code-ending-row start:number<span class="Special"> <- </span>get *sandbox, <span class="Constant">starting-row-on-screen:offset</span> click-below-menu?:boolean<span class="Special"> <- </span>greater-than click-row, start click-on-sandbox-code?:boolean<span class="Special"> <- </span>and click-above-response?, click-below-menu? @@ -4879,20 +6182,20 @@ container sandbox-data [ <span class="muScenario">scenario</span> run-shows-warnings-in-get [ <span class="Constant"> $close-trace</span> assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span> +<span class="Constant">recipe foo [</span> +<span class="Constant"> get 123:number, foo:offset</span> +<span class="Constant">]</span>] + <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span> + <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character assume-console [ press <span class="Constant">65532</span> <span class="Comment"># F4</span> ] run [ - x:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span> -<span class="Constant">recipe foo [</span> -<span class="Constant"> get 123:number, foo:offset</span> -<span class="Constant">]</span>] - y:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span> - env:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, x:address:array:character, y:address:array:character - event-loop screen:address, console:address, env:address:programming-environment-data + event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data ] screen-should-contain [ - <span class="Constant"> . run (F4) .</span> + <span class="Constant"> . errors found run (F4) .</span> <span class="Constant"> . ┊foo .</span> <span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> <span class="Constant"> . get 123:number, foo:offset ┊ .</span> @@ -4902,7 +6205,7 @@ container sandbox-data [ <span class="Constant"> . ┊ .</span> ] screen-should-contain-in-color <span class="Constant">1/red</span>, [ - <span class="Constant"> . .</span> + <span class="Constant"> . errors found .</span> <span class="Constant"> . .</span> <span class="Constant"> . .</span> <span class="Constant"> . .</span> @@ -4915,20 +6218,20 @@ container sandbox-data [ <span class="muScenario">scenario</span> run-shows-missing-type-warnings [ <span class="Constant"> $close-trace</span> assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span> +<span class="Constant">recipe foo [</span> +<span class="Constant"> x <- copy 0</span> +<span class="Constant">]</span>] + <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span> + <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character assume-console [ press <span class="Constant">65532</span> <span class="Comment"># F4</span> ] run [ - x:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span> -<span class="Constant">recipe foo [</span> -<span class="Constant"> x <- copy 0</span> -<span class="Constant">]</span>] - y:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span> - env:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, x:address:array:character, y:address:array:character - event-loop screen:address, console:address, env:address:programming-environment-data + event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data ] screen-should-contain [ - <span class="Constant"> . run (F4) .</span> + <span class="Constant"> . errors found run (F4) .</span> <span class="Constant"> . ┊foo .</span> <span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> <span class="Constant"> . x <- copy 0 ┊ .</span> @@ -4939,21 +6242,50 @@ container sandbox-data [ ] ] -<span class="muScenario">scenario</span> run-shows-get-on-non-container-warnings [ +<span class="muScenario">scenario</span> run-shows-unbalanced-bracket-warnings [ <span class="Constant"> $close-trace</span> assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span> + <span class="Comment"># recipe is incomplete (unbalanced '[')</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span> +<span class="Constant">recipe foo «</span> +<span class="Constant"> x <- copy 0</span> +<span class="Constant">]</span> + string-replace <span class="Constant">1</span>:address:array:character, <span class="Constant">171/«</span>, <span class="Constant">91</span> <span class="Comment"># '['</span> + <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span> + <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character assume-console [ press <span class="Constant">65532</span> <span class="Comment"># F4</span> ] run [ - x:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span> + event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data + ] + screen-should-contain [ + <span class="Constant"> . errors found run (F4) .</span> + <span class="Constant"> . ┊foo .</span> + <span class="Constant"> .recipe foo \\\[ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . x <- copy 0 ┊ .</span> + <span class="Constant"> . ┊ .</span> + <span class="Constant"> .9: unbalanced '\\\[' for recipe ┊ .</span> + <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊ .</span> + <span class="Constant"> . ┊ .</span> + ] +] + +<span class="muScenario">scenario</span> run-shows-get-on-non-container-warnings [ +<span class="Constant"> $close-trace</span> + assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span> <span class="Constant">recipe foo [</span> <span class="Constant"> x:address:point <- new point:type</span> <span class="Constant"> get x:address:point, 1:offset</span> <span class="Constant">]</span>] - y:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span> - env:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, x:address:array:character, y:address:array:character - event-loop screen:address, console:address, env:address:programming-environment-data + <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span> + <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character + assume-console [ + press <span class="Constant">65532</span> <span class="Comment"># F4</span> + ] + run [ + event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data ] screen-should-contain [ <span class="Constant"> . run (F4) .</span> @@ -4971,22 +6303,22 @@ container sandbox-data [ <span class="muScenario">scenario</span> run-shows-non-literal-get-argument-warnings [ <span class="Constant"> $close-trace</span> assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span> - assume-console [ - press <span class="Constant">65532</span> <span class="Comment"># F4</span> - ] - run [ - x:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span> <span class="Constant">recipe foo [</span> <span class="Constant"> x:number <- copy 0</span> <span class="Constant"> y:address:point <- new point:type</span> <span class="Constant"> get *y:address:point, x:number</span> <span class="Constant">]</span>] - y:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span> - env:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, x:address:array:character, y:address:array:character - event-loop screen:address, console:address, env:address:programming-environment-data + <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span> + <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character + assume-console [ + press <span class="Constant">65532</span> <span class="Comment"># F4</span> + ] + run [ + event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data ] screen-should-contain [ - <span class="Constant"> . run (F4) .</span> + <span class="Constant"> . errors found run (F4) .</span> <span class="Constant"> . ┊foo .</span> <span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> <span class="Constant"> . x:number <- copy 0 ┊ .</span> @@ -5000,6 +6332,51 @@ container sandbox-data [ ] ] +<span class="muScenario">scenario</span> run-shows-warnings-everytime [ +<span class="Constant"> $close-trace</span> + <span class="Comment"># try to run a file with an error</span> + assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span> +<span class="Constant">recipe foo [</span> +<span class="Constant"> x:number <- copy y:number</span> +<span class="Constant">]</span>] + <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span> + <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character + assume-console [ + press <span class="Constant">65532</span> <span class="Comment"># F4</span> + ] + run [ + event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data + ] + screen-should-contain [ + <span class="Constant"> . errors found run (F4) .</span> + <span class="Constant"> . ┊foo .</span> + <span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . x:number <- copy y:number ┊ .</span> + <span class="Constant"> .] ┊ .</span> + <span class="Constant"> .use before set: y in foo ┊ .</span> + <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊ .</span> + <span class="Constant"> . ┊ .</span> + ] + <span class="Comment"># rerun the file, check for the same error</span> + assume-console [ + press <span class="Constant">65532</span> <span class="Comment"># F4</span> + ] + run [ + event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data + ] + screen-should-contain [ + <span class="Constant"> . errors found run (F4) .</span> + <span class="Constant"> . ┊foo .</span> + <span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . x:number <- copy y:number ┊ .</span> + <span class="Constant"> .] ┊ .</span> + <span class="Constant"> .use before set: y in foo ┊ .</span> + <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊ .</span> + <span class="Constant"> . ┊ .</span> + ] +] + <span class="SalientComment">## helpers for drawing editor borders</span> <span class="muRecipe">recipe</span> draw-box [ @@ -5025,7 +6402,7 @@ container sandbox-data [ draw-bottom-left screen, bottom, left, color draw-bottom-right screen, bottom, right, color <span class="Comment"># position cursor inside box</span> - move-cursor screen, top, left + screen<span class="Special"> <- </span>move-cursor screen, top, left cursor-down screen cursor-right screen ] @@ -5052,7 +6429,7 @@ container sandbox-data [ <span class="muControl">break-if</span> bg-color-found? bg-color<span class="Special"> <- </span>copy <span class="Constant">0/black</span> <span class="Delimiter">}</span> - move-cursor screen, row, x + screen<span class="Special"> <- </span>move-cursor screen, row, x <span class="Delimiter">{</span> continue?:boolean<span class="Special"> <- </span>lesser-or-equal x, right <span class="Comment"># right is inclusive, to match editor-data semantics</span> <span class="muControl">break-unless</span> continue? @@ -5082,7 +6459,7 @@ container sandbox-data [ <span class="Delimiter">{</span> continue?:boolean<span class="Special"> <- </span>lesser-than y, bottom <span class="muControl">break-unless</span> continue? - move-cursor screen, y, col + screen<span class="Special"> <- </span>move-cursor screen, y, col print-character screen, style, color y<span class="Special"> <- </span>add y, <span class="Constant">1</span> <span class="muControl">loop</span> @@ -5100,7 +6477,7 @@ container sandbox-data [ <span class="muControl">break-if</span> color-found? color<span class="Special"> <- </span>copy <span class="Constant">245/grey</span> <span class="Delimiter">}</span> - move-cursor screen, top, left + screen<span class="Special"> <- </span>move-cursor screen, top, left print-character screen, <span class="Constant">9484/down-right</span>, color ] @@ -5115,7 +6492,7 @@ container sandbox-data [ <span class="muControl">break-if</span> color-found? color<span class="Special"> <- </span>copy <span class="Constant">245/grey</span> <span class="Delimiter">}</span> - move-cursor screen, top, right + screen<span class="Special"> <- </span>move-cursor screen, top, right print-character screen, <span class="Constant">9488/down-left</span>, color ] @@ -5130,7 +6507,7 @@ container sandbox-data [ <span class="muControl">break-if</span> color-found? color<span class="Special"> <- </span>copy <span class="Constant">245/grey</span> <span class="Delimiter">}</span> - move-cursor screen, bottom, left + screen<span class="Special"> <- </span>move-cursor screen, bottom, left print-character screen, <span class="Constant">9492/up-right</span>, color ] @@ -5145,7 +6522,7 @@ container sandbox-data [ <span class="muControl">break-if</span> color-found? color<span class="Special"> <- </span>copy <span class="Constant">245/grey</span> <span class="Delimiter">}</span> - move-cursor screen, bottom, right + screen<span class="Special"> <- </span>move-cursor screen, bottom, right print-character screen, <span class="Constant">9496/up-left</span>, color ] diff --git a/html/factorial.mu.html b/html/factorial.mu.html index 4a153691..d3837c22 100644 --- a/html/factorial.mu.html +++ b/html/factorial.mu.html @@ -13,13 +13,13 @@ 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; } -.muControl { color: #c0a020; } .muRecipe { color: #ff8700; } -.Delimiter { color: #a04060; } +.muScenario { color: #00af00; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .Special { color: #ff6060; } -.muScenario { color: #00af00; } +.Delimiter { color: #a04060; } +.muControl { color: #c0a020; } --> </style> diff --git a/html/fork.mu.html b/html/fork.mu.html index a051c0b3..09d02860 100644 --- a/html/fork.mu.html +++ b/html/fork.mu.html @@ -13,11 +13,11 @@ 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; } -.muControl { color: #c0a020; } .muRecipe { color: #ff8700; } -.Delimiter { color: #a04060; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } +.Delimiter { color: #a04060; } +.muControl { color: #c0a020; } --> </style> diff --git a/html/tangle.mu.html b/html/tangle.mu.html index e17d1df8..e3dba023 100644 --- a/html/tangle.mu.html +++ b/html/tangle.mu.html @@ -13,12 +13,12 @@ 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; } -.muControl { color: #c0a020; } .muRecipe { color: #ff8700; } -.Delimiter { color: #a04060; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .Special { color: #ff6060; } +.Delimiter { color: #a04060; } +.muControl { color: #c0a020; } --> </style> |