diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-11-29 14:18:52 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-11-29 14:18:52 -0800 |
commit | db1f56c8449d2ea3d158753fe37bac5a750a2566 (patch) | |
tree | 508a24c522c040498dbe7d60036035f3c4ae440a | |
parent | 3670fb87f6d38c9ba4fcbb1eaa6439b4007a194e (diff) | |
download | mu-db1f56c8449d2ea3d158753fe37bac5a750a2566.tar.gz |
2611
61 files changed, 1662 insertions, 1101 deletions
diff --git a/html/000organization.cc.html b/html/000organization.cc.html index bbc09e8d..a3822fb5 100644 --- a/html/000organization.cc.html +++ b/html/000organization.cc.html @@ -136,6 +136,7 @@ int main<span class="Delimiter">(</span>int argc<span class="Delimiter">,</span> <span class="Comment">// End One-time Setup</span> + <span class="Comment">// Commandline Parsing</span> <span class="Comment">// End Commandline Parsing</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Comment">// End Main</span> diff --git a/html/001help.cc.html b/html/001help.cc.html index a6a34cdd..eaa49b8b 100644 --- a/html/001help.cc.html +++ b/html/001help.cc.html @@ -49,6 +49,9 @@ if <span class="Delimiter">(</span>argc <= <span class="Constant">1</span> || << <span class="Constant">"You can test directories just like files.</span><span class="cSpecial">\n</span><span class="Constant">"</span> << <span class="Constant">"To pass ingredients to a mu program, provide them after '--':</span><span class="cSpecial">\n</span><span class="Constant">"</span> << <span class="Constant">" mu file_or_dir1 file_or_dir2 ... -- ingredient1 ingredient2 ...</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="Constant">"To browse a trace generated by a previous run:</span><span class="cSpecial">\n</span><span class="Constant">"</span> + << <span class="Constant">" mu browse-trace file</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> @@ -146,6 +149,13 @@ template<typename T> typename T::mapped_type& get_or_insert<span class <span class="Delimiter">}</span> <span class="Comment">//: The contract: any container that relies on get_or_insert should never call</span> <span class="Comment">//: contains_key.</span> +<span class="Comment">//:</span> +<span class="Comment">//: 7. istreams are a royal pain in the arse. You have to be careful about</span> +<span class="Comment">//: what subclass you try to putback into. You have to watch out for the pesky</span> +<span class="Comment">//: failbit and badbit. Just avoid eof() and use this helper instead.</span> +bool has_data<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Identifier">return</span> in && !in<span class="Delimiter">.</span>eof<span class="Delimiter">();</span> +<span class="Delimiter">}</span> <span class="Delimiter">:(before "End Includes")</span> <span class="PreProc">#include</span><span class="Constant"><assert.h></span> diff --git a/html/003trace.cc.html b/html/003trace.cc.html index 022ad5f1..a1c0be03 100644 --- a/html/003trace.cc.html +++ b/html/003trace.cc.html @@ -192,10 +192,8 @@ trace_stream* Trace_stream = <span class="Constant">NULL</span><span class="Deli <span class="Comment">// Top-level helper. IMPORTANT: can't nest.</span> <span class="PreProc">#define trace(</span><span class="Delimiter">...</span><span class="PreProc">) !Trace_stream ? cerr </span><span class="Comment">/*</span><span class="Comment">print nothing</span><span class="Comment">*/</span><span class="PreProc"> : Trace_stream</span><span class="Delimiter">-></span><span class="PreProc">stream(__VA_ARGS__)</span> -<span class="Comment">// Errors and warnings should go straight to cerr by default since calls to trace() have</span> -<span class="Comment">// some unfriendly constraints (they delay printing, they can't nest)</span> -<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(Warning_depth</span><span class="Delimiter">,</span><span class="PreProc"> </span><span class="Constant">"warn"</span><span class="PreProc">))</span> -<span class="PreProc">#define raise_error ((!Trace_stream || !Hide_errors) ? (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(Error_depth</span><span class="Delimiter">,</span><span class="PreProc"> </span><span class="Constant">"error"</span><span class="PreProc">))</span> +<span class="PreProc">#define raise (!Trace_stream ? (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(Warning_depth</span><span class="Delimiter">,</span><span class="PreProc"> </span><span class="Constant">"warn"</span><span class="PreProc">))</span> +<span class="PreProc">#define raise_error (!Trace_stream ? (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(Error_depth</span><span class="Delimiter">,</span><span class="PreProc"> </span><span class="Constant">"error"</span><span class="PreProc">))</span> <span class="Delimiter">:(before "End Types")</span> struct end <span class="Delimiter">{};</span> diff --git a/html/010vm.cc.html b/html/010vm.cc.html index f476aa61..976edf51 100644 --- a/html/010vm.cc.html +++ b/html/010vm.cc.html @@ -94,6 +94,7 @@ struct reagent <span class="Delimiter">{</span> reagent<span class="Delimiter">(</span>string s<span class="Delimiter">);</span> reagent<span class="Delimiter">();</span> ~reagent<span class="Delimiter">();</span> + void clear<span class="Delimiter">();</span> reagent<span class="Delimiter">(</span>const reagent& old<span class="Delimiter">);</span> reagent& operator=<span class="Delimiter">(</span>const reagent& old<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> @@ -270,7 +271,7 @@ 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> - while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<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 key = slurp_until<span class="Delimiter">(</span>row<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">);</span> @@ -295,7 +296,7 @@ reagent::reagent<span class="Delimiter">(</span>string s<span class="Delimiter"> string_tree* parse_property_list<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> - if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span> string_tree* result = new string_tree<span class="Delimiter">(</span>slurp_until<span class="Delimiter">(</span>in<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">));</span> result<span class="Delimiter">-></span>right = parse_property_list<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> @@ -353,9 +354,18 @@ reagent& reagent::operator=<span class="Delimiter">(</span>const reagent& <span class="Delimiter">}</span> reagent::~reagent<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> - if <span class="Delimiter">(</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">)</span> delete properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">;</span> + clear<span class="Delimiter">();</span> +<span class="Delimiter">}</span> + +void reagent::clear<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> + if <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="Delimiter">{</span> + delete properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">;</span> + properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second = <span class="Constant">NULL</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Delimiter">}</span> delete type<span class="Delimiter">;</span> + type = <span class="Constant">NULL</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> type_tree::~type_tree<span class="Delimiter">()</span> <span class="Delimiter">{</span> delete left<span class="Delimiter">;</span> @@ -510,31 +520,6 @@ string_tree* property<span class="Delimiter">(</span>const reagent& r<span c <span class="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -bool deeply_equal<span class="Delimiter">(</span>const string_tree* a<span class="Delimiter">,</span> const string_tree* b<span class="Delimiter">)</span> <span class="Delimiter">{</span> - if <span class="Delimiter">(</span>!a<span class="Delimiter">)</span> <span class="Identifier">return</span> !b<span class="Delimiter">;</span> - if <span class="Delimiter">(</span>!b<span class="Delimiter">)</span> <span class="Identifier">return</span> !a<span class="Delimiter">;</span> - <span class="Identifier">return</span> a<span class="Delimiter">-></span>value == b<span class="Delimiter">-></span>value - && deeply_equal<span class="Delimiter">(</span>a<span class="Delimiter">-></span>left<span class="Delimiter">,</span> b<span class="Delimiter">-></span>left<span class="Delimiter">)</span> - && deeply_equal<span class="Delimiter">(</span>a<span class="Delimiter">-></span>right<span class="Delimiter">,</span> b<span class="Delimiter">-></span>right<span class="Delimiter">);</span> -<span class="Delimiter">}</span> - -<span class="Delimiter">:(before "End Globals")</span> -set<string> Literal_type_names<span class="Delimiter">;</span> -<span class="Delimiter">:(before "End One-time Setup")</span> -Literal_type_names<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">"literal"</span><span class="Delimiter">);</span> -Literal_type_names<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">"number"</span><span class="Delimiter">);</span> -Literal_type_names<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">"character"</span><span class="Delimiter">);</span> -<span class="Delimiter">:(code)</span> -bool deeply_equal_types<span class="Delimiter">(</span>const string_tree* a<span class="Delimiter">,</span> const string_tree* b<span class="Delimiter">)</span> <span class="Delimiter">{</span> - if <span class="Delimiter">(</span>!a<span class="Delimiter">)</span> <span class="Identifier">return</span> !b<span class="Delimiter">;</span> - if <span class="Delimiter">(</span>!b<span class="Delimiter">)</span> <span class="Identifier">return</span> !a<span class="Delimiter">;</span> - if <span class="Delimiter">(</span>Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>a<span class="Delimiter">-></span>value<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">())</span> - <span class="Identifier">return</span> Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>b<span class="Delimiter">-></span>value<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">();</span> - <span class="Identifier">return</span> a<span class="Delimiter">-></span>value == b<span class="Delimiter">-></span>value - && deeply_equal_types<span class="Delimiter">(</span>a<span class="Delimiter">-></span>left<span class="Delimiter">,</span> b<span class="Delimiter">-></span>left<span class="Delimiter">)</span> - && deeply_equal_types<span class="Delimiter">(</span>a<span class="Delimiter">-></span>right<span class="Delimiter">,</span> b<span class="Delimiter">-></span>right<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> << no_scientific<span class="Delimiter">(</span>p<span class="Delimiter">-></span>second<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> @@ -573,7 +558,7 @@ void dump<span class="Delimiter">(</span>const string_tree* x<span class="Delimi <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>!in<span class="Delimiter">.</span>eof<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> + while <span class="Delimiter">(</span>in && 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> diff --git a/html/011load.cc.html b/html/011load.cc.html index 3e74bc02..7296d1bb 100644 --- a/html/011load.cc.html +++ b/html/011load.cc.html @@ -53,9 +53,9 @@ 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> - while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + while <span class="Delimiter">(</span>has_data<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> - if <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>!has_data<span class="Delimiter">(</span>in<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> if <span class="Delimiter">(</span>command == <span class="Constant">"recipe"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -116,25 +116,25 @@ void slurp_body<span class="Delimiter">(</span>istream& in<span class="Delim bool next_instruction<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> instruction* curr<span class="Delimiter">)</span> <span class="Delimiter">{</span> curr<span class="Delimiter">-></span>clear<span class="Delimiter">();</span> - if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise_error << <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> 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> + if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise_error << <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> 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> + if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise_error << <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> - 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> + while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<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> - if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise_error << <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> @@ -151,7 +151,7 @@ bool next_instruction<span class="Delimiter">(</span>istream& in<span class= 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">9993</span><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> - if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise_error << <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> @@ -185,7 +185,7 @@ bool next_instruction<span class="Delimiter">(</span>istream& in<span class= 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">9993</span><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> - if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise_error << <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> @@ -210,7 +210,7 @@ string Ignore<span class="Delimiter">(</span><span class="Constant">"," <span class="Delimiter">:(code)</span> void slurp_word<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> ostream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span> char c<span class="Delimiter">;</span> - if <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">()</span> && Terminators<span class="Delimiter">.</span>find<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">())</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">)</span> && Terminators<span class="Delimiter">.</span>find<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">())</span> != string::npos<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> @@ -232,7 +232,7 @@ void skip_ignored_characters<span class="Delimiter">(</span>istream& in<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>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Identifier">break</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> 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> @@ -241,9 +241,9 @@ void skip_whitespace_and_comments<span class="Delimiter">(</span>istream& in <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>eof<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>has_data<span class="Delimiter">(</span>in<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> - 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> in<span class="Delimiter">.</span>get<span class="Delimiter">();</span> + while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<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> diff --git a/html/012transform.cc.html b/html/012transform.cc.html index 6770e137..7ddd15af 100644 --- a/html/012transform.cc.html +++ b/html/012transform.cc.html @@ -57,8 +57,16 @@ vector<transform_fn> Transform<span class="Delimiter">;</span> <span class="Delimiter">:(after "int main")</span> <span class="Comment">// Begin Transforms</span> + <span class="Comment">// Begin Instruction Inserting/Deleting Transforms</span> + <span class="Comment">// End Instruction Inserting/Deleting Transforms</span> + + <span class="Comment">// Begin Instruction Modifying Transforms</span> + <span class="Comment">// End Instruction Modifying Transforms</span> <span class="Comment">// End Transforms</span> + <span class="Comment">// Begin Checks</span> + <span class="Comment">// End Checks</span> + <span class="Delimiter">:(code)</span> void transform_all<span class="Delimiter">()</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">9990</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"=== transform_all()"</span> << end<span class="Delimiter">();</span> @@ -73,6 +81,7 @@ void transform_all<span class="Delimiter">()</span> <span class="Delimiter">{</s r<span class="Delimiter">.</span>transformed_until = t<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> +<span class="CommentedCode">//? cerr << "wrapping up transform\n";</span> parse_int_reagents<span class="Delimiter">();</span> <span class="Comment">// do this after all other transforms have run</span> <span class="Comment">// End Transform All</span> <span class="Delimiter">}</span> diff --git a/html/013update_operation.cc.html b/html/013update_operation.cc.html index c2377b97..7a6c5f78 100644 --- a/html/013update_operation.cc.html +++ b/html/013update_operation.cc.html @@ -33,7 +33,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment">//: Once all code is loaded, save operation ids of instructions and check that</span> <span class="Comment">//: nothing's undefined.</span> -<span class="Delimiter">:(before "End Transforms")</span> +<span class="Delimiter">:(before "End Instruction Modifying Transforms")</span> Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>update_instruction_operations<span class="Delimiter">);</span> <span class="Comment">// idempotent</span> <span class="Delimiter">:(code)</span> diff --git a/html/014literal_string.cc.html b/html/014literal_string.cc.html index b137323a..024a0efc 100644 --- a/html/014literal_string.cc.html +++ b/html/014literal_string.cc.html @@ -55,17 +55,17 @@ recipe main [ put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"literal-string"</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> <span class="Delimiter">:(before "End next_word Special-cases")</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> - <span class="Identifier">return</span> result<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> + <span class="Identifier">return</span> result<span class="Delimiter">;</span> +<span class="Delimiter">}</span> <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 << static_cast<char><span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">());</span> <span class="Comment">// slurp the '['</span> + assert<span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<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>is_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> else @@ -76,7 +76,7 @@ string slurp_quoted<span class="Delimiter">(</span>istream& in<span class="D <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> bool is_code_string<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> ostream& 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> + while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<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> @@ -94,7 +94,7 @@ bool is_code_string<span class="Delimiter">(</span>istream& in<span class="D <span class="Comment">// strings.</span> void slurp_quoted_comment_oblivious<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> ostream& out<span class="Delimiter">)</span> <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> + while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<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>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> @@ -105,7 +105,7 @@ void slurp_quoted_comment_oblivious<span class="Delimiter">(</span>istream& 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> - 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> + if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">)</span> && brace_depth > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> raise_error << <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> @@ -121,7 +121,7 @@ void slurp_quoted_comment_aware<span class="Delimiter">(</span>istream& in<s <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> - 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> + while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<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> if <span class="Delimiter">(</span>c == <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> diff --git a/html/020run.cc.html b/html/020run.cc.html index 38ffeb73..e5ee3061 100644 --- a/html/020run.cc.html +++ b/html/020run.cc.html @@ -104,9 +104,7 @@ void run_current_routine<span class="Delimiter">()</span> raise_error << <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> put<span class="Delimiter">(</span>Memory<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> - <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> + <span class="Comment">// read all ingredients from memory, each potentially spanning multiple locations</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> @@ -115,7 +113,7 @@ void run_current_routine<span class="Delimiter">()</span> <span class="CommentedCode">//? Locations_read_by_instruction[current_instruction().name] += SIZE(ingredients.back());</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> - <span class="Comment">// Instructions below will write to 'products'.</span> + <span class="Comment">// instructions below will write to 'products'</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> @@ -191,14 +189,14 @@ if <span class="Delimiter">(</span>argc > <span class="Constant">1</span><spa <span class="Delimiter">}</span> transform_all<span class="Delimiter">();</span> <span class="CommentedCode">//? dump_recipe("handle-keyboard-event"), exit(0);</span> - if <span class="Delimiter">(</span>Run_tests<span class="Delimiter">)</span> Recipe<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> string<span class="Delimiter">(</span><span class="Constant">"main"</span><span class="Delimiter">)));</span> + if <span class="Delimiter">(</span>Run_tests<span class="Delimiter">)</span> Recipe<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"main"</span><span class="Delimiter">));</span> <span class="Comment">// End Loading .mu Files</span> <span class="Delimiter">}</span> <span class="Comment">//: Step 3: if we aren't running tests, locate a recipe called 'main' and</span> <span class="Comment">//: start running it.</span> <span class="Delimiter">:(before "End Main")</span> -if <span class="Delimiter">(</span>!Run_tests && contains_key<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> string<span class="Delimiter">(</span><span class="Constant">"main"</span><span class="Delimiter">))</span> && contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> string<span class="Delimiter">(</span><span class="Constant">"main"</span><span class="Delimiter">))))</span> <span class="Delimiter">{</span> +if <span class="Delimiter">(</span>!Run_tests && contains_key<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"main"</span><span class="Delimiter">)</span> && contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"main"</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span> setup<span class="Delimiter">();</span> <span class="CommentedCode">//? Trace_file = "interactive";</span> <span class="CommentedCode">//? START_TRACING_UNTIL_END_OF_SCOPE;</span> @@ -209,7 +207,7 @@ if <span class="Delimiter">(</span>!Run_tests && contains_key<span class <span class="Delimiter">:(code)</span> void run_main<span class="Delimiter">(</span>int argc<span class="Delimiter">,</span> char* argv[]<span class="Delimiter">)</span> <span class="Delimiter">{</span> - recipe_ordinal r = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> string<span class="Delimiter">(</span><span class="Constant">"main"</span><span class="Delimiter">));</span> + recipe_ordinal r = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"main"</span><span class="Delimiter">);</span> if <span class="Delimiter">(</span>r<span class="Delimiter">)</span> run<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Delimiter">}</span> diff --git a/html/021check_instruction.cc.html b/html/021check_instruction.cc.html index e203a386..585c2c3a 100644 --- a/html/021check_instruction.cc.html +++ b/html/021check_instruction.cc.html @@ -42,7 +42,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment">//: sophisticated layer system I'd introduce the simpler version first and</span> <span class="Comment">//: transform it in a separate layer or set of layers.</span> -<span class="Delimiter">:(after "Transform.push_back(update_instruction_operations)")</span> +<span class="Delimiter">:(before "End Checks")</span> Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_instruction<span class="Delimiter">);</span> <span class="Comment">// idempotent</span> <span class="Delimiter">:(code)</span> @@ -61,7 +61,7 @@ void check_instruction<span class="Delimiter">(</span>const recipe_ordinal r<spa <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>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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> + if <span class="Delimiter">(</span>!types_coercible<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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> raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"can't copy "</span> << inst<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> << inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="Constant">"; types don't match</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">goto</span> finish_checking_instruction<span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -106,57 +106,78 @@ recipe main [ ] <span class="traceContains">+error: main: can't copy 34 to 1:address:number; types don't match</span> +<span class="Delimiter">:(scenario write_address_to_number_allowed)</span> +<span class="Special">% Hide_errors = true;</span> +recipe main [ + <span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">12</span>/unsafe + <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:address:number +] +<span class="traceContains">+mem: storing 12 in location 2</span> +$error: <span class="Constant">0</span> + <span class="Delimiter">:(code)</span> -bool types_match<span class="Delimiter">(</span>reagent lhs<span class="Delimiter">,</span> reagent rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span> +<span class="Comment">// types_match with some leniency</span> +bool types_coercible<span class="Delimiter">(</span>const reagent& lhs<span class="Delimiter">,</span> const reagent& rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">,</span> rhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>rhs<span class="Delimiter">)</span> && is_mu_number<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + <span class="Comment">// End types_coercible Special-cases</span> + <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +bool types_match<span class="Delimiter">(</span>const reagent& lhs<span class="Delimiter">,</span> const reagent& rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Comment">// to sidestep type-checking, use /unsafe in the source.</span> + <span class="Comment">// this will be highlighted in red inside vim. just for setting up some tests.</span> + if <span class="Delimiter">(</span>is_unsafe<span class="Delimiter">(</span>rhs<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>rhs<span class="Delimiter">))</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>is_mu_array<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Comment">// End Matching Types For Literal(lhs)</span> + <span class="Comment">// allow writing 0 to any address</span> + if <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> rhs<span class="Delimiter">.</span>name == <span class="Constant">"0"</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!lhs<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"boolean"</span><span class="Delimiter">))</span> + <span class="Identifier">return</span> boolean_matches_literal<span class="Delimiter">(</span>lhs<span class="Delimiter">,</span> rhs<span class="Delimiter">);</span> + <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>lhs<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">;</span> <span class="Comment">// literals are always scalars</span> + <span class="Delimiter">}</span> + <span class="Identifier">return</span> types_strictly_match<span class="Delimiter">(</span>lhs<span class="Delimiter">,</span> rhs<span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +bool boolean_matches_literal<span class="Delimiter">(</span>const reagent& lhs<span class="Delimiter">,</span> const reagent& rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>rhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!lhs<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"boolean"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Identifier">return</span> rhs<span class="Delimiter">.</span>name == <span class="Constant">"0"</span> || rhs<span class="Delimiter">.</span>name == <span class="Constant">"1"</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +<span class="Comment">// copy arguments because later layers will want to make changes to them</span> +<span class="Comment">// without perturbing the caller</span> +bool types_strictly_match<span class="Delimiter">(</span>reagent lhs<span class="Delimiter">,</span> reagent rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>rhs<span class="Delimiter">)</span> && lhs<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + <span class="Comment">// to sidestep type-checking, use /unsafe in the source.</span> + <span class="Comment">// this will be highlighted in red inside vim. just for setting up some tests.</span> + if <span class="Delimiter">(</span>is_unsafe<span class="Delimiter">(</span>rhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Comment">// '_' never raises type error</span> if <span class="Delimiter">(</span>is_dummy<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Comment">// to sidestep type-checking, use /raw in the source.</span> - <span class="Comment">// this is unsafe, and will be highlighted in red inside vim. just for some tests.</span> - if <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>rhs<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>rhs<span class="Delimiter">))</span> <span class="Identifier">return</span> valid_type_for_literal<span class="Delimiter">(</span>lhs<span class="Delimiter">,</span> rhs<span class="Delimiter">)</span> && size_of<span class="Delimiter">(</span>rhs<span class="Delimiter">)</span> == size_of<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span> if <span class="Delimiter">(</span>!lhs<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span> !rhs<span class="Delimiter">.</span>type<span class="Delimiter">;</span> - <span class="Identifier">return</span> types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">,</span> rhs<span class="Delimiter">.</span>type<span class="Delimiter">);</span> -<span class="Delimiter">}</span> - -bool valid_type_for_literal<span class="Delimiter">(</span>const reagent& lhs<span class="Delimiter">,</span> const reagent& literal_rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span> - if <span class="Delimiter">(</span>is_mu_array<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Comment">// End valid_type_for_literal Special-cases</span> - <span class="Comment">// allow writing 0 to any address</span> - if <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> literal_rhs<span class="Delimiter">.</span>name == <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="Identifier">return</span> types_strictly_match<span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">,</span> rhs<span class="Delimiter">.</span>type<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Comment">// two types match if the second begins like the first</span> <span class="Comment">// (trees perform the same check recursively on each subtree)</span> -bool types_match<span class="Delimiter">(</span>type_tree* lhs<span class="Delimiter">,</span> type_tree* rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span> +bool types_strictly_match<span class="Delimiter">(</span>type_tree* lhs<span class="Delimiter">,</span> type_tree* rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span> if <span class="Delimiter">(</span>!lhs<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> - if <span class="Delimiter">(</span>!rhs || rhs<span class="Delimiter">-></span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - if <span class="Delimiter">(</span>lhs<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <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>lhs<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>rhs<span class="Delimiter">)</span> == size_of<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span> - <span class="Delimiter">}</span> - if <span class="Delimiter">(</span>lhs<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"character"</span><span class="Delimiter">)</span> && rhs<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> - if <span class="Delimiter">(</span>lhs<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">)</span> && rhs<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"character"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!rhs<span class="Delimiter">)</span> <span class="Identifier">return</span> lhs<span class="Delimiter">-></span>value == <span class="Constant">0</span><span class="Delimiter">;</span> if <span class="Delimiter">(</span>lhs<span class="Delimiter">-></span>value != rhs<span class="Delimiter">-></span>value<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Identifier">return</span> types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">-></span>left<span class="Delimiter">,</span> rhs<span class="Delimiter">-></span>left<span class="Delimiter">)</span> && types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">-></span>right<span class="Delimiter">,</span> rhs<span class="Delimiter">-></span>right<span class="Delimiter">);</span> -<span class="Delimiter">}</span> - -<span class="Comment">// hacky version that allows 0 addresses</span> -bool types_match<span class="Delimiter">(</span>const reagent lhs<span class="Delimiter">,</span> const type_tree* rhs<span class="Delimiter">,</span> const vector<double>& data<span class="Delimiter">)</span> <span class="Delimiter">{</span> - if <span class="Delimiter">(</span>is_dummy<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> - if <span class="Delimiter">(</span>rhs<span class="Delimiter">-></span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - if <span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <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>lhs<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> scalar<span class="Delimiter">(</span>data<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="Constant">0</span><span class="Delimiter">;</span> - <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>rhs<span class="Delimiter">)</span> == size_of<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span> - <span class="Delimiter">}</span> - if <span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value != rhs<span class="Delimiter">-></span>value<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Identifier">return</span> types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">,</span> rhs<span class="Delimiter">-></span>left<span class="Delimiter">)</span> && types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">,</span> rhs<span class="Delimiter">-></span>right<span class="Delimiter">);</span> + <span class="Identifier">return</span> types_strictly_match<span class="Delimiter">(</span>lhs<span class="Delimiter">-></span>left<span class="Delimiter">,</span> rhs<span class="Delimiter">-></span>left<span class="Delimiter">)</span> && types_strictly_match<span class="Delimiter">(</span>lhs<span class="Delimiter">-></span>right<span class="Delimiter">,</span> rhs<span class="Delimiter">-></span>right<span class="Delimiter">);</span> <span class="Delimiter">}</span> bool is_raw<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> has_property<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">"raw"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> +bool is_unsafe<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Identifier">return</span> has_property<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">"unsafe"</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> if <span class="Delimiter">(</span>!r<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</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> <span class="Constant">false</span><span class="Delimiter">;</span> diff --git a/html/029tools.cc.html b/html/029tools.cc.html index 4f5242fe..4b78fe12 100644 --- a/html/029tools.cc.html +++ b/html/029tools.cc.html @@ -72,7 +72,7 @@ case TRACE: <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="Comment">//: simpler limited version of 'trace'</span> <span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> STASH<span class="Delimiter">,</span> @@ -117,9 +117,8 @@ string print_mu<span class="Delimiter">(</span>const reagent& r<span class=" <span class="Identifier">return</span> r<span class="Delimiter">.</span>name+<span class="Constant">' '</span><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> + 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> out << no_scientific<span class="Delimiter">(</span>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> diff --git a/html/030container.cc.html b/html/030container.cc.html index 403c6a60..8ef0dda6 100644 --- a/html/030container.cc.html +++ b/html/030container.cc.html @@ -16,7 +16,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } .traceContains { color: #008000; } .SalientComment { color: #00ffff; } .cSpecial { color: #008000; } -.traceAbsent { color: #c00000; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } @@ -191,11 +190,12 @@ case GET: <span class="Delimiter">{</span> raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"invalid offset "</span> << offset_value << <span class="Constant">" for "</span> << get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> 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> + if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span> reagent product = inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> <span class="Comment">// Update GET product in Check</span> const reagent element = element_type<span class="Delimiter">(</span>base<span class="Delimiter">,</span> offset_value<span class="Delimiter">);</span> - if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span> - raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'get' "</span> << offset<span class="Delimiter">.</span>original_string << <span class="Constant">" ("</span> << offset_value << <span class="Constant">") on "</span> << get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name << <span class="Constant">" can't be saved in "</span> << product<span class="Delimiter">.</span>original_string << <span class="Constant">"; type should be "</span> << debug_string<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="Constant">" but is "</span> << debug_string<span class="Delimiter">(</span>product<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>!types_coercible<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span> + raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'get "</span> << base<span class="Delimiter">.</span>original_string << <span class="Constant">", "</span> << offset<span class="Delimiter">.</span>original_string << <span class="Constant">"' should write to "</span> << debug_string<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="Constant">" but "</span> << product<span class="Delimiter">.</span>name << <span class="Constant">" has type "</span> << debug_string<span class="Delimiter">(</span>product<span class="Delimiter">.</span>type<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="Identifier">break</span><span class="Delimiter">;</span> @@ -275,7 +275,17 @@ recipe main [ <span class="Constant">14</span>:number<span class="Special"> <- </span>copy <span class="Constant">36</span> <span class="Constant">15</span>:address:number<span class="Special"> <- </span>get <span class="Constant">12</span>:point-number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">1</span>:offset ] -<span class="traceContains">+error: main: 'get' 1:offset (1) on point-number can't be saved in 15:address:number; type should be number but is <address : <number : <>>></span> +<span class="traceContains">+error: main: 'get 12:point-number/raw, 1:offset' should write to number but 15 has type <address : <number : <>>></span> + +<span class="Comment">//: we might want to call 'get' without saving the results, say in a sandbox</span> + +<span class="Delimiter">:(scenario get_without_product)</span> +recipe main [ + <span class="Constant">12</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> + <span class="Constant">13</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span> + get <span class="Constant">12</span>:point/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">1</span>:offset <span class="Comment"># unsafe</span> +] +<span class="Comment"># just don't die</span> <span class="SalientComment">//:: To write to elements of containers, you need their address.</span> @@ -326,8 +336,8 @@ case GET_ADDRESS: <span class="Delimiter">{</span> reagent element = element_type<span class="Delimiter">(</span>base<span class="Delimiter">,</span> offset_value<span class="Delimiter">);</span> <span class="Comment">// ..except for an address at the start</span> element<span class="Delimiter">.</span>type = new type_tree<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">),</span> element<span class="Delimiter">.</span>type<span class="Delimiter">);</span> - if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span> - raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'get-address' "</span> << offset<span class="Delimiter">.</span>original_string << <span class="Constant">" ("</span> << offset_value << <span class="Constant">") on "</span> << get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name << <span class="Constant">" can't be saved in "</span> << product<span class="Delimiter">.</span>original_string << <span class="Constant">"; type should be "</span> << debug_string<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>!types_coercible<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span> + raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'get-address "</span> << base<span class="Delimiter">.</span>original_string << <span class="Constant">", "</span> << offset<span class="Delimiter">.</span>original_string << <span class="Constant">"' should write to "</span> << debug_string<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="Constant">" but "</span> << product<span class="Delimiter">.</span>name << <span class="Constant">" has type "</span> << debug_string<span class="Delimiter">(</span>product<span class="Delimiter">.</span>type<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="Identifier">break</span><span class="Delimiter">;</span> @@ -377,13 +387,16 @@ recipe main [ <span class="Delimiter">:(scenario get_address_product_type_mismatch)</span> <span class="Special">% Hide_errors = true;</span> +container boolbool [ + x:boolean + y:boolean +] recipe main [ - <span class="Constant">12</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</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">15</span>:number<span class="Special"> <- </span>get-address <span class="Constant">12</span>:point-number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">1</span>:offset + <span class="Constant">12</span>:boolean<span class="Special"> <- </span>copy <span class="Constant">1</span> + <span class="Constant">13</span>:boolean<span class="Special"> <- </span>copy <span class="Constant">0</span> + <span class="Constant">15</span>:boolean<span class="Special"> <- </span>get-address <span class="Constant">12</span>:boolbool<span class="Delimiter">,</span> <span class="Constant">1</span>:offset ] -<span class="traceContains">+error: main: 'get-address' 1:offset (1) on point-number can't be saved in 15:number; type should be <address : <number : <>>></span> +<span class="traceContains">+error: main: 'get-address 12:boolbool, 1:offset' should write to <address : <boolean : <>>> but 15 has type boolean</span> <span class="SalientComment">//:: Allow containers to be defined in mu code.</span> @@ -439,7 +452,7 @@ void insert_container<span class="Delimiter">(</span>const string& command<s recently_added_types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">));</span> info<span class="Delimiter">.</span>name = name<span class="Delimiter">;</span> info<span class="Delimiter">.</span>kind = kind<span class="Delimiter">;</span> - while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + while <span class="Delimiter">(</span>has_data<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> string element = next_word<span class="Delimiter">(</span>in<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> @@ -448,7 +461,7 @@ void insert_container<span class="Delimiter">(</span>const string& command<s info<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">9993</span><span class="Delimiter">,</span> <span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">" element name: "</span> << info<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>back<span class="Delimiter">()</span> << end<span class="Delimiter">();</span> type_tree* new_type = <span class="Constant">NULL</span><span class="Delimiter">;</span> - for <span class="Delimiter">(</span>type_tree** curr_type = &new_type<span class="Delimiter">;</span> !inner<span class="Delimiter">.</span>eof<span class="Delimiter">();</span> curr_type = &<span class="Delimiter">(</span>*curr_type<span class="Delimiter">)-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>type_tree** curr_type = &new_type<span class="Delimiter">;</span> has_data<span class="Delimiter">(</span>inner<span class="Delimiter">);</span> curr_type = &<span class="Delimiter">(</span>*curr_type<span class="Delimiter">)-></span>right<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="Comment">// End insert_container Special Uses(type_name)</span> if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type_name<span class="Delimiter">)</span> @@ -535,22 +548,23 @@ recipe main [ <span class="Comment"># integer is not a type</span> <span class="Constant">1</span>:integer<span class="Special"> <- </span>copy <span class="Constant">0</span> ] -<span class="traceContains">+error: main: unknown type in '1:integer <- copy 0'</span> +<span class="traceContains">+error: main: unknown type integer in '1:integer <- copy 0'</span> <span class="Delimiter">:(scenario run_allows_type_definition_after_use)</span> <span class="Special">% Hide_errors = true;</span> recipe main [ - <span class="Constant">1</span>:bar<span class="Special"> <- </span>copy <span class="Constant">0</span>/<span class="Special">raw</span> + <span class="Constant">1</span>:bar<span class="Special"> <- </span>copy <span class="Constant">0</span>/unsafe ] container bar [ x:number ] -<span class="traceAbsent">-error: unknown type: bar</span> $error: <span class="Constant">0</span> -<span class="Delimiter">:(after "Begin Transforms")</span> +<span class="Delimiter">:(after "Begin Instruction Modifying Transforms")</span> +<span class="Comment">// Begin Type Modifying Transforms</span> Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_or_set_invalid_types<span class="Delimiter">);</span> <span class="Comment">// idempotent</span> +<span class="Comment">// End Type Modifying Transforms</span> <span class="Delimiter">:(code)</span> void check_or_set_invalid_types<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -578,8 +592,10 @@ void check_or_set_invalid_types<span class="Delimiter">(</span>type_tree* type<s if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">))</span> <span class="Delimiter">{</span> if <span class="Delimiter">(</span>type_name && contains_key<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type_name<span class="Delimiter">-></span>value<span class="Delimiter">))</span> type<span class="Delimiter">-></span>value = get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type_name<span class="Delimiter">-></span>value<span class="Delimiter">);</span> + else if <span class="Delimiter">(</span>type_name<span class="Delimiter">)</span> + raise_error << block << <span class="Constant">"unknown type "</span> << type_name<span class="Delimiter">-></span>value << <span class="Constant">" in "</span> << name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> else - raise_error << block << <span class="Constant">"unknown type in "</span> << name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + raise_error << block << <span class="Constant">"missing type in "</span> << name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> check_or_set_invalid_types<span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">,</span> type_name ? type_name<span class="Delimiter">-></span>left : <span class="Constant">NULL</span><span class="Delimiter">,</span> block<span class="Delimiter">,</span> name<span class="Delimiter">);</span> check_or_set_invalid_types<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">,</span> type_name ? type_name<span class="Delimiter">-></span>right : <span class="Constant">NULL</span><span class="Delimiter">,</span> block<span class="Delimiter">,</span> name<span class="Delimiter">);</span> diff --git a/html/031address.cc.html b/html/031address.cc.html index f2b0e28f..5a58fc2f 100644 --- a/html/031address.cc.html +++ b/html/031address.cc.html @@ -38,7 +38,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">:(scenario copy_indirect)</span> recipe main [ - <span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">2</span>/<span class="Special">raw</span> + <span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">2</span>/unsafe <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> <span class="Comment"># This loads location 1 as an address and looks up *that* location.</span> <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:address:number/lookup @@ -52,7 +52,7 @@ canonize<span class="Delimiter">(</span>x<span class="Delimiter">);</span> <span class="Comment">//: 'lookup' property</span> <span class="Delimiter">:(scenario store_indirect)</span> recipe main [ - <span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">2</span>/<span class="Special">raw</span> + <span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">2</span>/unsafe <span class="Constant">1</span>:address:number/lookup<span class="Special"> <- </span>copy <span class="Constant">34</span> ] <span class="traceContains">+mem: storing 34 in location 2</span> @@ -96,7 +96,7 @@ void lookup_memory<span class="Delimiter">(</span>reagent& x<span class="Del drop_one_lookup<span class="Delimiter">(</span>x<span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Delimiter">:(after "bool types_match(reagent lhs, reagent rhs)")</span> +<span class="Delimiter">:(after "bool types_strictly_match(reagent lhs, reagent rhs)")</span> if <span class="Delimiter">(</span>!canonize_type<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> if <span class="Delimiter">(</span>!canonize_type<span class="Delimiter">(</span>rhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> @@ -161,7 +161,7 @@ recipe main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">2</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>:address:number<span class="Special"> <- </span>copy <span class="Constant">5</span>/<span class="Special">raw</span> + <span class="Constant">4</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">5</span>/unsafe *<span class="Constant">4</span>:address:number<span class="Special"> <- </span>get <span class="Constant">1</span>:address:point/lookup<span class="Delimiter">,</span> <span class="Constant">0</span>:offset ] <span class="traceContains">+mem: storing 34 in location 5</span> @@ -203,7 +203,7 @@ canonize<span class="Delimiter">(</span>base<span class="Delimiter">);</span> <span class="Delimiter">:(scenario lookup_abbreviation)</span> recipe main [ - <span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">2</span>/<span class="Special">raw</span> + <span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">2</span>/unsafe <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">1</span>:address:number ] diff --git a/html/032array.cc.html b/html/032array.cc.html index 8c0ce105..d2689076 100644 --- a/html/032array.cc.html +++ b/html/032array.cc.html @@ -119,7 +119,7 @@ recipe main [ <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="Special">raw</span> + <span class="Constant">5</span>:address:array:number<span class="Special"> <- </span>copy <span class="Constant">1</span>/unsafe <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> @@ -194,7 +194,7 @@ case INDEX: <span class="Delimiter">{</span> canonize_type<span class="Delimiter">(</span>product<span class="Delimiter">);</span> reagent element<span class="Delimiter">;</span> element<span class="Delimiter">.</span>type = new type_tree<span class="Delimiter">(</span>*array_element<span class="Delimiter">(</span>base<span class="Delimiter">.</span>type<span class="Delimiter">));</span> - if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!types_coercible<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'index' on "</span> << base<span class="Delimiter">.</span>original_string << <span class="Constant">" can't be saved in "</span> << product<span class="Delimiter">.</span>original_string << <span class="Constant">"; type should be "</span> << debug_string<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<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> @@ -238,7 +238,7 @@ recipe main [ <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="Special">raw</span> + <span class="Constant">5</span>:address:array:number<span class="Special"> <- </span>copy <span class="Constant">1</span>/unsafe <span class="Constant">6</span>:number<span class="Special"> <- </span>index *<span class="Constant">5</span>:address:array:number<span class="Delimiter">,</span> <span class="Constant">1</span> ] <span class="traceContains">+mem: storing 15 in location 6</span> @@ -268,7 +268,7 @@ recipe main [ <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="Special">raw</span> + <span class="Constant">8</span>:address:array:point<span class="Special"> <- </span>copy <span class="Constant">1</span>/unsafe index *<span class="Constant">8</span>:address:array:point<span class="Delimiter">,</span> -<span class="Constant">1</span> ] <span class="traceContains">+error: main: invalid index -1</span> @@ -283,11 +283,23 @@ recipe main [ <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="Special">raw</span> + <span class="Constant">8</span>:address:array:point<span class="Special"> <- </span>copy <span class="Constant">1</span>/unsafe <span class="Constant">9</span>:number<span class="Special"> <- </span>index *<span class="Constant">8</span>:address:array:point<span class="Delimiter">,</span> <span class="Constant">0</span> ] <span class="traceContains">+error: main: 'index' on *8:address:array:point can't be saved in 9:number; type should be point</span> +<span class="Comment">//: we might want to call 'index' without saving the results, say in a sandbox</span> + +<span class="Delimiter">:(scenario index_without_product)</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> + index <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">0</span> +] +<span class="Comment"># just don't die</span> + <span class="SalientComment">//:: To write to elements of containers, you need their address.</span> <span class="Delimiter">:(scenario index_address)</span> @@ -322,7 +334,7 @@ case INDEX_ADDRESS: <span class="Delimiter">{</span> reagent element<span class="Delimiter">;</span> element<span class="Delimiter">.</span>type = new type_tree<span class="Delimiter">(</span>*array_element<span class="Delimiter">(</span>base<span class="Delimiter">.</span>type<span class="Delimiter">));</span> element<span class="Delimiter">.</span>type = new type_tree<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">),</span> element<span class="Delimiter">.</span>type<span class="Delimiter">);</span> - if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!types_coercible<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'index' on "</span> << base<span class="Delimiter">.</span>original_string << <span class="Constant">" can't be saved in "</span> << product<span class="Delimiter">.</span>original_string << <span class="Constant">"; type should be "</span> << debug_string<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<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> @@ -376,7 +388,7 @@ recipe main [ <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="Special">raw</span> + <span class="Constant">8</span>:address:array:point<span class="Special"> <- </span>copy <span class="Constant">1</span>/unsafe index-address *<span class="Constant">8</span>:address:array:point<span class="Delimiter">,</span> -<span class="Constant">1</span> ] <span class="traceContains">+error: main: invalid index -1</span> @@ -391,7 +403,7 @@ recipe main [ <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="Special">raw</span> + <span class="Constant">8</span>:address:array:point<span class="Special"> <- </span>copy <span class="Constant">1</span>/unsafe <span class="Constant">9</span>:address:number<span class="Special"> <- </span>index-address *<span class="Constant">8</span>:address:array:point<span class="Delimiter">,</span> <span class="Constant">0</span> ] <span class="traceContains">+error: main: 'index' on *8:address:array:point can't be saved in 9:address:number; type should be <address : <point : <>>></span> @@ -445,6 +457,18 @@ case LENGTH: <span class="Delimiter">{</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> + +<span class="Comment">//: a particularly common array type is the string, or address:array:character</span> +<span class="Delimiter">:(code)</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> x<span class="Delimiter">.</span>type + && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">)</span> + && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right + && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">)</span> + && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right + && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"character"</span><span class="Delimiter">)</span> + && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right == <span class="Constant">NULL</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> </pre> </body> </html> diff --git a/html/035call_ingredient.cc.html b/html/035call_ingredient.cc.html index ff46da6f..34c4c270 100644 --- a/html/035call_ingredient.cc.html +++ b/html/035call_ingredient.cc.html @@ -55,7 +55,7 @@ recipe f [ <span class="Delimiter">:(before "End call Fields")</span> vector<vector<double> > ingredient_atoms<span class="Delimiter">;</span> -vector<type_tree*> ingredient_types<span class="Delimiter">;</span> +vector<reagent> ingredients<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> @@ -65,12 +65,7 @@ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</ current_call<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> reagent ingredient = call_instruction<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> canonize_type<span class="Delimiter">(</span>ingredient<span class="Delimiter">);</span> - current_call<span class="Delimiter">().</span>ingredient_types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>ingredient<span class="Delimiter">.</span>type<span class="Delimiter">);</span> - ingredient<span class="Delimiter">.</span>type = <span class="Constant">NULL</span><span class="Delimiter">;</span> <span class="Comment">// release long-lived pointer</span> -<span class="Delimiter">}</span> -<span class="Delimiter">:(before "End call Destructor")</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>ingredient_types<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - delete ingredient_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> + current_call<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>ingredient<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> @@ -97,10 +92,10 @@ case NEXT_INGREDIENT: <span class="Delimiter">{</span> if <span class="Delimiter">(</span>!is_mu_string<span class="Delimiter">(</span>product<span class="Delimiter">))</span> raise_error << <span class="Constant">"main: wrong type for ingredient "</span> << product<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> - else if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>product<span class="Delimiter">,</span> - current_call<span class="Delimiter">().</span>ingredient_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">),</span> - current_call<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>at<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">)))</span> <span class="Delimiter">{</span> + else if <span class="Delimiter">(</span>!types_coercible<span class="Delimiter">(</span>product<span class="Delimiter">,</span> + current_call<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">)))</span> <span class="Delimiter">{</span> raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"wrong type for ingredient "</span> << product<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Comment">// End next-ingredient Type Mismatch Error</span> <span class="Delimiter">}</span> products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span> current_call<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>at<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">));</span> diff --git a/html/036call_reply.cc.html b/html/036call_reply.cc.html index 45622e07..1784c8f9 100644 --- a/html/036call_reply.cc.html +++ b/html/036call_reply.cc.html @@ -73,13 +73,14 @@ case REPLY: <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>caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - if <span class="Delimiter">(</span>!types_match<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> reply_inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!types_coercible<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> reply_inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span> raise_error << maybe<span class="Delimiter">(</span>callee<span class="Delimiter">)</span> << <span class="Constant">"reply ingredient "</span> << reply_inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="Constant">" can't be saved in "</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> reagent lhs = reply_inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> canonize_type<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span> reagent rhs = caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> canonize_type<span class="Delimiter">(</span>rhs<span class="Delimiter">);</span> raise_error << debug_string<span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="Constant">" vs "</span> << debug_string<span class="Delimiter">(</span>rhs<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Comment">// End reply Type Mismatch Error</span> <span class="Identifier">goto</span> finish_reply<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> diff --git a/html/038scheduler.cc.html b/html/038scheduler.cc.html index 16b3efbb..56396b68 100644 --- a/html/038scheduler.cc.html +++ b/html/038scheduler.cc.html @@ -146,7 +146,7 @@ Current_routine = <span class="Constant">NULL</span><span class="Delimiter">;</s <span class="Comment">//: special case for the very first routine</span> <span class="Delimiter">:(replace{} "void run_main(int argc, char* argv[])")</span> void run_main<span class="Delimiter">(</span>int argc<span class="Delimiter">,</span> char* argv[]<span class="Delimiter">)</span> <span class="Delimiter">{</span> - recipe_ordinal r = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> string<span class="Delimiter">(</span><span class="Constant">"main"</span><span class="Delimiter">));</span> + recipe_ordinal r = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"main"</span><span class="Delimiter">);</span> if <span class="Delimiter">(</span>r<span class="Delimiter">)</span> <span class="Delimiter">{</span> routine* main_routine = new routine<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// Update main_routine</span> @@ -200,8 +200,7 @@ case START_RUNNING: <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> reagent ingredient = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> canonize_type<span class="Delimiter">(</span>ingredient<span class="Delimiter">);</span> - new_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>ingredient<span class="Delimiter">.</span>type<span class="Delimiter">);</span> - ingredient<span class="Delimiter">.</span>type = <span class="Constant">NULL</span><span class="Delimiter">;</span> <span class="Comment">// release long-lived pointer</span> + new_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>ingredient<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> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> diff --git a/html/040brace.cc.html b/html/040brace.cc.html index 6f994e22..a65f6e0f 100644 --- a/html/040brace.cc.html +++ b/html/040brace.cc.html @@ -65,7 +65,7 @@ recipe main [ <span class="traceContains">+transform: jump 1:offset</span> <span class="traceContains">+transform: copy ...</span> -<span class="Delimiter">:(after "Begin Transforms")</span> +<span class="Delimiter">:(before "End Instruction Modifying Transforms")</span> Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>transform_braces<span class="Delimiter">);</span> <span class="Comment">// idempotent</span> <span class="Delimiter">:(code)</span> diff --git a/html/041jump_target.cc.html b/html/041jump_target.cc.html index e85829db..341cf3c2 100644 --- a/html/041jump_target.cc.html +++ b/html/041jump_target.cc.html @@ -52,7 +52,7 @@ recipe main [ <span class="Delimiter">:(before "End Mu Types Initialization")</span> put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"label"</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> -<span class="Delimiter">:(before "Transform.push_back(transform_braces)")</span> +<span class="Delimiter">:(before "End Instruction Modifying Transforms")</span> Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>transform_labels<span class="Delimiter">);</span> <span class="Comment">// idempotent</span> <span class="Delimiter">:(code)</span> diff --git a/html/042name.cc.html b/html/042name.cc.html index da006079..aa0a1fe9 100644 --- a/html/042name.cc.html +++ b/html/042name.cc.html @@ -54,7 +54,7 @@ recipe main [ <span class="traceContains">+error: main: use before set: y</span> <span class="Comment"># todo: detect conditional defines</span> -<span class="Delimiter">:(after "Transform.push_back(check_or_set_invalid_types")</span> <span class="Comment">// there'll be other transforms relating to types; they all need to happen first</span> +<span class="Delimiter">:(before "End Instruction Modifying Transforms")</span> Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>transform_names<span class="Delimiter">);</span> <span class="Comment">// idempotent</span> <span class="Delimiter">:(before "End Globals")</span> @@ -66,31 +66,32 @@ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</ <span class="Delimiter">:(code)</span> void transform_names<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> - trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"--- transform names for recipe "</span> << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name << end<span class="Delimiter">();</span> -<span class="CommentedCode">//? cerr << "--- transform names for recipe " << get(Recipe, r).name << '\n';</span> + recipe& caller = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span> + trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"--- transform names for recipe "</span> << caller<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "--- transform names for recipe " << caller.name << '\n';</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> 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> - for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - instruction& inst = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> + 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<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + instruction& inst = caller<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> <span class="Comment">// End transform_names(inst) Special-cases</span> <span class="Comment">// map names to addresses</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> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">))</span> <span class="Identifier">continue</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> caller<span class="Delimiter">.</span>name<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_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <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="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + raise_error << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <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="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> 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> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">))</span> <span class="Identifier">continue</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> caller<span class="Delimiter">.</span>name<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">9993</span><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> @@ -100,7 +101,7 @@ void transform_names<span class="Delimiter">(</span>const recipe_ordinal r<span <span class="Delimiter">}</span> <span class="Delimiter">}</span> if <span class="Delimiter">(</span>names_used && numeric_locations_used<span class="Delimiter">)</span> - raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"mixing variable names and numeric addresses</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + raise_error << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"mixing variable names and numeric addresses</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<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> const string& recipe_name<span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -240,8 +241,10 @@ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == < 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>type<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<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> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">));</span> - trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"name"</span><span class="Delimiter">)</span> << <span class="Constant">"element "</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">" of type "</span> << get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name << <span class="Constant">" is at offset "</span> << no_scientific<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>value<span class="Delimiter">)</span> << end<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Comment">// otherwise we'll raise an error elsewhere</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> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">));</span> + trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"name"</span><span class="Delimiter">)</span> << <span class="Constant">"element "</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">" of type "</span> << get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name << <span class="Constant">" is at offset "</span> << no_scientific<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>value<span class="Delimiter">)</span> << end<span class="Delimiter">();</span> + <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> @@ -249,8 +252,8 @@ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == < <span class="Delimiter">:(scenarios transform)</span> <span class="Delimiter">:(scenario transform_names_handles_containers)</span> recipe main [ - a:point<span class="Special"> <- </span>copy <span class="Constant">0</span>/<span class="Special">raw</span> - b:number<span class="Special"> <- </span>copy <span class="Constant">0</span>/<span class="Special">raw</span> + a:point<span class="Special"> <- </span>copy <span class="Constant">0</span>/unsafe + b:number<span class="Special"> <- </span>copy <span class="Constant">0</span>/unsafe ] <span class="traceContains">+name: assign a 1</span> <span class="traceContains">+name: assign b 3</span> @@ -279,8 +282,10 @@ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == < 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>type<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<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> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">));</span> - trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"name"</span><span class="Delimiter">)</span> << <span class="Constant">"variant "</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">" of type "</span> << get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name << <span class="Constant">" has tag "</span> << no_scientific<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>value<span class="Delimiter">)</span> << end<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Comment">// otherwise we'll raise an error elsewhere</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> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">));</span> + trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"name"</span><span class="Delimiter">)</span> << <span class="Constant">"variant "</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">" of type "</span> << get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name << <span class="Constant">" has tag "</span> << no_scientific<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>value<span class="Delimiter">)</span> << end<span class="Delimiter">();</span> + <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> </pre> diff --git a/html/043new.cc.html b/html/043new.cc.html index 35398d9f..81a1c1c7 100644 --- a/html/043new.cc.html +++ b/html/043new.cc.html @@ -459,16 +459,6 @@ long long int unicode_length<span class="Delimiter">(</span>const string& s< <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> x<span class="Delimiter">.</span>type - && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">)</span> - && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right - && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">)</span> - && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right - && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"character"</span><span class="Delimiter">)</span> - && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right == <span class="Constant">NULL</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 = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> 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> diff --git a/html/044space.cc.html b/html/044space.cc.html index 0bd414cb..10e456cb 100644 --- a/html/044space.cc.html +++ b/html/044space.cc.html @@ -42,7 +42,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> - default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span>/<span class="Special">raw</span> + default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span>/unsafe <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> @@ -54,8 +54,8 @@ 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> - default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">1000</span>/<span class="Special">raw</span> - <span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">3</span>/<span class="Special">raw</span> + default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">1000</span>/unsafe + <span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">3</span>/unsafe <span class="Constant">8</span>:number/<span class="Special">raw <- </span>copy *<span class="Constant">1</span>:address:number ] <span class="traceContains">+mem: storing 34 in location 8</span> @@ -105,8 +105,8 @@ 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> - default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">1000</span>/<span class="Special">raw</span> - <span class="Constant">1</span>:address:point<span class="Special"> <- </span>copy <span class="Constant">12</span>/<span class="Special">raw</span> + default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">1000</span>/unsafe + <span class="Constant">1</span>:address:point<span class="Special"> <- </span>copy <span class="Constant">12</span>/unsafe <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 ] <span class="traceContains">+mem: storing 35 in location 9</span> @@ -125,8 +125,8 @@ 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> - default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">1000</span>/<span class="Special">raw</span> - <span class="Constant">1</span>:address:array:number<span class="Special"> <- </span>copy <span class="Constant">12</span>/<span class="Special">raw</span> + default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">1000</span>/unsafe + <span class="Constant">1</span>:address:array:number<span class="Special"> <- </span>copy <span class="Constant">12</span>/unsafe <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> ] <span class="traceContains">+mem: storing 35 in location 9</span> @@ -259,7 +259,7 @@ long long int address<span class="Delimiter">(</span>long long int offset<span c <span class="Delimiter">:(scenario get_default_space)</span> recipe main [ - default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span>/<span class="Special">raw</span> + default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span>/unsafe <span class="Constant">1</span>:address:array:location/<span class="Special">raw <- </span>copy default-space:address:array:location ] <span class="traceContains">+mem: storing 10 in location 1</span> diff --git a/html/045space_surround.cc.html b/html/045space_surround.cc.html index da74d215..29d58818 100644 --- a/html/045space_surround.cc.html +++ b/html/045space_surround.cc.html @@ -42,8 +42,8 @@ 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> - default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span>/<span class="Special">raw</span> - <span class="Constant">0</span>:address:array:location/names:dummy<span class="Special"> <- </span>copy <span class="Constant">20</span>/<span class="Special">raw</span> <span class="Comment"># later layers will explain the /names: property</span> + default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span>/unsafe + <span class="Constant">0</span>:address:array:location/names:dummy<span class="Special"> <- </span>copy <span class="Constant">20</span>/unsafe <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> ] diff --git a/html/047global.cc.html b/html/047global.cc.html index da8d790f..b2017a82 100644 --- a/html/047global.cc.html +++ b/html/047global.cc.html @@ -42,8 +42,8 @@ recipe main [ <span class="Constant">10</span>:number<span class="Special"> <- </span>copy <span class="Constant">5</span> <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="Special">raw</span> - default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span>/<span class="Special">raw</span> + global-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">20</span>/unsafe + default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span>/unsafe <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> ] diff --git a/html/048check_type_by_name.cc.html b/html/048check_type_by_name.cc.html index d091ba31..13703a0e 100644 --- a/html/048check_type_by_name.cc.html +++ b/html/048check_type_by_name.cc.html @@ -21,7 +21,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .CommentedCode { color: #6c6c6c; } -.Todo { color: #000000; background-color: #ffff00; padding-bottom: 1px; } --> </style> @@ -49,11 +48,11 @@ recipe main [ ] <span class="traceContains">+error: main: x used with multiple types</span> -<span class="Delimiter">:(before "Transform.push_back(check_or_set_invalid_types)")</span> -Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_types_by_name<span class="Delimiter">);</span> <span class="Comment">// idempotent</span> +<span class="Delimiter">:(after "Begin Instruction Modifying Transforms")</span> +Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_or_set_types_by_name<span class="Delimiter">);</span> <span class="Comment">// idempotent</span> <span class="Delimiter">:(code)</span> -void check_types_by_name<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void check_or_set_types_by_name<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"--- deduce types for recipe "</span> << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name << end<span class="Delimiter">();</span> <span class="CommentedCode">//? cerr << "--- deduce types for recipe " << get(Recipe, r).name << '\n';</span> map<string<span class="Delimiter">,</span> type_tree*> type<span class="Delimiter">;</span> @@ -82,7 +81,6 @@ void deduce_missing_type<span class="Delimiter">(</span>map<string<span class void check_type<span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> type_tree*>& type<span class="Delimiter">,</span> map<string<span class="Delimiter">,</span> string_tree*>& type_name<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">// </span><span class="Todo">TODO</span><span class="Comment">: delete this</span> <span class="Comment">// if you use raw locations you're probably doing something unsafe</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>type<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// will throw a more precise error elsewhere</span> @@ -93,7 +91,7 @@ void check_type<span class="Delimiter">(</span>map<string<span class="Delimit if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>type_name<span class="Delimiter">,</span> x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span> type_name[x<span class="Delimiter">.</span>name] = 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> <span class="Delimiter">}</span> - if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>type[x<span class="Delimiter">.</span>name]<span class="Delimiter">,</span> x<span class="Delimiter">.</span>type<span class="Delimiter">))</span> + if <span class="Delimiter">(</span>!types_strictly_match<span class="Delimiter">(</span>type[x<span class="Delimiter">.</span>name]<span class="Delimiter">,</span> x<span class="Delimiter">.</span>type<span class="Delimiter">))</span> raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << x<span class="Delimiter">.</span>name << <span class="Constant">" used with multiple types</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> @@ -130,7 +128,7 @@ recipe main [ y:address:charcter<span class="Special"> <- </span>new character:type *y<span class="Special"> <- </span>copy <span class="Constant">67</span> ] -<span class="traceContains">+error: main: unknown type in 'y:address:charcter <- new character:type'</span> +<span class="traceContains">+error: main: unknown type charcter in 'y:address:charcter <- new character:type'</span> </pre> </body> </html> diff --git a/html/050scenario.cc.html b/html/050scenario.cc.html index c586b575..523ea59f 100644 --- a/html/050scenario.cc.html +++ b/html/050scenario.cc.html @@ -233,9 +233,13 @@ case RUN: <span class="Delimiter">{</span> case RUN: <span class="Delimiter">{</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> +<span class="CommentedCode">//? cerr << "before load\n";</span> vector<recipe_ordinal> tmp_recipe = load<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>str<span class="Delimiter">());</span> +<span class="CommentedCode">//? cerr << "before bind\n";</span> bind_special_scenario_names<span class="Delimiter">(</span>tmp_recipe<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> +<span class="CommentedCode">//? cerr << "before transform\n";</span> transform_all<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "end\n";</span> if <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span> ++Trace_stream<span class="Delimiter">-></span>callstack_depth<span class="Delimiter">;</span> trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">"trace"</span><span class="Delimiter">)</span> << <span class="Constant">"run: incrementing callstack depth to "</span> << Trace_stream<span class="Delimiter">-></span>callstack_depth << end<span class="Delimiter">();</span> @@ -306,7 +310,7 @@ void check_memory<span class="Delimiter">(</span>const string& s<span class= 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> - if <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>!has_data<span class="Delimiter">(</span>in<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> 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> @@ -341,7 +345,10 @@ void check_memory<span class="Delimiter">(</span>const string& s<span class= 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> - 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>value == <span class="Constant">"string"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + const string_tree* type_name = 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> + if <span class="Delimiter">(</span>type_name<span class="Delimiter">-></span>value == <span class="Constant">"array"</span> + && type_name<span class="Delimiter">-></span>right && type_name<span class="Delimiter">-></span>right<span class="Delimiter">-></span>value == <span class="Constant">"character"</span> + && !type_name<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<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> @@ -362,7 +369,7 @@ void check_string<span class="Delimiter">(</span>long long int address<span clas trace<span class="Delimiter">(</span><span class="Constant">9999</span><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> if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">)</span> != 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_error << <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> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">))</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + raise_error << <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> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">))</span> << <span class="Constant">" ("</span> << read_mu_string<span class="Delimiter">(</span>address<span class="Delimiter">)</span> << <span class="Constant">")</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> else raise_error << <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> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">))</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> if <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -377,7 +384,7 @@ void check_string<span class="Delimiter">(</span>long long int address<span clas if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address+i<span class="Delimiter">)</span> != 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_error << <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> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address+i<span class="Delimiter">))</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + raise_error << <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> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address+i<span class="Delimiter">))</span> << <span class="Constant">" ('"</span> << static_cast<char><span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address+i<span class="Delimiter">))</span> << <span class="Constant">"')</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Delimiter">}</span> else <span class="Delimiter">{</span> <span class="Comment">// just testing scenario support</span> @@ -412,7 +419,7 @@ recipe main [ <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">98</span> <span class="Comment"># 'b'</span> <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">99</span> <span class="Comment"># 'c'</span> memory-should-contain [ - <span class="Constant">1</span>:string<span class="Special"> <- </span>[ab] + <span class="Constant">1</span>:array:character<span class="Special"> <- </span>[ab] ] ] <span class="traceContains">+error: expected location 1 to contain length 2 of string [ab] but saw 3</span> @@ -424,7 +431,7 @@ recipe main [ <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">98</span> <span class="Comment"># 'b'</span> <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">99</span> <span class="Comment"># 'c'</span> memory-should-contain [ - <span class="Constant">1</span>:string<span class="Special"> <- </span>[abc] + <span class="Constant">1</span>:array:character<span class="Special"> <- </span>[abc] ] ] <span class="traceContains">+run: checking string length at 1</span> @@ -467,25 +474,22 @@ case TRACE_SHOULD_CONTAIN: <span class="Delimiter">{</span> <span class="Delimiter">:(code)</span> <span class="Comment">// simplified version of check_trace_contents() that emits errors rather</span> <span class="Comment">// than just printing to stderr</span> -bool check_trace<span class="Delimiter">(</span>const string& expected<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void check_trace<span class="Delimiter">(</span>const string& expected<span class="Delimiter">)</span> <span class="Delimiter">{</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> - 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> + if <span class="Delimiter">(</span>expected_lines<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</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> - 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="Identifier">return</span> <span class="Constant">true</span><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="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> raise_error << <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 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>const string& expected<span class="Delimiter">)</span> <span class="Delimiter">{</span> diff --git a/html/051scenario_test.mu.html b/html/051scenario_test.mu.html index d38539dd..074da198 100644 --- a/html/051scenario_test.mu.html +++ b/html/051scenario_test.mu.html @@ -60,7 +60,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<span class="muScenario">scenario</span> check_string_in_memory [ +<span class="muScenario">scenario</span> check_text_in_memory [ run [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">3</span> <span class="Constant">2</span>:character<span class="Special"> <- </span>copy <span class="Constant">97</span> <span class="Comment"># 'a'</span> @@ -68,7 +68,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant">4</span>:character<span class="Special"> <- </span>copy <span class="Constant">99</span> <span class="Comment"># 'c'</span> ] memory-should-contain [ - <span class="Constant">1</span>:string<span class="Special"> <- </span><span class="Constant">[abc]</span> + <span class="Constant">1</span>:array:character<span class="Special"> <- </span><span class="Constant">[abc]</span> ] ] diff --git a/html/052tangle.cc.html b/html/052tangle.cc.html index 4fc37210..131de37a 100644 --- a/html/052tangle.cc.html +++ b/html/052tangle.cc.html @@ -88,7 +88,7 @@ else if <span class="Delimiter">(</span>command == <span class="Constant">" <span class="Comment">//: after all recipes are loaded, insert fragments at appropriate labels.</span> -<span class="Delimiter">:(after "Begin Transforms")</span> +<span class="Delimiter">:(after "Begin Instruction Inserting/Deleting Transforms")</span> Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>insert_fragments<span class="Delimiter">);</span> <span class="Comment">// NOT idempotent</span> <span class="Comment">//: We might need to perform multiple passes, in case inserted fragments</span> diff --git a/html/053rewrite_stash.cc.html b/html/053rewrite_stash.cc.html new file mode 100644 index 00000000..ba867faf --- /dev/null +++ b/html/053rewrite_stash.cc.html @@ -0,0 +1,85 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> +<html> +<head> +<meta http-equiv="content-type" content="text/html; charset=UTF-8"> +<title>Mu - 053rewrite_stash.cc</title> +<meta name="Generator" content="Vim/7.4"> +<meta name="plugin-version" content="vim7.4_v1"> +<meta name="syntax" content="cpp"> +<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy="> +<meta name="colorscheme" content="minimal"> +<style type="text/css"> +<!-- +pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; } +body { font-family: monospace; color: #eeeeee; background-color: #080808; } +* { font-size: 1.05em; } +.Constant { color: #00a0a0; } +.Comment { color: #9090ff; } +.Delimiter { color: #a04060; } +.Identifier { color: #804000; } +--> +</style> + +<script type='text/javascript'> +<!-- + +--> +</script> +</head> +<body> +<pre id='vimCodeElement'> +<span class="Comment">//: when encountering other types, try to convert them to strings using</span> +<span class="Comment">//: 'to-text'</span> + +<span class="Delimiter">:(before "End Instruction Inserting/Deleting Transforms")</span> +Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>rewrite_stashes_to_text<span class="Delimiter">);</span> + +<span class="Delimiter">:(code)</span> +void rewrite_stashes_to_text<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + recipe& caller = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span> + if <span class="Delimiter">(</span>contains_named_locations<span class="Delimiter">(</span>caller<span class="Delimiter">))</span> + rewrite_stashes_to_text_named<span class="Delimiter">(</span>caller<span class="Delimiter">);</span> + <span class="Comment">// in recipes without named locations, 'stash' is still not configurable</span> +<span class="Delimiter">}</span> + +bool contains_named_locations<span class="Delimiter">(</span>const recipe& caller<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<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + const instruction& inst = caller<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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> + 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> + <span class="Identifier">return</span> <span class="Constant">true</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> + 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> + <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> + +void rewrite_stashes_to_text_named<span class="Delimiter">(</span>recipe& caller<span class="Delimiter">)</span> <span class="Delimiter">{</span> + static long long int stash_instruction_idx = <span class="Constant">0</span><span class="Delimiter">;</span> + vector<instruction> new_instructions<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<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + instruction& inst = caller<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>name == <span class="Constant">"stash"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<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>ingredients<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>is_mu_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + instruction def<span class="Delimiter">;</span> + def<span class="Delimiter">.</span>name = <span class="Constant">"to-text-line"</span><span class="Delimiter">;</span> + def<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">));</span> + ostringstream ingredient_name<span class="Delimiter">;</span> + ingredient_name << <span class="Constant">"stash_"</span> << stash_instruction_idx << <span class="Constant">'_'</span> << j << <span class="Constant">":address:array:character"</span><span class="Delimiter">;</span> + def<span class="Delimiter">.</span>products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span>ingredient_name<span class="Delimiter">.</span>str<span class="Delimiter">()));</span> + new_instructions<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>def<span class="Delimiter">);</span> + inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>clear<span class="Delimiter">();</span> <span class="Comment">// reclaim old memory</span> + inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)</span> = reagent<span class="Delimiter">(</span>ingredient_name<span class="Delimiter">.</span>str<span class="Delimiter">());</span> + <span class="Delimiter">}</span> + <span class="Delimiter">}</span> + new_instructions<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>inst<span class="Delimiter">);</span> + <span class="Delimiter">}</span> + new_instructions<span class="Delimiter">.</span>swap<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> +<span class="Delimiter">}</span> +</pre> +</body> +</html> +<!-- vim: set foldmethod=manual : --> diff --git a/html/054dilated_reagent.cc.html b/html/054dilated_reagent.cc.html index 4f107a15..02f714e4 100644 --- a/html/054dilated_reagent.cc.html +++ b/html/054dilated_reagent.cc.html @@ -15,11 +15,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } .traceContains { color: #008000; } .cSpecial { color: #008000; } +.PreProc { color: #c000c0; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } .Identifier { color: #804000; } .Constant { color: #00a0a0; } +.Error { color: #ffffff; background-color: #ff6060; padding-bottom: 1px; } --> </style> @@ -42,26 +44,32 @@ recipe main [ ] <span class="traceContains">+parse: product: {"1": "number", "foo": "bar"}</span> +<span class="Delimiter">:(scenario load_trailing_space_after_curly_bracket)</span> +recipe main [ +<span class="PreProc"> </span><span class="Comment"># line below has a space at the end</span> + <span class="Delimiter">{</span><span class="Error"> </span> +] +<span class="Comment"># successfully parsed</span> + <span class="Comment">//: First augment next_word to group balanced brackets together.</span> <span class="Delimiter">:(before "End next_word Special-cases")</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="Identifier">return</span> slurp_balanced_bracket<span class="Delimiter">(</span>in<span class="Delimiter">);</span> - <span class="Comment">// treat curlies mostly like parens, but don't mess up labels</span> - if <span class="Delimiter">(</span>start_of_dilated_reagent<span class="Delimiter">(</span>in<span class="Delimiter">))</span> - <span class="Identifier">return</span> slurp_balanced_bracket<span class="Delimiter">(</span>in<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="Identifier">return</span> slurp_balanced_bracket<span class="Delimiter">(</span>in<span class="Delimiter">);</span> +<span class="Comment">// treat curlies mostly like parens, but don't mess up labels</span> +if <span class="Delimiter">(</span>start_of_dilated_reagent<span class="Delimiter">(</span>in<span class="Delimiter">))</span> + <span class="Identifier">return</span> slurp_balanced_bracket<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Delimiter">:(code)</span> <span class="Comment">// A curly is considered a label if it's the last thing on a line. Dilated</span> <span class="Comment">// reagents should remain all on one line.</span> -<span class="Comment">//</span> -<span class="Comment">// Side-effect: This might delete some whitespace after an initial '{'.</span> bool start_of_dilated_reagent<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="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + long long int pos = in<span class="Delimiter">.</span>tellg<span class="Delimiter">();</span> in<span class="Delimiter">.</span>get<span class="Delimiter">();</span> <span class="Comment">// slurp '{'</span> skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span> char next = in<span class="Delimiter">.</span>peek<span class="Delimiter">();</span> - in<span class="Delimiter">.</span>putback<span class="Delimiter">(</span><span class="Constant">'{'</span><span class="Delimiter">);</span> + in<span class="Delimiter">.</span>seekg<span class="Delimiter">(</span>pos<span class="Delimiter">);</span> <span class="Identifier">return</span> next != <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -107,7 +115,7 @@ if <span class="Delimiter">(</span>s<span class="Delimiter">.</span>at<span clas istringstream in<span class="Delimiter">(</span>s<span class="Delimiter">);</span> in >> std::noskipws<span class="Delimiter">;</span> in<span class="Delimiter">.</span>get<span class="Delimiter">();</span> <span class="Comment">// skip '{'</span> - while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span> string key = slurp_key<span class="Delimiter">(</span>in<span class="Delimiter">);</span> if <span class="Delimiter">(</span>key<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> if <span class="Delimiter">(</span>key == <span class="Constant">"}"</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> diff --git a/html/055parse_tree.cc.html b/html/055parse_tree.cc.html index 7d9e158f..14142686 100644 --- a/html/055parse_tree.cc.html +++ b/html/055parse_tree.cc.html @@ -61,7 +61,7 @@ string_tree* parse_string_tree<span class="Delimiter">(</span>const string& string_tree* parse_string_tree<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> - if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">NULL</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="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span> @@ -74,7 +74,7 @@ string_tree* parse_string_tree<span class="Delimiter">(</span>istream& in<sp string_tree* result = <span class="Constant">NULL</span><span class="Delimiter">;</span> string_tree** curr = &result<span class="Delimiter">;</span> while <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> - assert<span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">());</span> + assert<span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">));</span> *curr = new string_tree<span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">);</span> skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span> skip_ignored_characters<span class="Delimiter">(</span>in<span class="Delimiter">);</span> diff --git a/html/056recipe_header.cc.html b/html/056recipe_header.cc.html index 5000a703..a1c6dd82 100644 --- a/html/056recipe_header.cc.html +++ b/html/056recipe_header.cc.html @@ -164,12 +164,12 @@ if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == < recipe add2 x:number<span class="Delimiter">,</span> y:number <span class="Delimiter">-></span> z:number [ local-scope load-ingredients - z:address:number<span class="Special"> <- </span>copy <span class="Constant">0</span>/<span class="Special">raw</span> + z:address:number<span class="Special"> <- </span>copy <span class="Constant">0</span>/unsafe reply z ] <span class="traceContains">+error: add2: replied with the wrong type at 'reply z'</span> -<span class="Delimiter">:(after "Transform.push_back(check_types_by_name)")</span> +<span class="Delimiter">:(before "End Checks")</span> Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_reply_instructions_against_header<span class="Delimiter">);</span> <span class="Comment">// idempotent</span> <span class="Delimiter">:(code)</span> @@ -181,9 +181,7 @@ void check_reply_instructions_against_header<span class="Delimiter">(</span>cons 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_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> const instruction& inst = caller_recipe<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>name != <span class="Constant">"reply"</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>products<span class="Delimiter">)</span> != SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">))</span> - raise_error << maybe<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"tried to reply the wrong number of products 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> - 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_recipe<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>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> raise_error << maybe<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"replied with the wrong type at '"</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="Delimiter">}</span> @@ -202,11 +200,11 @@ recipe add2 x:number<span class="Delimiter">,</span> x:number <span class="Delim <span class="Delimiter">:(before "End recipe Fields")</span> map<string<span class="Delimiter">,</span> int> ingredient_index<span class="Delimiter">;</span> -<span class="Delimiter">:(after "Transform.push_back(insert_fragments)")</span> -Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_and_update_header_reagents<span class="Delimiter">);</span> <span class="Comment">// idempotent</span> +<span class="Delimiter">:(after "Begin Instruction Modifying Transforms")</span> +Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_header_ingredients<span class="Delimiter">);</span> <span class="Comment">// idempotent</span> <span class="Delimiter">:(code)</span> -void check_and_update_header_reagents<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void check_header_ingredients<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> recipe& caller_recipe = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span> if <span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"--- checking reply instructions against header for "</span> << caller_recipe<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span> @@ -232,7 +230,7 @@ recipe add2 x:number<span class="Delimiter">,</span> y:number <span class="Delim ] <span class="traceContains">+mem: storing 8 in location 1</span> -<span class="Delimiter">:(before "Transform.push_back(check_reply_instructions_against_header)")</span> +<span class="Delimiter">:(after "Begin Type Modifying Transforms")</span> Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>deduce_types_from_header<span class="Delimiter">);</span> <span class="Comment">// idempotent</span> <span class="Delimiter">:(code)</span> @@ -299,7 +297,7 @@ recipe add2 x:number<span class="Delimiter">,</span> y:number <span class="Delim ] <span class="traceContains">+mem: storing 8 in location 1</span> -<span class="Delimiter">:(after "Transform.push_back(check_and_update_header_reagents)")</span> +<span class="Delimiter">:(after "Transform.push_back(check_header_ingredients)")</span> Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>fill_in_reply_ingredients<span class="Delimiter">);</span> <span class="Comment">// idempotent</span> <span class="Delimiter">:(code)</span> diff --git a/html/057static_dispatch.cc.html b/html/057static_dispatch.cc.html index 243b9c28..1c7b28b7 100644 --- a/html/057static_dispatch.cc.html +++ b/html/057static_dispatch.cc.html @@ -14,11 +14,13 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background- body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } .traceContains { color: #008000; } -.Identifier { color: #804000; } +.traceAbsent { color: #c00000; } +.cSpecial { color: #008000; } +.CommentedCode { color: #6c6c6c; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } -.CommentedCode { color: #6c6c6c; } +.Identifier { color: #804000; } .Constant { color: #00a0a0; } --> </style> @@ -65,12 +67,11 @@ for <span class="Delimiter">(</span>map<string<span class="Delimiter">,</span <span class="Delimiter">:(before "End Load Recipe Header(result)")</span> if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span> const recipe_ordinal r = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">);</span> -<span class="CommentedCode">//? if (variant_already_exists(result)) cerr << "AAAAAAAAAAAAAAAAAA variant already exists " << result.name << '\n';</span> if <span class="Delimiter">((</span>!contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">)</span> || get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>has_header<span class="Delimiter">)</span> && !variant_already_exists<span class="Delimiter">(</span>result<span class="Delimiter">))</span> <span class="Delimiter">{</span> string new_name = next_unused_recipe_name<span class="Delimiter">(</span>result<span class="Delimiter">.</span>name<span class="Delimiter">);</span> put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> new_name<span class="Delimiter">,</span> Next_recipe_ordinal++<span class="Delimiter">);</span> - get<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> new_name<span class="Delimiter">));</span> + get_or_insert<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> new_name<span class="Delimiter">));</span> result<span class="Delimiter">.</span>name = new_name<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> @@ -82,7 +83,7 @@ else <span class="Delimiter">{</span> <span class="Delimiter">:(code)</span> bool variant_already_exists<span class="Delimiter">(</span>const recipe& rr<span class="Delimiter">)</span> <span class="Delimiter">{</span> - const vector<recipe_ordinal>& variants = get<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> rr<span class="Delimiter">.</span>name<span class="Delimiter">);</span> + const vector<recipe_ordinal>& variants = get_or_insert<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> rr<span class="Delimiter">.</span>name<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>variants<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> && all_reagents_match<span class="Delimiter">(</span>rr<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))))</span> <span class="Delimiter">{</span> @@ -110,11 +111,24 @@ bool all_reagents_match<span class="Delimiter">(</span>const recipe& r1<span <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -bool exact_match<span class="Delimiter">(</span>type_tree* a<span class="Delimiter">,</span> type_tree* b<span class="Delimiter">)</span> <span class="Delimiter">{</span> - if <span class="Delimiter">(</span>a == b<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Globals")</span> +set<string> Literal_type_names<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End One-time Setup")</span> +Literal_type_names<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">"number"</span><span class="Delimiter">);</span> +Literal_type_names<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">"character"</span><span class="Delimiter">);</span> +<span class="Delimiter">:(code)</span> +bool deeply_equal_types<span class="Delimiter">(</span>const string_tree* a<span class="Delimiter">,</span> const string_tree* b<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!a<span class="Delimiter">)</span> <span class="Identifier">return</span> !b<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!b<span class="Delimiter">)</span> <span class="Identifier">return</span> !a<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>a<span class="Delimiter">-></span>value == <span class="Constant">"literal"</span> && b<span class="Delimiter">-></span>value == <span class="Constant">"literal"</span><span class="Delimiter">)</span> + <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>a<span class="Delimiter">-></span>value == <span class="Constant">"literal"</span><span class="Delimiter">)</span> + <span class="Identifier">return</span> Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>b<span class="Delimiter">-></span>value<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>b<span class="Delimiter">-></span>value == <span class="Constant">"literal"</span><span class="Delimiter">)</span> + <span class="Identifier">return</span> Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>a<span class="Delimiter">-></span>value<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">();</span> <span class="Identifier">return</span> a<span class="Delimiter">-></span>value == b<span class="Delimiter">-></span>value - && exact_match<span class="Delimiter">(</span>a<span class="Delimiter">-></span>left<span class="Delimiter">,</span> b<span class="Delimiter">-></span>left<span class="Delimiter">)</span> - && exact_match<span class="Delimiter">(</span>a<span class="Delimiter">-></span>right<span class="Delimiter">,</span> b<span class="Delimiter">-></span>right<span class="Delimiter">);</span> + && deeply_equal_types<span class="Delimiter">(</span>a<span class="Delimiter">-></span>left<span class="Delimiter">,</span> b<span class="Delimiter">-></span>left<span class="Delimiter">)</span> + && deeply_equal_types<span class="Delimiter">(</span>a<span class="Delimiter">-></span>right<span class="Delimiter">,</span> b<span class="Delimiter">-></span>right<span class="Delimiter">);</span> <span class="Delimiter">}</span> string next_unused_recipe_name<span class="Delimiter">(</span>const string& recipe_name<span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -141,32 +155,33 @@ recipe test a:number<span class="Delimiter">,</span> b:number <span class="Delim ] <span class="traceContains">+mem: storing 2 in location 7</span> -<span class="Comment">//: after insert_fragments (tangle) and before computing operation ids</span> <span class="Comment">//: after filling in all missing types (because we'll be introducing 'blank' types in this transform in a later layer, for shape-shifting recipes)</span> -<span class="Delimiter">:(after "Transform.push_back(deduce_types_from_header)")</span> +<span class="Delimiter">:(after "End Type Modifying Transforms")</span> Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>resolve_ambiguous_calls<span class="Delimiter">);</span> <span class="Comment">// idempotent</span> <span class="Delimiter">:(code)</span> void resolve_ambiguous_calls<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> recipe& caller_recipe = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span> trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"--- resolve ambiguous calls for recipe "</span> << caller_recipe<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "--- resolve ambiguous calls for recipe " << caller_recipe.name << '\n';</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>caller_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> instruction& inst = caller_recipe<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>is_label<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - assert<span class="Delimiter">(</span>!get<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">).</span>empty<span class="Delimiter">());</span> + if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">).</span>empty<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> replace_best_variant<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="CommentedCode">//? if (caller_recipe.name == "main") cerr << "=============== " << debug_string(caller_recipe) << '\n';</span> <span class="Delimiter">}</span> void replace_best_variant<span class="Delimiter">(</span>instruction& inst<span class="Delimiter">,</span> const recipe& caller_recipe<span class="Delimiter">)</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"instruction "</span> << inst<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span> vector<recipe_ordinal>& variants = get<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">);</span> +<span class="CommentedCode">//? trace(9992, "transform") << "checking base: " << get(Recipe_ordinal, inst.name) << end();</span> long long int best_score = variant_score<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">));</span> + trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"score for base: "</span> << best_score << 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>variants<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> +<span class="CommentedCode">//? trace(9992, "transform") << "checking variant " << i << ": " << variants.at(i) << end();</span> long long int current_score = variant_score<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> - trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"checking variant "</span> << i << <span class="Constant">": "</span> << current_score << end<span class="Delimiter">();</span> + trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"score for variant "</span> << i << <span class="Constant">": "</span> << current_score << end<span class="Delimiter">();</span> if <span class="Delimiter">(</span>current_score > best_score<span class="Delimiter">)</span> <span class="Delimiter">{</span> inst<span class="Delimiter">.</span>name = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)).</span>name<span class="Delimiter">;</span> best_score = current_score<span class="Delimiter">;</span> @@ -176,32 +191,74 @@ void replace_best_variant<span class="Delimiter">(</span>instruction& inst<s <span class="Delimiter">}</span> long long int variant_score<span class="Delimiter">(</span>const instruction& inst<span class="Delimiter">,</span> recipe_ordinal variant<span class="Delimiter">)</span> <span class="Delimiter">{</span> + long long int result = <span class="Constant">1000</span><span class="Delimiter">;</span> if <span class="Delimiter">(</span>variant == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Comment">// ghost from a previous test</span> +<span class="CommentedCode">//? cerr << "variant score: " << inst.to_string() << '\n';</span> + if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">))</span> <span class="Delimiter">{</span> + assert<span class="Delimiter">(</span>variant < MAX_PRIMITIVE_RECIPES<span class="Delimiter">);</span> + <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> const vector<reagent>& header_ingredients = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">;</span> if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> < SIZE<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">))</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"too few ingredients"</span> << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "too few ingredients\n";</span> <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> +<span class="CommentedCode">//? cerr << "=== checking ingredients\n";</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>header_ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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> trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"mismatch: ingredient "</span> << i << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "mismatch: ingredient " << i << '\n';</span> <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> + if <span class="Delimiter">(</span>types_strictly_match<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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> + trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"strict match: ingredient "</span> << i << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "strict match: ingredient " << i << '\n';</span> + <span class="Delimiter">}</span> + else if <span class="Delimiter">(</span>boolean_matches_literal<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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="Comment">// slight penalty for coercing literal to boolean (prefer direct conversion to number if possible)</span> + trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"boolean matches literal: ingredient "</span> << i << end<span class="Delimiter">();</span> + result--<span class="Delimiter">;</span> + <span class="Delimiter">}</span> + else <span class="Delimiter">{</span> + <span class="Comment">// slightly larger penalty for modifying type in other ways</span> + trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"non-strict match: ingredient "</span> << i << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "non-strict match: ingredient " << i << '\n';</span> + result-=<span class="Constant">10</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> <span class="Delimiter">}</span> +<span class="CommentedCode">//? cerr << "=== done checking ingredients\n";</span> if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">)</span> > SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">))</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"too few products"</span> << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "too few products\n";</span> <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> const vector<reagent>& header_products = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<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> if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>header_products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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> trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"mismatch: product "</span> << i << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "mismatch: product " << i << '\n';</span> <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> + if <span class="Delimiter">(</span>types_strictly_match<span class="Delimiter">(</span>header_products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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> + trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"strict match: product "</span> << i << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "strict match: product " << i << '\n';</span> + <span class="Delimiter">}</span> + else if <span class="Delimiter">(</span>boolean_matches_literal<span class="Delimiter">(</span>header_products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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="Comment">// slight penalty for coercing literal to boolean (prefer direct conversion to number if possible)</span> + trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"boolean matches literal: product "</span> << i << end<span class="Delimiter">();</span> + result--<span class="Delimiter">;</span> + <span class="Delimiter">}</span> + else <span class="Delimiter">{</span> + <span class="Comment">// slightly larger penalty for modifying type in other ways</span> + trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"non-strict match: product "</span> << i << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "non-strict match: product " << i << '\n';</span> + result-=<span class="Constant">10</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> <span class="Delimiter">}</span> - <span class="Comment">// the greater the number of unused ingredients, the lower the score</span> - <span class="Identifier">return</span> <span class="Constant">100</span> - <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">)</span>-SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">))</span> - - <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span>-SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">));</span> <span class="Comment">// ok to go negative</span> + <span class="Comment">// the greater the number of unused ingredients/products, the lower the score</span> + <span class="Identifier">return</span> result - <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">)</span>-SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">))</span> + - <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span>-SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">));</span> <span class="Comment">// ok to go negative</span> <span class="Delimiter">}</span> <span class="Delimiter">:(scenario static_dispatch_disabled_on_headerless_definition)</span> @@ -223,6 +280,154 @@ recipe test a:number <span class="Delimiter">-></span> z:number [ z<span class="Special"> <- </span>copy <span class="Constant">1</span> ] <span class="traceContains">+warn: redefining recipe test</span> + +<span class="Delimiter">:(scenario static_dispatch_on_primitive_names)</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>equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number + <span class="Constant">4</span>:boolean<span class="Special"> <- </span>copy <span class="Constant">0</span>/<span class="Constant">false</span> + <span class="Constant">5</span>:boolean<span class="Special"> <- </span>copy <span class="Constant">0</span>/<span class="Constant">false</span> + <span class="Constant">6</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">4</span>:boolean<span class="Delimiter">,</span> <span class="Constant">5</span>:boolean +] + +<span class="Comment"># temporarily hardcode number equality to always fail</span> +recipe equal x:number<span class="Delimiter">,</span> y:number <span class="Delimiter">-></span> z:boolean [ + local-scope + load-ingredients + z<span class="Special"> <- </span>copy <span class="Constant">0</span>/<span class="Constant">false</span> +] +<span class="Comment"># comparing numbers used overload</span> +<span class="traceContains">+mem: storing 0 in location 3</span> +<span class="Comment"># comparing booleans continues to use primitive</span> +<span class="traceContains">+mem: storing 1 in location 6</span> + +<span class="Delimiter">:(scenario static_dispatch_prefers_literals_to_be_numbers_rather_than_addresses)</span> +recipe main [ + <span class="Constant">1</span>:number<span class="Special"> <- </span>foo <span class="Constant">0</span> +] +recipe foo x:address:number <span class="Delimiter">-></span> y:number [ + reply <span class="Constant">34</span> +] +recipe foo x:number <span class="Delimiter">-></span> y:number [ + reply <span class="Constant">35</span> +] +<span class="traceContains">+mem: storing 35 in location 1</span> + +<span class="Delimiter">:(scenario static_dispatch_on_non_literal_character_ignores_variant_with_numbers)</span> +<span class="Special">% Hide_errors = true;</span> +recipe main [ + local-scope + x:character<span class="Special"> <- </span>copy <span class="Constant">10</span>/newline + <span class="Constant">1</span>:number/<span class="Special">raw <- </span>foo x +] +recipe foo x:number <span class="Delimiter">-></span> y:number [ + load-ingredients + reply <span class="Constant">34</span> +] +<span class="traceContains">+error: foo: wrong type for ingredient x:number</span> +<span class="traceAbsent">-mem: storing 34 in location 1</span> + +<span class="Delimiter">:(scenario static_dispatch_dispatches_literal_to_boolean_before_character)</span> +recipe main [ + <span class="Constant">1</span>:number/<span class="Special">raw <- </span>foo <span class="Constant">0</span> <span class="Comment"># valid literal for boolean</span> +] +recipe foo x:character <span class="Delimiter">-></span> y:number [ + local-scope + load-ingredients + reply <span class="Constant">34</span> +] +recipe foo x:boolean <span class="Delimiter">-></span> y:number [ + local-scope + load-ingredients + reply <span class="Constant">35</span> +] +<span class="Comment"># boolean variant is preferred</span> +<span class="traceContains">+mem: storing 35 in location 1</span> + +<span class="Delimiter">:(scenario static_dispatch_dispatches_literal_to_character_when_out_of_boolean_range)</span> +recipe main [ + <span class="Constant">1</span>:number/<span class="Special">raw <- </span>foo <span class="Constant">97</span> <span class="Comment"># not a valid literal for boolean</span> +] +recipe foo x:character <span class="Delimiter">-></span> y:number [ + local-scope + load-ingredients + reply <span class="Constant">34</span> +] +recipe foo x:boolean <span class="Delimiter">-></span> y:number [ + local-scope + load-ingredients + reply <span class="Constant">35</span> +] +<span class="Comment"># character variant is preferred</span> +<span class="traceContains">+mem: storing 34 in location 1</span> + +<span class="Delimiter">:(scenario static_dispatch_dispatches_literal_to_number_if_at_all_possible)</span> +recipe main [ + <span class="Constant">1</span>:number/<span class="Special">raw <- </span>foo <span class="Constant">97</span> +] +recipe foo x:character <span class="Delimiter">-></span> y:number [ + local-scope + load-ingredients + reply <span class="Constant">34</span> +] +recipe foo x:number <span class="Delimiter">-></span> y:number [ + local-scope + load-ingredients + reply <span class="Constant">35</span> +] +<span class="Comment"># number variant is preferred</span> +<span class="traceContains">+mem: storing 35 in location 1</span> + +<span class="Comment">//: after we make all attempts to dispatch, any unhandled cases will end up at</span> +<span class="Comment">//: some wrong variant and trigger an error while trying to load-ingredients</span> + +<span class="Delimiter">:(scenario static_dispatch_shows_clear_error_on_missing_variant)</span> +<span class="Special">% Hide_errors = true;</span> +recipe main [ + <span class="Constant">1</span>:number<span class="Special"> <- </span>foo <span class="Constant">34</span> +] +recipe foo x:boolean <span class="Delimiter">-></span> y:number [ + local-scope + load-ingredients + reply <span class="Constant">35</span> +] +<span class="traceContains">+error: foo: wrong type for ingredient x:boolean</span> +<span class="traceContains">+error: (we're inside recipe foo x:boolean -> y:number)</span> +<span class="traceContains">+error: (we're trying to call '1:number <- foo 34' inside recipe main)</span> + +<span class="Delimiter">:(before "End next-ingredient Type Mismatch Error")</span> +raise_error << <span class="Constant">" (we're inside "</span> << header_label<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>running_recipe<span class="Delimiter">)</span> << <span class="Constant">")</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> +raise_error << <span class="Constant">" (we're trying to call '"</span> << to_instruction<span class="Delimiter">(</span>*++Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>begin<span class="Delimiter">()).</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"' inside "</span> << header_label<span class="Delimiter">((</span>++Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>begin<span class="Delimiter">())-></span>running_recipe<span class="Delimiter">)</span> << <span class="Constant">")</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + +<span class="Delimiter">:(scenario static_dispatch_shows_clear_error_on_missing_variant_2)</span> +<span class="Special">% Hide_errors = true;</span> +recipe main [ + <span class="Constant">1</span>:boolean<span class="Special"> <- </span>foo <span class="Constant">34</span> +] +recipe foo x:number <span class="Delimiter">-></span> y:number [ + local-scope + load-ingredients + reply x +] +<span class="traceContains">+error: foo: reply ingredient x can't be saved in 1:boolean</span> +<span class="traceContains">+error: (we just returned from recipe foo x:number -> y:number)</span> + +<span class="Delimiter">:(before "End reply Type Mismatch Error")</span> +raise_error << <span class="Constant">" (we just returned from "</span> << header_label<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>operation<span class="Delimiter">)</span> << <span class="Constant">")</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + +<span class="Delimiter">:(code)</span> +string header_label<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + const recipe& caller = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span> + ostringstream out<span class="Delimiter">;</span> + out << <span class="Constant">"recipe "</span> << caller<span class="Delimiter">.</span>name<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<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> + out << <span class="Constant">' '</span> << caller<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!caller<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<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>caller<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> + out << <span class="Constant">' '</span> << caller<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string<span class="Delimiter">;</span> + <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span> +<span class="Delimiter">}</span> </pre> </body> </html> diff --git a/html/058shape_shifting_container.cc.html b/html/058shape_shifting_container.cc.html index 0402d54b..6229c527 100644 --- a/html/058shape_shifting_container.cc.html +++ b/html/058shape_shifting_container.cc.html @@ -21,7 +21,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } .Delimiter { color: #a04060; } .SalientComment { color: #00ffff; } .Identifier { color: #804000; } -.CommentedCode { color: #6c6c6c; } --> </style> @@ -84,7 +83,7 @@ void read_type_ingredients<span class="Delimiter">(</span>string& name<span put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">,</span> Next_type_ordinal++<span class="Delimiter">);</span> type_info& info = get_or_insert<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">));</span> long long int next_type_ordinal = START_TYPE_INGREDIENTS<span class="Delimiter">;</span> - while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span> + while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span> string curr = slurp_until<span class="Delimiter">(</span>in<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">);</span> if <span class="Delimiter">(</span>info<span class="Delimiter">.</span>type_ingredient_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>curr<span class="Delimiter">)</span> != info<span class="Delimiter">.</span>type_ingredient_names<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> raise_error << <span class="Constant">"can't repeat type ingredient names in a single container definition</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> @@ -130,13 +129,7 @@ long long int size_of_type_ingredient<span class="Delimiter">(</span>const type_ <span class="Delimiter">}</span> assert<span class="Delimiter">(</span>curr<span class="Delimiter">);</span> assert<span class="Delimiter">(</span>!curr<span class="Delimiter">-></span>left<span class="Delimiter">);</span> <span class="Comment">// unimplemented</span> - if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> curr<span class="Delimiter">-></span>value<span class="Delimiter">))</span> <span class="Delimiter">{</span> - <span class="Comment">// temporarily while we're still ironing out kinks; eventually replace with a raise_error</span> -<span class="CommentedCode">//? DUMP("");</span> - cerr << <span class="Constant">"missing type "</span> << debug_string<span class="Delimiter">(</span>curr<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> - exit<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> - <span class="Delimiter">}</span> - assert<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> curr<span class="Delimiter">-></span>value<span class="Delimiter">));</span> + if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> curr<span class="Delimiter">-></span>value<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span> trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"type"</span><span class="Delimiter">)</span> << <span class="Constant">"type deduced to be "</span> << get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> curr<span class="Delimiter">-></span>value<span class="Delimiter">).</span>name << <span class="Constant">"$"</span> << end<span class="Delimiter">();</span> type_tree tmp<span class="Delimiter">(</span>curr<span class="Delimiter">-></span>value<span class="Delimiter">);</span> if <span class="Delimiter">(</span>curr<span class="Delimiter">-></span>right<span class="Delimiter">)</span> diff --git a/html/059shape_shifting_recipe.cc.html b/html/059shape_shifting_recipe.cc.html index 13c436c4..ce450999 100644 --- a/html/059shape_shifting_recipe.cc.html +++ b/html/059shape_shifting_recipe.cc.html @@ -72,34 +72,58 @@ if <span class="Delimiter">(</span>Current_routine<span class="Delimiter">->< <span class="Comment">//: Make sure we don't match up literals with type ingredients without</span> <span class="Comment">//: specialization.</span> -<span class="Delimiter">:(before "End valid_type_for_literal Special-cases")</span> +<span class="Delimiter">:(before "End Matching Types For Literal(lhs)")</span> if <span class="Delimiter">(</span>contains_type_ingredient_name<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Comment">//: We'll be creating recipes without loading them from anywhere by</span> -<span class="Comment">//: *specializing* existing recipes, so make sure we don't clear any of those</span> -<span class="Comment">//: when we start running tests.</span> +<span class="Comment">//: *specializing* existing recipes.</span> +<span class="Comment">//:</span> +<span class="Comment">//: Keep track of these new recipes in a separate variable in addition to</span> +<span class="Comment">//: recently_added_recipes, so that edit/ can clear them before reloading to</span> +<span class="Comment">//: regenerate errors.</span> +<span class="Delimiter">:(before "End Globals")</span> +vector<recipe_ordinal> recently_added_shape_shifting_recipes<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Setup")</span> +<span class="CommentedCode">//? cerr << "setup: clearing recently-added shape-shifting recipes\n";</span> +recently_added_shape_shifting_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> + +<span class="Comment">//: make sure we don't clear any of these recipes when we start running tests</span> <span class="Delimiter">:(before "End Loading .mu Files")</span> recently_added_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> recently_added_types<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "clearing recently-added shape-shifting recipes\n";</span> +recently_added_shape_shifting_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> + +<span class="Comment">//: save original name of specialized recipes</span> +<span class="Delimiter">:(before "End recipe Fields")</span> +string original_name<span class="Delimiter">;</span> +<span class="Comment">//: original name is only set during load</span> +<span class="Delimiter">:(before "End recipe Refinements")</span> +result<span class="Delimiter">.</span>original_name = result<span class="Delimiter">.</span>name<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Instruction Dispatch(inst, best_score)")</span> if <span class="Delimiter">(</span>best_score == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> -<span class="CommentedCode">//? if (inst.name == "push-duplex") Trace_stream = new trace_stream;</span> trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"no variant found; searching for variant with suitable type ingredients"</span> << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "no variant found for " << inst.name << "; searching for variant with suitable type ingredients" << '\n';</span> recipe_ordinal exemplar = pick_matching_shape_shifting_variant<span class="Delimiter">(</span>variants<span class="Delimiter">,</span> inst<span class="Delimiter">,</span> best_score<span class="Delimiter">);</span> if <span class="Delimiter">(</span>exemplar<span class="Delimiter">)</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"found variant to specialize: "</span> << exemplar << <span class="Constant">' '</span> << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> exemplar<span class="Delimiter">).</span>name << end<span class="Delimiter">();</span> - variants<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_variant<span class="Delimiter">(</span>exemplar<span class="Delimiter">,</span> inst<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">));</span> +<span class="CommentedCode">//? cerr << "found variant to specialize: " << exemplar << ' ' << get(Recipe, exemplar).name << '\n';</span> + recipe_ordinal new_recipe_ordinal = new_variant<span class="Delimiter">(</span>exemplar<span class="Delimiter">,</span> inst<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">);</span> + variants<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_recipe_ordinal<span class="Delimiter">);</span> + <span class="Comment">// perform all transforms on the new specialization</span> + const string& new_name = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>back<span class="Delimiter">()).</span>name<span class="Delimiter">;</span> + trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"transforming new specialization: "</span> << new_name << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "transforming new specialization: " << new_name << '\n';</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> + <span class="Delimiter">(</span>*Transform<span class="Delimiter">.</span>at<span class="Delimiter">(</span>t<span class="Delimiter">))(</span>new_recipe_ordinal<span class="Delimiter">);</span> + <span class="Delimiter">}</span> + get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> new_recipe_ordinal<span class="Delimiter">).</span>transformed_until = SIZE<span class="Delimiter">(</span>Transform<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">;</span> <span class="CommentedCode">//? cerr << "-- replacing " << inst.name << " with " << get(Recipe, variants.back()).name << '\n' << debug_string(get(Recipe, variants.back()));</span> inst<span class="Delimiter">.</span>name = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>back<span class="Delimiter">()).</span>name<span class="Delimiter">;</span> trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"new specialization: "</span> << inst<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "new specialization: " << inst.name << '\n';</span> <span class="Delimiter">}</span> -<span class="CommentedCode">//? if (inst.name == "push-duplex") {</span> -<span class="CommentedCode">//? cerr << "======== {\n";</span> -<span class="CommentedCode">//? cerr << inst.to_string() << '\n';</span> -<span class="CommentedCode">//? DUMP("");</span> -<span class="CommentedCode">//? cerr << "======== }\n";</span> -<span class="CommentedCode">//? }</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> @@ -126,64 +150,96 @@ long long int shape_shifting_variant_score<span class="Delimiter">(</span>const <span class="CommentedCode">//? cerr << "======== " << inst.to_string() << '\n';</span> if <span class="Delimiter">(</span>!any_type_ingredient_in_header<span class="Delimiter">(</span>variant<span class="Delimiter">))</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"no type ingredients"</span> << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "no type ingredients\n";</span> <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> const vector<reagent>& header_ingredients = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">;</span> if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> < SIZE<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">))</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"too few ingredients"</span> << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "too few ingredients\n";</span> <span class="Identifier">return</span> -<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>header_ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> if <span class="Delimiter">(</span>!deeply_equal_concrete_types<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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> trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"mismatch: ingredient "</span> << i << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "mismatch: ingredient " << i << ": " << debug_string(header_ingredients.at(i)) << " vs " << debug_string(inst.ingredients.at(i)) << '\n';</span> <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</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> > SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">))</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"too few products"</span> << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "too few products\n";</span> <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> const vector<reagent>& header_products = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<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> if <span class="Delimiter">(</span>!deeply_equal_concrete_types<span class="Delimiter">(</span>header_products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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> trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"mismatch: product "</span> << i << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << "mismatch: product " << i << '\n';</span> <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Comment">// the greater the number of unused ingredients, the lower the score</span> <span class="Identifier">return</span> <span class="Constant">100</span> - <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">)</span>-SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">))</span> - - <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span>-SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">));</span> <span class="Comment">// ok to go negative</span> + - <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span>-SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">))</span> <span class="Comment">// ok to go negative</span> + + number_of_concrete_types<span class="Delimiter">(</span>variant<span class="Delimiter">);</span> <span class="Delimiter">}</span> bool any_type_ingredient_in_header<span class="Delimiter">(</span>recipe_ordinal variant<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>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - if <span class="Delimiter">(</span>contains_type_ingredient_name<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> + const recipe& caller = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<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<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>contains_type_ingredient_name<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Identifier">return</span> <span class="Constant">true</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>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - if <span class="Delimiter">(</span>contains_type_ingredient_name<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<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>caller<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>contains_type_ingredient_name<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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> bool deeply_equal_concrete_types<span class="Delimiter">(</span>reagent lhs<span class="Delimiter">,</span> reagent rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span> -<span class="CommentedCode">//? cerr << debug_string(lhs) << " vs " << debug_string(rhs) << '\n';</span> -<span class="CommentedCode">//? bool result = deeply_equal_concrete_types(lhs.properties.at(0).second, rhs.properties.at(0).second, rhs);</span> -<span class="CommentedCode">//? cerr << " => " << result << '\n';</span> -<span class="CommentedCode">//? return result;</span> -<span class="CommentedCode">//? cerr << "== " << debug_string(lhs) << " vs " << debug_string(rhs) << '\n';</span> canonize_type<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span> canonize_type<span class="Delimiter">(</span>rhs<span class="Delimiter">);</span> <span class="Identifier">return</span> deeply_equal_concrete_types<span class="Delimiter">(</span>lhs<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> rhs<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> rhs<span class="Delimiter">);</span> <span class="Delimiter">}</span> +long long int number_of_concrete_types<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + const recipe& caller = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<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>caller<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> + result += number_of_concrete_types<span class="Delimiter">(</span>caller<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>caller<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> + result += number_of_concrete_types<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> + <span class="Identifier">return</span> result<span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +long long int number_of_concrete_types<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Identifier">return</span> number_of_concrete_types<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> +<span class="Delimiter">}</span> + +long long int number_of_concrete_types<span class="Delimiter">(</span>const string_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!type<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span> + long long int result = <span class="Constant">0</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>value<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && !is_type_ingredient_name<span class="Delimiter">(</span>type<span class="Delimiter">-></span>value<span class="Delimiter">))</span> + result++<span class="Delimiter">;</span> + result += number_of_concrete_types<span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">);</span> + result += number_of_concrete_types<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">);</span> + <span class="Identifier">return</span> result<span class="Delimiter">;</span> +<span class="Delimiter">}</span> + bool deeply_equal_concrete_types<span class="Delimiter">(</span>const string_tree* lhs<span class="Delimiter">,</span> const string_tree* rhs<span class="Delimiter">,</span> const reagent& rhs_reagent<span class="Delimiter">)</span> <span class="Delimiter">{</span> if <span class="Delimiter">(</span>!lhs<span class="Delimiter">)</span> <span class="Identifier">return</span> !rhs<span class="Delimiter">;</span> if <span class="Delimiter">(</span>!rhs<span class="Delimiter">)</span> <span class="Identifier">return</span> !lhs<span class="Delimiter">;</span> if <span class="Delimiter">(</span>is_type_ingredient_name<span class="Delimiter">(</span>lhs<span class="Delimiter">-></span>value<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Comment">// type ingredient matches anything</span> - if <span class="Delimiter">(</span>Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>lhs<span class="Delimiter">-></span>value<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">())</span> - <span class="Identifier">return</span> Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>rhs<span class="Delimiter">-></span>value<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>lhs<span class="Delimiter">-></span>value == <span class="Constant">"literal"</span> && rhs<span class="Delimiter">-></span>value == <span class="Constant">"literal"</span><span class="Delimiter">)</span> + <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>lhs<span class="Delimiter">-></span>value == <span class="Constant">"literal"</span> + && Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>rhs<span class="Delimiter">-></span>value<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">())</span> + <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>rhs<span class="Delimiter">-></span>value == <span class="Constant">"literal"</span> + && Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>lhs<span class="Delimiter">-></span>value<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">())</span> + <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> if <span class="Delimiter">(</span>rhs<span class="Delimiter">-></span>value == <span class="Constant">"literal"</span> && lhs<span class="Delimiter">-></span>value == <span class="Constant">"address"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> rhs_reagent<span class="Delimiter">.</span>name == <span class="Constant">"0"</span><span class="Delimiter">;</span> <span class="CommentedCode">//? cerr << lhs->value << " vs " << rhs->value << '\n';</span> @@ -215,6 +271,7 @@ recipe_ordinal new_variant<span class="Delimiter">(</span>recipe_ordinal exempla assert<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> exemplar<span class="Delimiter">));</span> assert<span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> new_recipe_ordinal<span class="Delimiter">));</span> recently_added_recipes<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_recipe_ordinal<span class="Delimiter">);</span> + recently_added_shape_shifting_recipes<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_recipe_ordinal<span class="Delimiter">);</span> put<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> new_recipe_ordinal<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> exemplar<span class="Delimiter">));</span> recipe& new_recipe = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> new_recipe_ordinal<span class="Delimiter">);</span> new_recipe<span class="Delimiter">.</span>name = new_name<span class="Delimiter">;</span> @@ -232,11 +289,6 @@ recipe_ordinal new_variant<span class="Delimiter">(</span>recipe_ordinal exempla if <span class="Delimiter">(</span>error<span class="Delimiter">)</span> <span class="Identifier">return</span> exemplar<span class="Delimiter">;</span> <span class="Delimiter">}</span> ensure_all_concrete_types<span class="Delimiter">(</span>new_recipe<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> exemplar<span class="Delimiter">));</span> - <span class="Comment">// finally, perform all transforms on the new specialization</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> - <span class="Delimiter">(</span>*Transform<span class="Delimiter">.</span>at<span class="Delimiter">(</span>t<span class="Delimiter">))(</span>new_recipe_ordinal<span class="Delimiter">);</span> - <span class="Delimiter">}</span> - new_recipe<span class="Delimiter">.</span>transformed_until = SIZE<span class="Delimiter">(</span>Transform<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Identifier">return</span> new_recipe_ordinal<span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -244,20 +296,20 @@ void compute_type_names<span class="Delimiter">(</span>recipe& variant<span trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"compute type names: "</span> << variant<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span> map<string<span class="Delimiter">,</span> string_tree*> type_names<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>variant<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> - save_or_deduce_type_name<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> type_names<span class="Delimiter">);</span> + save_or_deduce_type_name<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> type_names<span class="Delimiter">,</span> variant<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>variant<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> - save_or_deduce_type_name<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> type_names<span class="Delimiter">);</span> + save_or_deduce_type_name<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> type_names<span class="Delimiter">,</span> variant<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>variant<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> instruction& inst = variant<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">" instruction: "</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << end<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> - save_or_deduce_type_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> type_names<span class="Delimiter">);</span> + save_or_deduce_type_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> type_names<span class="Delimiter">,</span> variant<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> - save_or_deduce_type_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> type_names<span class="Delimiter">);</span> + save_or_deduce_type_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> type_names<span class="Delimiter">,</span> variant<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> -void save_or_deduce_type_name<span class="Delimiter">(</span>reagent& x<span class="Delimiter">,</span> map<string<span class="Delimiter">,</span> string_tree*>& type_name<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void save_or_deduce_type_name<span class="Delimiter">(</span>reagent& x<span class="Delimiter">,</span> map<string<span class="Delimiter">,</span> string_tree*>& type_name<span class="Delimiter">,</span> const recipe& variant<span class="Delimiter">)</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">9994</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">" checking "</span> << x<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">": "</span> << debug_string<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> << end<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 && contains_key<span class="Delimiter">(</span>type_name<span class="Delimiter">,</span> x<span class="Delimiter">.</span>name<span class="Delimiter">))</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 = new string_tree<span class="Delimiter">(</span>*get<span class="Delimiter">(</span>type_name<span class="Delimiter">,</span> x<span class="Delimiter">.</span>name<span class="Delimiter">));</span> @@ -265,7 +317,7 @@ void save_or_deduce_type_name<span class="Delimiter">(</span>reagent& x<span <span class="Identifier">return</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> <span class="Delimiter">{</span> - raise << <span class="Constant">"unknown type for "</span> << x<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + raise_error << maybe<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>original_name<span class="Delimiter">)</span> << <span class="Constant">"unknown type for "</span> << x<span class="Delimiter">.</span>original_string << <span class="Constant">" (check the name for typos)</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> if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>type_name<span class="Delimiter">,</span> x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> @@ -306,6 +358,7 @@ void accumulate_type_ingredients<span class="Delimiter">(</span>const reagent&am void accumulate_type_ingredients<span class="Delimiter">(</span>const string_tree* exemplar_type<span class="Delimiter">,</span> const string_tree* refinement_type<span class="Delimiter">,</span> map<string<span class="Delimiter">,</span> const string_tree*>& mappings<span class="Delimiter">,</span> const recipe& exemplar<span class="Delimiter">,</span> const reagent& exemplar_reagent<span class="Delimiter">,</span> const instruction& call_instruction<span class="Delimiter">,</span> const recipe& caller_recipe<span class="Delimiter">,</span> bool* error<span class="Delimiter">)</span> <span class="Delimiter">{</span> if <span class="Delimiter">(</span>!exemplar_type<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> if <span class="Delimiter">(</span>!refinement_type<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Comment">// todo: make this smarter; only warn if exemplar_type contains some *new* type ingredient</span> raise_error << maybe<span class="Delimiter">(</span>exemplar<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"missing type ingredient in "</span> << exemplar_reagent<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> @@ -317,10 +370,7 @@ void accumulate_type_ingredients<span class="Delimiter">(</span>const string_tre <span class="Delimiter">}</span> if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-></span>value<span class="Delimiter">))</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"adding mapping from "</span> << exemplar_type<span class="Delimiter">-></span>value << <span class="Constant">" to "</span> << debug_string<span class="Delimiter">(</span>refinement_type<span class="Delimiter">)</span> << end<span class="Delimiter">();</span> - if <span class="Delimiter">(</span>refinement_type<span class="Delimiter">-></span>value == <span class="Constant">"literal"</span><span class="Delimiter">)</span> - put<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-></span>value<span class="Delimiter">,</span> new string_tree<span class="Delimiter">(</span><span class="Constant">"number"</span><span class="Delimiter">));</span> - else - put<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-></span>value<span class="Delimiter">,</span> new string_tree<span class="Delimiter">(</span>*refinement_type<span class="Delimiter">));</span> + put<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-></span>value<span class="Delimiter">,</span> new string_tree<span class="Delimiter">(</span>*refinement_type<span class="Delimiter">));</span> <span class="Delimiter">}</span> else <span class="Delimiter">{</span> if <span class="Delimiter">(</span>!deeply_equal_types<span class="Delimiter">(</span>get<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-></span>value<span class="Delimiter">),</span> refinement_type<span class="Delimiter">))</span> <span class="Delimiter">{</span> @@ -329,6 +379,11 @@ void accumulate_type_ingredients<span class="Delimiter">(</span>const string_tre *error = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> +<span class="CommentedCode">//? cerr << exemplar_type->value << ": " << debug_string(get(mappings, exemplar_type->value)) << " <= " << debug_string(refinement_type) << '\n';</span> + if <span class="Delimiter">(</span>get<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-></span>value<span class="Delimiter">)-></span>value == <span class="Constant">"literal"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + delete get<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> + put<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-></span>value<span class="Delimiter">,</span> new string_tree<span class="Delimiter">(</span>*refinement_type<span class="Delimiter">));</span> + <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> else <span class="Delimiter">{</span> @@ -342,20 +397,20 @@ void replace_type_ingredients<span class="Delimiter">(</span>recipe& new_rec if <span class="Delimiter">(</span>mappings<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"replacing in recipe header ingredients"</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>new_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> - replace_type_ingredients<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> mappings<span class="Delimiter">);</span> + replace_type_ingredients<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> mappings<span class="Delimiter">,</span> new_recipe<span class="Delimiter">);</span> trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"replacing in recipe header products"</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>new_recipe<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> - replace_type_ingredients<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> mappings<span class="Delimiter">);</span> + replace_type_ingredients<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> mappings<span class="Delimiter">,</span> new_recipe<span class="Delimiter">);</span> <span class="Comment">// update its body</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>new_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> instruction& inst = new_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"replacing in instruction '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'"</span> << end<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>ingredients<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> - replace_type_ingredients<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">),</span> mappings<span class="Delimiter">);</span> + replace_type_ingredients<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">),</span> mappings<span class="Delimiter">,</span> new_recipe<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> - replace_type_ingredients<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">),</span> mappings<span class="Delimiter">);</span> + replace_type_ingredients<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">),</span> mappings<span class="Delimiter">,</span> new_recipe<span class="Delimiter">);</span> <span class="Comment">// special-case for new: replace type ingredient in first ingredient *value*</span> - if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">"new"</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>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>inst<span class="Delimiter">.</span>name == <span class="Constant">"new"</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>value != <span class="Constant">"literal-string"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> string_tree* type_name = parse_string_tree<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> replace_type_ingredients<span class="Delimiter">(</span>type_name<span class="Delimiter">,</span> mappings<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 = type_name<span class="Delimiter">-></span>to_string<span class="Delimiter">();</span> @@ -364,10 +419,13 @@ void replace_type_ingredients<span class="Delimiter">(</span>recipe& new_rec <span class="Delimiter">}</span> <span class="Delimiter">}</span> -void replace_type_ingredients<span class="Delimiter">(</span>reagent& x<span class="Delimiter">,</span> const map<string<span class="Delimiter">,</span> const string_tree*>& mappings<span class="Delimiter">)</span> <span class="Delimiter">{</span> +void replace_type_ingredients<span class="Delimiter">(</span>reagent& x<span class="Delimiter">,</span> const map<string<span class="Delimiter">,</span> const string_tree*>& mappings<span class="Delimiter">,</span> const recipe& caller<span class="Delimiter">)</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"replacing in ingredient "</span> << x<span class="Delimiter">.</span>original_string << end<span class="Delimiter">();</span> <span class="Comment">// replace properties</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> + 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> <span class="Delimiter">{</span> + raise_error << <span class="Constant">"specializing "</span> << caller<span class="Delimiter">.</span>original_name << <span class="Constant">": missing type for "</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> replace_type_ingredients<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> mappings<span class="Delimiter">);</span> <span class="Comment">// refresh types from properties</span> delete x<span class="Delimiter">.</span>type<span class="Delimiter">;</span> @@ -381,7 +439,10 @@ void replace_type_ingredients<span class="Delimiter">(</span>string_tree* type<s if <span class="Delimiter">(</span>is_type_ingredient_name<span class="Delimiter">(</span>type<span class="Delimiter">-></span>value<span class="Delimiter">)</span> && contains_key<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">))</span> <span class="Delimiter">{</span> const string_tree* replacement = get<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << type<span class="Delimiter">-></span>value << <span class="Constant">" => "</span> << debug_string<span class="Delimiter">(</span>replacement<span class="Delimiter">)</span> << end<span class="Delimiter">();</span> - type<span class="Delimiter">-></span>value = replacement<span class="Delimiter">-></span>value<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>replacement<span class="Delimiter">-></span>value == <span class="Constant">"literal"</span><span class="Delimiter">)</span> + type<span class="Delimiter">-></span>value = <span class="Constant">"number"</span><span class="Delimiter">;</span> + else + type<span class="Delimiter">-></span>value = replacement<span class="Delimiter">-></span>value<span class="Delimiter">;</span> if <span class="Delimiter">(</span>replacement<span class="Delimiter">-></span>left<span class="Delimiter">)</span> type<span class="Delimiter">-></span>left = new string_tree<span class="Delimiter">(</span>*replacement<span class="Delimiter">-></span>left<span class="Delimiter">);</span> if <span class="Delimiter">(</span>replacement<span class="Delimiter">-></span>right<span class="Delimiter">)</span> type<span class="Delimiter">-></span>right = new string_tree<span class="Delimiter">(</span>*replacement<span class="Delimiter">-></span>right<span class="Delimiter">);</span> <span class="Delimiter">}</span> @@ -684,6 +745,80 @@ container d2:_elem [ ] <span class="traceContains">+mem: storing 34 in location 1</span> <span class="traceContains">+mem: storing 35 in location 2</span> + +<span class="Delimiter">:(scenario missing_type_in_shape_shifting_recipe)</span> +<span class="Special">% Hide_errors = true;</span> +recipe main [ + a:d1:number<span class="Special"> <- </span>merge <span class="Constant">3</span> + foo a +] +recipe foo a:d1:_elem <span class="Delimiter">-></span> b:number [ + local-scope + load-ingredients + copy e <span class="Comment"># no such variable</span> + reply <span class="Constant">34</span> +] +container d1:_elem [ + x:_elem +] +<span class="traceContains">+error: foo: unknown type for e (check the name for typos)</span> +<span class="traceContains">+error: specializing foo: missing type for e</span> +<span class="Comment"># and it doesn't crash</span> + +<span class="Delimiter">:(scenario missing_type_in_shape_shifting_recipe_2)</span> +<span class="Special">% Hide_errors = true;</span> +recipe main [ + a:d1:number<span class="Special"> <- </span>merge <span class="Constant">3</span> + foo a +] +recipe foo a:d1:_elem <span class="Delimiter">-></span> b:number [ + local-scope + load-ingredients + get e<span class="Delimiter">,</span> x:offset <span class="Comment"># unknown variable in a 'get', which does some extra checking</span> + reply <span class="Constant">34</span> +] +container d1:_elem [ + x:_elem +] +<span class="traceContains">+error: foo: unknown type for e (check the name for typos)</span> +<span class="traceContains">+error: specializing foo: missing type for e</span> +<span class="Comment"># and it doesn't crash</span> + +<span class="Delimiter">:(scenarios transform)</span> +<span class="Delimiter">:(scenario specialize_recursive_shape_shifting_recipe)</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>foo <span class="Constant">1</span>:number +] +recipe foo x:_elem <span class="Delimiter">-></span> y:number [ + local-scope + load-ingredients + <span class="Delimiter">{</span> + <span class="Identifier">break</span> + y:number<span class="Special"> <- </span>foo x + <span class="Delimiter">}</span> + reply y +] +<span class="traceContains">+transform: new specialization: foo_2</span> +<span class="Comment"># transform terminates</span> + +<span class="Delimiter">:(scenarios run)</span> +<span class="Delimiter">:(scenario specialize_most_similar_variant)</span> +recipe main [ + <span class="Constant">1</span>:address:number<span class="Special"> <- </span>new number:type + <span class="Constant">2</span>:number<span class="Special"> <- </span>foo <span class="Constant">1</span>:address:number +] +recipe foo x:_elem <span class="Delimiter">-></span> y:number [ + local-scope + load-ingredients + reply <span class="Constant">34</span> +] +recipe foo x:address:_elem <span class="Delimiter">-></span> y:number [ + local-scope + load-ingredients + reply <span class="Constant">35</span> +] +<span class="traceContains">+mem: storing 35 in location 2</span> </pre> </body> </html> diff --git a/html/070string.mu.html b/html/070text.mu.html index 08edff08..38851b6c 100644 --- a/html/070string.mu.html +++ b/html/070text.mu.html @@ -2,7 +2,7 @@ <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> -<title>Mu - 070string.mu</title> +<title>Mu - 070text.mu</title> <meta name="Generator" content="Vim/7.4"> <meta name="plugin-version" content="vim7.4_v1"> <meta name="syntax" content="none"> @@ -20,6 +20,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .Special { color: #ff6060; } +.CommentedCode { color: #6c6c6c; } .Delimiter { color: #a04060; } --> </style> @@ -32,23 +33,38 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } </head> <body> <pre id='vimCodeElement'> -<span class="Comment"># Some useful helpers for dealing with strings.</span> +<span class="Comment"># Some useful helpers for dealing with text (arrays of characters)</span> -<span class="muRecipe">recipe</span> string-equal [ +<span class="Comment"># to-text-line gets called implicitly in various places</span> +<span class="Comment"># define it to be identical to 'to-text' by default</span> +<span class="muRecipe">recipe</span> to-text-line x:_elem<span class="muRecipe"> -> </span>y:address:array:character [ <span class="Constant">local-scope</span> - a:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> + y<span class="Special"> <- </span>to-text x +] + +<span class="Comment"># to-text on text is just the identity function</span> +<span class="muRecipe">recipe</span> to-text x:address:array:character<span class="muRecipe"> -> </span>y:address:array:character [ + <span class="Constant">local-scope</span> + <span class="Constant">load-ingredients</span> +<span class="CommentedCode">#? $print [to-text text], 10/newline</span> + <span class="muControl">reply</span> x +] + +<span class="muRecipe">recipe</span> equal a:address:array:character, b:address:array:character<span class="muRecipe"> -> </span>result:boolean [ + <span class="Constant">local-scope</span> + <span class="Constant">load-ingredients</span> a-len:number<span class="Special"> <- </span>length *a - b:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> b-len:number<span class="Special"> <- </span>length *b <span class="Comment"># compare lengths</span> <span class="Delimiter">{</span> - trace <span class="Constant">99</span>, <span class="Constant">[string-equal]</span>, <span class="Constant">[comparing lengths]</span> + trace <span class="Constant">99</span>, <span class="Constant">[text-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">99</span>, <span class="Constant">[string-equal]</span>, <span class="Constant">[comparing characters]</span> + trace <span class="Constant">99</span>, <span class="Constant">[text-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 @@ -66,92 +82,91 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">reply</span> <span class="Constant">1</span> ] -<span class="muScenario">scenario</span> string-equal-reflexive [ +<span class="muScenario">scenario</span> text-equal-reflexive [ run [ <span class="Constant">default-space</span>:address:array:location<span class="Special"> <- </span>new <span class="Constant">location:type</span>, <span class="Constant">30</span> x:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> - <span class="Constant">3</span>:boolean/<span class="Special">raw <- </span>string-equal x, x + <span class="Constant">3</span>:boolean/<span class="Special">raw <- </span>equal x, x ] memory-should-contain [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Comment"># x == x for all x</span> ] ] -<span class="muScenario">scenario</span> string-equal-identical [ +<span class="muScenario">scenario</span> text-equal-identical [ run [ <span class="Constant">default-space</span>:address:array:location<span class="Special"> <- </span>new <span class="Constant">location:type</span>, <span class="Constant">30</span> x:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> y:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> - <span class="Constant">3</span>:boolean/<span class="Special">raw <- </span>string-equal x, y + <span class="Constant">3</span>:boolean/<span class="Special">raw <- </span>equal x, y ] memory-should-contain [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Comment"># abc == abc</span> ] ] -<span class="muScenario">scenario</span> string-equal-distinct-lengths [ +<span class="muScenario">scenario</span> text-equal-distinct-lengths [ run [ <span class="Constant">default-space</span>:address:array:location<span class="Special"> <- </span>new <span class="Constant">location:type</span>, <span class="Constant">30</span> x:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> y:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcd]</span> - <span class="Constant">3</span>:boolean/<span class="Special">raw <- </span>string-equal x, y + <span class="Constant">3</span>:boolean/<span class="Special">raw <- </span>equal x, y ] memory-should-contain [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">0</span> <span class="Comment"># abc != abcd</span> ] trace-should-contain [ - string-equal: comparing lengths + text-equal: comparing lengths ] trace-should-not-contain [ - string-equal: comparing characters + text-equal: comparing characters ] ] -<span class="muScenario">scenario</span> string-equal-with-empty [ +<span class="muScenario">scenario</span> text-equal-with-empty [ run [ <span class="Constant">default-space</span>:address:array:location<span class="Special"> <- </span>new <span class="Constant">location:type</span>, <span class="Constant">30</span> x:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span> y:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcd]</span> - <span class="Constant">3</span>:boolean/<span class="Special">raw <- </span>string-equal x, y + <span class="Constant">3</span>:boolean/<span class="Special">raw <- </span>equal x, y ] memory-should-contain [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">0</span> <span class="Comment"># "" != abcd</span> ] ] -<span class="muScenario">scenario</span> string-equal-common-lengths-but-distinct [ +<span class="muScenario">scenario</span> text-equal-common-lengths-but-distinct [ run [ <span class="Constant">default-space</span>:address:array:location<span class="Special"> <- </span>new <span class="Constant">location:type</span>, <span class="Constant">30</span> x:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> y:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abd]</span> - <span class="Constant">3</span>:boolean/<span class="Special">raw <- </span>string-equal x, y + <span class="Constant">3</span>:boolean/<span class="Special">raw <- </span>equal x, y ] memory-should-contain [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">0</span> <span class="Comment"># abc != abd</span> ] ] -<span class="Comment"># A new type to help incrementally construct strings.</span> +<span class="Comment"># A new type to help incrementally construct texts.</span> <span class="muData">container</span> buffer [ length:number data:address:array:character ] -<span class="muRecipe">recipe</span> new-buffer [ +<span class="muRecipe">recipe</span> new-buffer capacity:number<span class="muRecipe"> -> </span>result:address:buffer [ <span class="Constant">local-scope</span> - result:address:buffer<span class="Special"> <- </span>new <span class="Constant">buffer:type</span> + <span class="Constant">load-ingredients</span> + result<span class="Special"> <- </span>new <span class="Constant">buffer:type</span> len:address:number<span class="Special"> <- </span>get-address *result, <span class="Constant">length:offset</span> *len:address:number<span class="Special"> <- </span>copy <span class="Constant">0</span> s:address:address:array:character<span class="Special"> <- </span>get-address *result, <span class="Constant">data:offset</span> - capacity:number, found?:boolean<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - assert found?, <span class="Constant">[new-buffer must get a capacity argument]</span> *s<span class="Special"> <- </span>new <span class="Constant">character:type</span>, capacity <span class="muControl">reply</span> result ] -<span class="muRecipe">recipe</span> grow-buffer [ +<span class="muRecipe">recipe</span> grow-buffer in:address:buffer<span class="muRecipe"> -> </span>in:address:buffer [ <span class="Constant">local-scope</span> - in:address:buffer<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># double buffer size</span> x:address:address:array:character<span class="Special"> <- </span>get-address *in, <span class="Constant">data:offset</span> oldlen:number<span class="Special"> <- </span>length **x @@ -169,33 +184,48 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } 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> in ] -<span class="muRecipe">recipe</span> buffer-full? [ +<span class="muRecipe">recipe</span> buffer-full? in:address:buffer<span class="muRecipe"> -> </span>result:boolean [ <span class="Constant">local-scope</span> - in:address:buffer<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> len:number<span class="Special"> <- </span>get *in, <span class="Constant">length:offset</span> s:address:array:character<span class="Special"> <- </span>get *in, <span class="Constant">data:offset</span> capacity:number<span class="Special"> <- </span>length *s - result:boolean<span class="Special"> <- </span>greater-or-equal len, capacity - <span class="muControl">reply</span> result + result<span class="Special"> <- </span>greater-or-equal len, capacity +] + +<span class="Comment"># most broadly applicable definition of append to a buffer: just call to-text</span> +<span class="muRecipe">recipe</span> append buf:address:buffer, x:_elem<span class="muRecipe"> -> </span>buf:address:buffer [ + <span class="Constant">local-scope</span> +<span class="CommentedCode">#? $print [append _elem to buffer], 10/newline</span> + <span class="Constant">load-ingredients</span> + text:address:array:character<span class="Special"> <- </span>to-text x + len:number<span class="Special"> <- </span>length *text + 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, len + <span class="muControl">break-if</span> done? + c:character<span class="Special"> <- </span>index *text, i + buf<span class="Special"> <- </span>append buf, c + i<span class="Special"> <- </span>add i, <span class="Constant">1</span> + <span class="muControl">loop</span> + <span class="Delimiter">}</span> ] -<span class="Comment"># in <- buffer-append in:address:buffer, c:character</span> -<span class="muRecipe">recipe</span> buffer-append [ +<span class="muRecipe">recipe</span> append in:address:buffer, c:character<span class="muRecipe"> -> </span>in:address:buffer [ <span class="Constant">local-scope</span> - in:address:buffer<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - c:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> +<span class="CommentedCode">#? $print [append character to buffer], 10/newline</span> + <span class="Constant">load-ingredients</span> len:address:number<span class="Special"> <- </span>get-address *in, <span class="Constant">length:offset</span> <span class="Delimiter">{</span> <span class="Comment"># backspace? just drop last character if it exists and return</span> backspace?:boolean<span class="Special"> <- </span>equal c, <span class="Constant">8/backspace</span> <span class="muControl">break-unless</span> backspace? empty?:boolean<span class="Special"> <- </span>lesser-or-equal *len, <span class="Constant">0</span> - <span class="muControl">reply-if</span> empty?, in/same-as-ingredient:<span class="Constant">0</span> + <span class="muControl">reply-if</span> empty? *len<span class="Special"> <- </span>subtract *len, <span class="Constant">1</span> - <span class="muControl">reply</span> in/same-as-ingredient:<span class="Constant">0</span> + <span class="muControl">reply</span> <span class="Delimiter">}</span> <span class="Delimiter">{</span> <span class="Comment"># grow buffer if necessary</span> @@ -207,7 +237,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } dest:address:character<span class="Special"> <- </span>index-address *s, *len *dest<span class="Special"> <- </span>copy c *len<span class="Special"> <- </span>add *len, <span class="Constant">1</span> - <span class="muControl">reply</span> in/same-as-ingredient:<span class="Constant">0</span> ] <span class="muScenario">scenario</span> buffer-append-works [ @@ -215,14 +244,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant">local-scope</span> x:address:buffer<span class="Special"> <- </span>new-buffer <span class="Constant">3</span> s1:address:array:character<span class="Special"> <- </span>get *x:address:buffer, <span class="Constant">data:offset</span> - x:address:buffer<span class="Special"> <- </span>buffer-append x:address:buffer, <span class="Constant">97</span> <span class="Comment"># 'a'</span> - x:address:buffer<span class="Special"> <- </span>buffer-append x:address:buffer, <span class="Constant">98</span> <span class="Comment"># 'b'</span> - x:address:buffer<span class="Special"> <- </span>buffer-append x:address:buffer, <span class="Constant">99</span> <span class="Comment"># 'c'</span> + x:address:buffer<span class="Special"> <- </span>append x:address:buffer, <span class="Constant">97</span> <span class="Comment"># 'a'</span> + x:address:buffer<span class="Special"> <- </span>append x:address:buffer, <span class="Constant">98</span> <span class="Comment"># 'b'</span> + x:address:buffer<span class="Special"> <- </span>append x:address:buffer, <span class="Constant">99</span> <span class="Comment"># 'c'</span> s2:address:array:character<span class="Special"> <- </span>get *x:address:buffer, <span class="Constant">data:offset</span> <span class="Constant">1</span>:boolean/<span class="Special">raw <- </span>equal s1:address:array:character, s2:address:array:character <span class="Constant">2</span>:array:character/<span class="Special">raw <- </span>copy *s2:address:array:character <span class="Constant"> +buffer-filled</span> - x:address:buffer<span class="Special"> <- </span>buffer-append x:address:buffer, <span class="Constant">100</span> <span class="Comment"># 'd'</span> + x:address:buffer<span class="Special"> <- </span>append x:address:buffer, <span class="Constant">100</span> <span class="Comment"># 'd'</span> s3:address:array:character<span class="Special"> <- </span>get *x:address:buffer, <span class="Constant">data:offset</span> <span class="Constant">10</span>:boolean/<span class="Special">raw <- </span>equal s1:address:array:character, s3:address:array:character <span class="Constant">11</span>:number/<span class="Special">raw <- </span>get *x:address:buffer, <span class="Constant">length:offset</span> @@ -252,9 +281,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } run [ <span class="Constant">local-scope</span> x:address:buffer<span class="Special"> <- </span>new-buffer <span class="Constant">3</span> - x<span class="Special"> <- </span>buffer-append x, <span class="Constant">97</span> <span class="Comment"># 'a'</span> - x<span class="Special"> <- </span>buffer-append x, <span class="Constant">98</span> <span class="Comment"># 'b'</span> - x<span class="Special"> <- </span>buffer-append x, <span class="Constant">8/backspace</span> + x<span class="Special"> <- </span>append x, <span class="Constant">97</span> <span class="Comment"># 'a'</span> + x<span class="Special"> <- </span>append x, <span class="Constant">98</span> <span class="Comment"># 'b'</span> + x<span class="Special"> <- </span>append x, <span class="Constant">8/backspace</span> s:address:array:character<span class="Special"> <- </span>buffer-to-array x <span class="Constant">1</span>:array:character/<span class="Special">raw <- </span>copy *s ] @@ -265,15 +294,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<span class="Comment"># result:address:array:character <- integer-to-decimal-string n:number</span> -<span class="muRecipe">recipe</span> integer-to-decimal-string [ +<span class="muRecipe">recipe</span> to-text n:number<span class="muRecipe"> -> </span>result:address:array:character [ <span class="Constant">local-scope</span> - n:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - <span class="Comment"># is it zero?</span> + <span class="Constant">load-ingredients</span> + <span class="Comment"># is n zero?</span> <span class="Delimiter">{</span> <span class="muControl">break-if</span> n - result:address:array:character<span class="Special"> <- </span>new <span class="Constant">[0]</span> - <span class="muControl">reply</span> result + result<span class="Special"> <- </span>new <span class="Constant">[0]</span> + <span class="muControl">reply</span> <span class="Delimiter">}</span> <span class="Comment"># save sign</span> negate-result:boolean<span class="Special"> <- </span>copy <span class="Constant">0</span> @@ -291,18 +319,18 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">break-if</span> done? n, digit:number<span class="Special"> <- </span>divide-with-remainder n, <span class="Constant">10</span> c:character<span class="Special"> <- </span>add digit-base, digit - tmp:address:buffer<span class="Special"> <- </span>buffer-append tmp, c + tmp:address:buffer<span class="Special"> <- </span>append tmp, c <span class="muControl">loop</span> <span class="Delimiter">}</span> <span class="Comment"># add sign</span> <span class="Delimiter">{</span> <span class="muControl">break-unless</span> negate-result:boolean - tmp<span class="Special"> <- </span>buffer-append tmp, <span class="Constant">45</span> <span class="Comment"># '-'</span> + tmp<span class="Special"> <- </span>append tmp, <span class="Constant">45</span> <span class="Comment"># '-'</span> <span class="Delimiter">}</span> - <span class="Comment"># reverse buffer into string result</span> + <span class="Comment"># reverse buffer into text result</span> len:number<span class="Special"> <- </span>get *tmp, <span class="Constant">length:offset</span> buf:address:array:character<span class="Special"> <- </span>get *tmp, <span class="Constant">data:offset</span> - result:address:array:character<span class="Special"> <- </span>new <span class="Constant">character:type</span>, len + result<span class="Special"> <- </span>new <span class="Constant">character:type</span>, len i:number<span class="Special"> <- </span>subtract len, <span class="Constant">1</span> <span class="Comment"># source index, decreasing</span> j:number<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># destination index, increasing</span> <span class="Delimiter">{</span> @@ -317,12 +345,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } j<span class="Special"> <- </span>add j, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> result ] -<span class="muRecipe">recipe</span> buffer-to-array [ +<span class="muRecipe">recipe</span> buffer-to-array in:address:buffer<span class="muRecipe"> -> </span>result:address:array:character [ <span class="Constant">local-scope</span> - in:address:buffer<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Delimiter">{</span> <span class="Comment"># propagate null buffer</span> <span class="muControl">break-if</span> in @@ -331,7 +358,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } len:number<span class="Special"> <- </span>get *in, <span class="Constant">length:offset</span> s:address:array:character<span class="Special"> <- </span>get *in, <span class="Constant">data:offset</span> <span class="Comment"># we can't just return s because it is usually the wrong length</span> - result:address:array:character<span class="Special"> <- </span>new <span class="Constant">character:type</span>, len + result<span class="Special"> <- </span>new <span class="Constant">character:type</span>, len 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, len @@ -342,32 +369,31 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } 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> result ] <span class="muScenario">scenario</span> integer-to-decimal-digit-zero [ run [ - <span class="Constant">1</span>:address:array:character/<span class="Special">raw <- </span>integer-to-decimal-string <span class="Constant">0</span> + <span class="Constant">1</span>:address:array:character/<span class="Special">raw <- </span>to-text <span class="Constant">0</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">[0]</span> + <span class="Constant">2</span>:array:character<span class="Special"> <- </span><span class="Constant">[0]</span> ] ] <span class="muScenario">scenario</span> integer-to-decimal-digit-positive [ run [ - <span class="Constant">1</span>:address:array:character/<span class="Special">raw <- </span>integer-to-decimal-string <span class="Constant">234</span> + <span class="Constant">1</span>:address:array:character/<span class="Special">raw <- </span>to-text <span class="Constant">234</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">[234]</span> + <span class="Constant">2</span>:array:character<span class="Special"> <- </span><span class="Constant">[234]</span> ] ] <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 <span class="Constant">-1</span> + <span class="Constant">1</span>:address:array:character/<span class="Special">raw <- </span>to-text <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 [ @@ -377,16 +403,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<span class="Comment"># result:address:array:character <- string-append a:address:array:character, b:address:array:character</span> -<span class="muRecipe">recipe</span> string-append [ +<span class="muRecipe">recipe</span> append a:address:array:character, b:address:array:character<span class="muRecipe"> -> </span>result:address:array:character [ <span class="Constant">local-scope</span> +<span class="CommentedCode">#? $print [append text to text], 10/newline</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># result = new character[a.length + b.length]</span> - a:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> a-len:number<span class="Special"> <- </span>length *a - b:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> b-len:number<span class="Special"> <- </span>length *b result-len:number<span class="Special"> <- </span>add a-len, b-len - result:address:array:character<span class="Special"> <- </span>new <span class="Constant">character:type</span>, result-len + result<span class="Special"> <- </span>new <span class="Constant">character:type</span>, result-len <span class="Comment"># copy a into result</span> result-idx:number<span class="Special"> <- </span>copy <span class="Constant">0</span> i:number<span class="Special"> <- </span>copy <span class="Constant">0</span> @@ -416,37 +441,34 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } result-idx<span class="Special"> <- </span>add result-idx, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> result ] -<span class="muScenario">scenario</span> string-append-1 [ +<span class="muScenario">scenario</span> text-append-1 [ run [ <span class="Constant">1</span>:address:array:character/<span class="Special">raw <- </span>new <span class="Constant">[hello,]</span> <span class="Constant">2</span>:address:array:character/<span class="Special">raw <- </span>new <span class="Constant">[ world!]</span> - <span class="Constant">3</span>:address:array:character/<span class="Special">raw <- </span>string-append <span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>, <span class="Constant">2</span>:address:array:character/<span class="Special">raw</span> + <span class="Constant">3</span>:address:array:character/<span class="Special">raw <- </span>append <span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>, <span class="Constant">2</span>:address:array:character/<span class="Special">raw</span> <span class="Constant">4</span>:array:character/<span class="Special">raw <- </span>copy *<span class="Constant">3</span>:address:array:character/<span class="Special">raw</span> ] memory-should-contain [ - <span class="Constant">4</span>:string<span class="Special"> <- </span><span class="Constant">[hello, world!]</span> + <span class="Constant">4</span>:array:character<span class="Special"> <- </span><span class="Constant">[hello, world!]</span> ] ] -<span class="muScenario">scenario</span> replace-character-in-string [ +<span class="muScenario">scenario</span> replace-character-in-text [ 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">1</span>:address:array:character/<span class="Special">raw <- </span>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="Constant">2</span>:array:character<span class="Special"> <- </span><span class="Constant">[azc]</span> ] ] -<span class="muRecipe">recipe</span> string-replace [ +<span class="muRecipe">recipe</span> replace s:address:array:character, oldc:character, newc:character<span class="muRecipe"> -> </span>s:address:array:character [ <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> + <span class="Constant">load-ingredients</span> from:number, _<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># default to 0</span> len:number<span class="Special"> <- </span>length *s i:number<span class="Special"> <- </span>find-next s, oldc, from @@ -455,64 +477,62 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } 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> + s<span class="Special"> <- </span>replace s, oldc, newc, i ] <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">1</span>:address:array:character/<span class="Special">raw <- </span>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="Constant">2</span>:array:character<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">1</span>:address:array:character/<span class="Special">raw <- </span>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="Constant">2</span>:array:character<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">1</span>:address:array:character/<span class="Special">raw <- </span>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="Constant">2</span>:array:character<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">1</span>:address:array:character/<span class="Special">raw <- </span>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="Constant">2</span>:array:character<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 [ +<span class="muRecipe">recipe</span> interpolate template:address:array:character<span class="muRecipe"> -> </span>result:address:array:character [ <span class="Constant">local-scope</span> - template:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># consume just the template</span> <span class="Comment"># compute result-len, space to allocate for result</span> tem-len:number<span class="Special"> <- </span>length *template result-len:number<span class="Special"> <- </span>copy tem-len <span class="Delimiter">{</span> - <span class="Comment"># while arg received</span> + <span class="Comment"># while ingredients remain</span> a:address:array:character, arg-received?:boolean<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="muControl">break-unless</span> arg-received? <span class="Comment"># result-len = result-len + arg.length - 1 (for the 'underscore' being replaced)</span> @@ -579,7 +599,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } result-idx<span class="Special"> <- </span>add result-idx, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> result ] <span class="muScenario">scenario</span> interpolate-works [ @@ -590,7 +609,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant">4</span>:array:character/<span class="Special">raw <- </span>copy *<span class="Constant">3</span>:address:array:character/<span class="Special">raw</span> ] memory-should-contain [ - <span class="Constant">4</span>:string<span class="Special"> <- </span><span class="Constant">[abc def]</span> + <span class="Constant">4</span>:array:character<span class="Special"> <- </span><span class="Constant">[abc def]</span> ] ] @@ -602,7 +621,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant">4</span>:array:character/<span class="Special">raw <- </span>copy *<span class="Constant">3</span>:address:array:character/<span class="Special">raw</span> ] memory-should-contain [ - <span class="Constant">4</span>:string<span class="Special"> <- </span><span class="Constant">[abc, hello!]</span> + <span class="Constant">4</span>:array:character<span class="Special"> <- </span><span class="Constant">[abc, hello!]</span> <span class="Constant">16</span><span class="Special"> <- </span><span class="Constant">0</span> <span class="Comment"># out of bounds</span> ] ] @@ -615,77 +634,75 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant">4</span>:array:character/<span class="Special">raw <- </span>copy *<span class="Constant">3</span>:address:array:character/<span class="Special">raw</span> ] memory-should-contain [ - <span class="Constant">4</span>:string<span class="Special"> <- </span><span class="Constant">[hello, abc]</span> + <span class="Constant">4</span>:array:character<span class="Special"> <- </span><span class="Constant">[hello, abc]</span> ] ] <span class="Comment"># result:boolean <- space? c:character</span> -<span class="muRecipe">recipe</span> space? [ +<span class="muRecipe">recipe</span> space? c:character<span class="muRecipe"> -> </span>result:boolean [ <span class="Constant">local-scope</span> - c:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># most common case first</span> - result:boolean<span class="Special"> <- </span>equal c, <span class="Constant">32/space</span> - <span class="muControl">reply-if</span> result, result + result<span class="Special"> <- </span>equal c, <span class="Constant">32/space</span> + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">10/newline</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">9/tab</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">13/carriage-return</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result <span class="Comment"># remaining uncommon cases in sorted order</span> <span class="Comment"># <a href="http://unicode.org">http://unicode.org</a> code-points in unicode-set Z and Pattern_White_Space</span> result<span class="Special"> <- </span>equal c, <span class="Constant">11/ctrl-k</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">12/ctrl-l</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">133/ctrl-0085</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">160/no-break-space</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">5760/ogham-space-mark</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">8192/en-quad</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">8193/em-quad</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">8194/en-space</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">8195/em-space</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">8196/three-per-em-space</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">8197/four-per-em-space</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">8198/six-per-em-space</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">8199/figure-space</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">8200/punctuation-space</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">8201/thin-space</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">8202/hair-space</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">8206/left-to-right</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">8207/right-to-left</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">8232/line-separator</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">8233/paragraph-separator</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">8239/narrow-no-break-space</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">8287/medium-mathematical-space</span> - <span class="muControl">reply-if</span> result, result + <span class="muControl">reply-if</span> result result<span class="Special"> <- </span>equal c, <span class="Constant">12288/ideographic-space</span> - <span class="muControl">reply</span> result ] -<span class="Comment"># result:address:array:character <- trim s:address:array:character</span> -<span class="muRecipe">recipe</span> trim [ +<span class="muRecipe">recipe</span> trim s:address:array:character<span class="muRecipe"> -> </span>result:address:array:character [ <span class="Constant">local-scope</span> - s:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> len:number<span class="Special"> <- </span>length *s <span class="Comment"># left trim: compute start</span> start:number<span class="Special"> <- </span>copy <span class="Constant">0</span> @@ -693,8 +710,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">{</span> at-end?:boolean<span class="Special"> <- </span>greater-or-equal start, len <span class="muControl">break-unless</span> at-end? - result:address:array:character<span class="Special"> <- </span>new <span class="Constant">character:type</span>, <span class="Constant">0</span> - <span class="muControl">reply</span> result + result<span class="Special"> <- </span>new <span class="Constant">character:type</span>, <span class="Constant">0</span> + <span class="muControl">reply</span> <span class="Delimiter">}</span> curr:character<span class="Special"> <- </span>index *s, start whitespace?:boolean<span class="Special"> <- </span>space? curr @@ -731,7 +748,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } j<span class="Special"> <- </span>add j, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> result ] <span class="muScenario">scenario</span> trim-unmodified [ @@ -741,7 +757,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant">3</span>:array:character<span class="Special"> <- </span>copy *<span class="Constant">2</span>:address:array:character ] memory-should-contain [ - <span class="Constant">3</span>:string<span class="Special"> <- </span><span class="Constant">[abc]</span> + <span class="Constant">3</span>:array:character<span class="Special"> <- </span><span class="Constant">[abc]</span> ] ] @@ -752,7 +768,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant">3</span>:array:character<span class="Special"> <- </span>copy *<span class="Constant">2</span>:address:array:character ] memory-should-contain [ - <span class="Constant">3</span>:string<span class="Special"> <- </span><span class="Constant">[abc]</span> + <span class="Constant">3</span>:array:character<span class="Special"> <- </span><span class="Constant">[abc]</span> ] ] @@ -763,7 +779,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant">3</span>:array:character<span class="Special"> <- </span>copy *<span class="Constant">2</span>:address:array:character ] memory-should-contain [ - <span class="Constant">3</span>:string<span class="Special"> <- </span><span class="Constant">[abc]</span> + <span class="Constant">3</span>:array:character<span class="Special"> <- </span><span class="Constant">[abc]</span> ] ] @@ -774,7 +790,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant">3</span>:array:character<span class="Special"> <- </span>copy *<span class="Constant">2</span>:address:array:character ] memory-should-contain [ - <span class="Constant">3</span>:string<span class="Special"> <- </span><span class="Constant">[abc]</span> + <span class="Constant">3</span>:array:character<span class="Special"> <- </span><span class="Constant">[abc]</span> ] ] @@ -786,12 +802,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant">3</span>:array:character<span class="Special"> <- </span>copy *<span class="Constant">2</span>:address:array:character ] memory-should-contain [ - <span class="Constant">3</span>:string<span class="Special"> <- </span><span class="Constant">[abc]</span> + <span class="Constant">3</span>:array:character<span class="Special"> <- </span><span class="Constant">[abc]</span> ] ] -<span class="Comment"># next-index:number <- find-next text:address:array:character, pattern:character, idx:number</span> -<span class="muRecipe">recipe</span> find-next [ +<span class="muRecipe">recipe</span> find-next text:address:array:character, pattern:character, idx:number<span class="muRecipe"> -> </span>next-index:number [ <span class="Constant">local-scope</span> text:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> pattern:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -809,7 +824,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">reply</span> idx ] -<span class="muScenario">scenario</span> string-find-next [ +<span class="muScenario">scenario</span> text-find-next [ run [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a/b]</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>, <span class="Constant">0/start-index</span> @@ -819,7 +834,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<span class="muScenario">scenario</span> string-find-next-empty [ +<span class="muScenario">scenario</span> text-find-next-empty [ run [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>, <span class="Constant">0/start-index</span> @@ -829,7 +844,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<span class="muScenario">scenario</span> string-find-next-initial [ +<span class="muScenario">scenario</span> text-find-next-initial [ run [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[/abc]</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>, <span class="Constant">0/start-index</span> @@ -839,7 +854,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<span class="muScenario">scenario</span> string-find-next-final [ +<span class="muScenario">scenario</span> text-find-next-final [ run [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc/]</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>, <span class="Constant">0/start-index</span> @@ -849,7 +864,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<span class="muScenario">scenario</span> string-find-next-missing [ +<span class="muScenario">scenario</span> text-find-next-missing [ run [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>, <span class="Constant">0/start-index</span> @@ -859,7 +874,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<span class="muScenario">scenario</span> string-find-next-invalid-index [ +<span class="muScenario">scenario</span> text-find-next-invalid-index [ run [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>, <span class="Constant">4/start-index</span> @@ -869,7 +884,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<span class="muScenario">scenario</span> string-find-next-first [ +<span class="muScenario">scenario</span> text-find-next-first [ run [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ab/c/]</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>, <span class="Constant">0/start-index</span> @@ -879,7 +894,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<span class="muScenario">scenario</span> string-find-next-second [ +<span class="muScenario">scenario</span> text-find-next-second [ run [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ab/c/]</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>, <span class="Constant">3/start-index</span> @@ -889,19 +904,16 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<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"># search for a pattern of multiple characters</span> <span class="Comment"># fairly dumb algorithm</span> -<span class="muRecipe">recipe</span> find-substring [ +<span class="muRecipe">recipe</span> find-next text:address:array:character, pattern:address:array:character, idx:number<span class="muRecipe"> -> </span>next-index:number [ <span class="Constant">local-scope</span> - text:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - pattern:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - idx:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> first:character<span class="Special"> <- </span>index *pattern, <span class="Constant">0</span> <span class="Comment"># repeatedly check for match at current idx</span> len:number<span class="Special"> <- </span>length *text <span class="Delimiter">{</span> - <span class="Comment"># does some unnecessary work checking for substrings even when there isn't enough of text left</span> + <span class="Comment"># does some unnecessary work checking even when there isn't enough of text left</span> done?:boolean<span class="Special"> <- </span>greater-or-equal idx, len <span class="muControl">break-if</span> done? found?:boolean<span class="Special"> <- </span>match-at text, pattern, idx @@ -914,68 +926,65 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">reply</span> idx ] -<span class="muScenario">scenario</span> find-substring-1 [ +<span class="muScenario">scenario</span> find-next-text-1 [ run [ <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">[bc]</span> - <span class="Constant">3</span>:number<span class="Special"> <- </span>find-substring <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">0</span> + <span class="Constant">3</span>:number<span class="Special"> <- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">0</span> ] memory-should-contain [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span> ] ] -<span class="muScenario">scenario</span> find-substring-2 [ +<span class="muScenario">scenario</span> find-next-text-2 [ run [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcd]</span> <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[bc]</span> - <span class="Constant">3</span>:number<span class="Special"> <- </span>find-substring <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">1</span> + <span class="Constant">3</span>:number<span class="Special"> <- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">1</span> ] memory-should-contain [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span> ] ] -<span class="muScenario">scenario</span> find-substring-no-match [ +<span class="muScenario">scenario</span> find-next-no-match [ run [ <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">[bd]</span> - <span class="Constant">3</span>:number<span class="Special"> <- </span>find-substring <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">0</span> + <span class="Constant">3</span>:number<span class="Special"> <- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">0</span> ] memory-should-contain [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">3</span> <span class="Comment"># not found</span> ] ] -<span class="muScenario">scenario</span> find-substring-suffix-match [ +<span class="muScenario">scenario</span> find-next-suffix-match [ run [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcd]</span> <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[cd]</span> - <span class="Constant">3</span>:number<span class="Special"> <- </span>find-substring <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">0</span> + <span class="Constant">3</span>:number<span class="Special"> <- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">0</span> ] memory-should-contain [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">2</span> ] ] -<span class="muScenario">scenario</span> find-substring-suffix-match-2 [ +<span class="muScenario">scenario</span> find-next-suffix-match-2 [ run [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcd]</span> <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[cde]</span> - <span class="Constant">3</span>:number<span class="Special"> <- </span>find-substring <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">0</span> + <span class="Constant">3</span>:number<span class="Special"> <- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">0</span> ] memory-should-contain [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">4</span> <span class="Comment"># not found</span> ] ] -<span class="Comment"># result:boolean <- match-at text:address:array:character, pattern:address:array:character, idx:number</span> -<span class="Comment"># checks if substring matches at index 'idx'</span> -<span class="muRecipe">recipe</span> match-at [ +<span class="Comment"># checks if pattern matches at index 'idx'</span> +<span class="muRecipe">recipe</span> match-at text:address:array:character, pattern:address:array:character, idx:number<span class="muRecipe"> -> </span>result:boolean [ <span class="Constant">local-scope</span> - text:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - pattern:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - idx:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> pattern-len:number<span class="Special"> <- </span>length *pattern <span class="Comment"># check that there's space left for the pattern</span> <span class="Delimiter">{</span> @@ -1004,7 +1013,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">reply</span> <span class="Constant">1/found</span> ] -<span class="muScenario">scenario</span> match-at-checks-substring-at-index [ +<span class="muScenario">scenario</span> match-at-checks-pattern-at-index [ run [ <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">[ab]</span> @@ -1086,7 +1095,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant">3</span>:boolean<span class="Special"> <- </span>match-at <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">1</span> ] memory-should-contain [ - <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Comment"># matches inner substring</span> + <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Comment"># match</span> ] ] @@ -1101,18 +1110,16 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<span class="Comment"># result:address:array:address:array:character <- split s:address:array:character, delim:character</span> -<span class="muRecipe">recipe</span> split [ +<span class="muRecipe">recipe</span> split s:address:array:character, delim:character<span class="muRecipe"> -> </span>result:address:array:address:array:character [ <span class="Constant">local-scope</span> - s:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - delim:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - <span class="Comment"># empty string? return empty array</span> + <span class="Constant">load-ingredients</span> + <span class="Comment"># empty text? return empty array</span> len:number<span class="Special"> <- </span>length *s <span class="Delimiter">{</span> empty?:boolean<span class="Special"> <- </span>equal len, <span class="Constant">0</span> <span class="muControl">break-unless</span> empty? - result:address:array:address:array:character<span class="Special"> <- </span>new <span class="Constant">location:type</span>, <span class="Constant">0</span> - <span class="muControl">reply</span> result + result<span class="Special"> <- </span>new <span class="Constant">location:type</span>, <span class="Constant">0</span> + <span class="muControl">reply</span> <span class="Delimiter">}</span> <span class="Comment"># count #pieces we need room for</span> count:number<span class="Special"> <- </span>copy <span class="Constant">1</span> <span class="Comment"># n delimiters = n+1 pieces</span> @@ -1126,7 +1133,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">loop</span> <span class="Delimiter">}</span> <span class="Comment"># allocate space</span> - result:address:array:address:array:character<span class="Special"> <- </span>new <span class="Constant">location:type</span>, count + result<span class="Special"> <- </span>new <span class="Constant">location:type</span>, count <span class="Comment"># repeatedly copy slices start..end until delimiter into result[curr-result]</span> curr-result:number<span class="Special"> <- </span>copy <span class="Constant">0</span> start:number<span class="Special"> <- </span>copy <span class="Constant">0</span> @@ -1137,16 +1144,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } end:number<span class="Special"> <- </span>find-next s, delim, start <span class="Comment"># copy start..end into result[curr-result]</span> dest:address:address:array:character<span class="Special"> <- </span>index-address *result, curr-result - *dest<span class="Special"> <- </span>string-copy s, start, end + *dest<span class="Special"> <- </span>copy s, start, end <span class="Comment"># slide over to next slice</span> start<span class="Special"> <- </span>add end, <span class="Constant">1</span> curr-result<span class="Special"> <- </span>add curr-result, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> result ] -<span class="muScenario">scenario</span> string-split-1 [ +<span class="muScenario">scenario</span> text-split-1 [ run [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a/b]</span> <span class="Constant">2</span>:address:array:address:array:character<span class="Special"> <- </span>split <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span> @@ -1158,12 +1164,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] memory-should-contain [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">2</span> <span class="Comment"># length of result</span> - <span class="Constant">10</span>:string<span class="Special"> <- </span><span class="Constant">[a]</span> - <span class="Constant">20</span>:string<span class="Special"> <- </span><span class="Constant">[b]</span> + <span class="Constant">10</span>:array:character<span class="Special"> <- </span><span class="Constant">[a]</span> + <span class="Constant">20</span>:array:character<span class="Special"> <- </span><span class="Constant">[b]</span> ] ] -<span class="muScenario">scenario</span> string-split-2 [ +<span class="muScenario">scenario</span> text-split-2 [ run [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a/b/c]</span> <span class="Constant">2</span>:address:array:address:array:character<span class="Special"> <- </span>split <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span> @@ -1177,13 +1183,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] memory-should-contain [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">3</span> <span class="Comment"># length of result</span> - <span class="Constant">10</span>:string<span class="Special"> <- </span><span class="Constant">[a]</span> - <span class="Constant">20</span>:string<span class="Special"> <- </span><span class="Constant">[b]</span> - <span class="Constant">30</span>:string<span class="Special"> <- </span><span class="Constant">[c]</span> + <span class="Constant">10</span>:array:character<span class="Special"> <- </span><span class="Constant">[a]</span> + <span class="Constant">20</span>:array:character<span class="Special"> <- </span><span class="Constant">[b]</span> + <span class="Constant">30</span>:array:character<span class="Special"> <- </span><span class="Constant">[c]</span> ] ] -<span class="muScenario">scenario</span> string-split-missing [ +<span class="muScenario">scenario</span> text-split-missing [ run [ <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:address:array:character<span class="Special"> <- </span>split <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span> @@ -1193,11 +1199,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] memory-should-contain [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Comment"># length of result</span> - <span class="Constant">10</span>:string<span class="Special"> <- </span><span class="Constant">[abc]</span> + <span class="Constant">10</span>:array:character<span class="Special"> <- </span><span class="Constant">[abc]</span> ] ] -<span class="muScenario">scenario</span> string-split-empty [ +<span class="muScenario">scenario</span> text-split-empty [ run [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span> <span class="Constant">2</span>:address:array:address:array:character<span class="Special"> <- </span>split <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span> @@ -1208,7 +1214,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<span class="muScenario">scenario</span> string-split-empty-piece [ +<span class="muScenario">scenario</span> text-split-empty-piece [ run [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a/b//c]</span> <span class="Constant">2</span>:address:array:address:array:character<span class="Special"> <- </span>split <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span> @@ -1224,35 +1230,32 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] memory-should-contain [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">4</span> <span class="Comment"># length of result</span> - <span class="Constant">10</span>:string<span class="Special"> <- </span><span class="Constant">[a]</span> - <span class="Constant">20</span>:string<span class="Special"> <- </span><span class="Constant">[b]</span> - <span class="Constant">30</span>:string<span class="Special"> <- </span><span class="Constant">[]</span> - <span class="Constant">40</span>:string<span class="Special"> <- </span><span class="Constant">[c]</span> + <span class="Constant">10</span>:array:character<span class="Special"> <- </span><span class="Constant">[a]</span> + <span class="Constant">20</span>:array:character<span class="Special"> <- </span><span class="Constant">[b]</span> + <span class="Constant">30</span>:array:character<span class="Special"> <- </span><span class="Constant">[]</span> + <span class="Constant">40</span>:array:character<span class="Special"> <- </span><span class="Constant">[c]</span> ] ] -<span class="Comment"># x:address:array:character, y:address:array:character <- split-first text:address:array:character, delim:character</span> -<span class="muRecipe">recipe</span> split-first [ +<span class="muRecipe">recipe</span> split-first text:address:array:character, delim:character<span class="muRecipe"> -> </span>x:address:array:character, y:address:array:character [ <span class="Constant">local-scope</span> - text:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - delim:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - <span class="Comment"># empty string? return empty strings</span> + <span class="Constant">load-ingredients</span> + <span class="Comment"># empty text? return empty texts</span> len:number<span class="Special"> <- </span>length *text <span class="Delimiter">{</span> empty?:boolean<span class="Special"> <- </span>equal len, <span class="Constant">0</span> <span class="muControl">break-unless</span> empty? x:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span> y:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span> - <span class="muControl">reply</span> x, y + <span class="muControl">reply</span> <span class="Delimiter">}</span> idx:number<span class="Special"> <- </span>find-next text, delim, <span class="Constant">0</span> - x:address:array:character<span class="Special"> <- </span>string-copy text, <span class="Constant">0</span>, idx + x:address:array:character<span class="Special"> <- </span>copy text, <span class="Constant">0</span>, idx idx<span class="Special"> <- </span>add idx, <span class="Constant">1</span> - y:address:array:character<span class="Special"> <- </span>string-copy text, idx, len - <span class="muControl">reply</span> x, y + y:address:array:character<span class="Special"> <- </span>copy text, idx, len ] -<span class="muScenario">scenario</span> string-split-first [ +<span class="muScenario">scenario</span> text-split-first [ run [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a/b]</span> <span class="Constant">2</span>:address:array:character, <span class="Constant">3</span>:address:array:character<span class="Special"> <- </span>split-first <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span> @@ -1260,18 +1263,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant">20</span>:array:character<span class="Special"> <- </span>copy *<span class="Constant">3</span>:address:array:character ] memory-should-contain [ - <span class="Constant">10</span>:string<span class="Special"> <- </span><span class="Constant">[a]</span> - <span class="Constant">20</span>:string<span class="Special"> <- </span><span class="Constant">[b]</span> + <span class="Constant">10</span>:array:character<span class="Special"> <- </span><span class="Constant">[a]</span> + <span class="Constant">20</span>:array:character<span class="Special"> <- </span><span class="Constant">[b]</span> ] ] -<span class="Comment"># result:address:array:character <- string-copy buf:address:array:character, start:number, end:number</span> -<span class="Comment"># todo: make this generic</span> -<span class="muRecipe">recipe</span> string-copy [ +<span class="muRecipe">recipe</span> copy buf:address:array:character, start:number, end:number<span class="muRecipe"> -> </span>result:address:array:character [ <span class="Constant">local-scope</span> - buf:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - start:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - end:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># if end is out of bounds, trim it</span> len:number<span class="Special"> <- </span>length *buf end:number<span class="Special"> <- </span>min len, end @@ -1291,46 +1290,44 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } dest-idx<span class="Special"> <- </span>add dest-idx, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> result ] -<span class="muScenario">scenario</span> string-copy-copies-substring [ +<span class="muScenario">scenario</span> text-copy-copies-partial-text [ run [ <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>string-copy <span class="Constant">1</span>:address:array:character, <span class="Constant">1</span>, <span class="Constant">3</span> + <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>copy <span class="Constant">1</span>:address:array:character, <span class="Constant">1</span>, <span class="Constant">3</span> <span class="Constant">3</span>:array:character<span class="Special"> <- </span>copy *<span class="Constant">2</span>:address:array:character ] memory-should-contain [ - <span class="Constant">3</span>:string<span class="Special"> <- </span><span class="Constant">[bc]</span> + <span class="Constant">3</span>:array:character<span class="Special"> <- </span><span class="Constant">[bc]</span> ] ] -<span class="muScenario">scenario</span> string-copy-out-of-bounds [ +<span class="muScenario">scenario</span> text-copy-out-of-bounds [ run [ <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>string-copy <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>, <span class="Constant">4</span> + <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>copy <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>, <span class="Constant">4</span> <span class="Constant">3</span>:array:character<span class="Special"> <- </span>copy *<span class="Constant">2</span>:address:array:character ] memory-should-contain [ - <span class="Constant">3</span>:string<span class="Special"> <- </span><span class="Constant">[c]</span> + <span class="Constant">3</span>:array:character<span class="Special"> <- </span><span class="Constant">[c]</span> ] ] -<span class="muScenario">scenario</span> string-copy-out-of-bounds-2 [ +<span class="muScenario">scenario</span> text-copy-out-of-bounds-2 [ run [ <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>string-copy <span class="Constant">1</span>:address:array:character, <span class="Constant">3</span>, <span class="Constant">3</span> + <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>copy <span class="Constant">1</span>:address:array:character, <span class="Constant">3</span>, <span class="Constant">3</span> <span class="Constant">3</span>:array:character<span class="Special"> <- </span>copy *<span class="Constant">2</span>:address:array:character ] memory-should-contain [ - <span class="Constant">3</span>:string<span class="Special"> <- </span><span class="Constant">[]</span> + <span class="Constant">3</span>:array:character<span class="Special"> <- </span><span class="Constant">[]</span> ] ] -<span class="muRecipe">recipe</span> min [ +<span class="muRecipe">recipe</span> min x:number, y:number<span class="muRecipe"> -> </span>z:number [ <span class="Constant">local-scope</span> - x:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - y:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Delimiter">{</span> return-x?:boolean<span class="Special"> <- </span>lesser-than x, y <span class="muControl">break-if</span> return-x? @@ -1339,10 +1336,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">reply</span> x ] -<span class="muRecipe">recipe</span> max [ +<span class="muRecipe">recipe</span> max x:number, y:number<span class="muRecipe"> -> </span>z:number [ <span class="Constant">local-scope</span> - x:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - y:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Delimiter">{</span> return-x?:boolean<span class="Special"> <- </span>greater-than x, y <span class="muControl">break-if</span> return-x? diff --git a/html/071channel.mu.html b/html/071channel.mu.html index 1bddb78c..ec4fc68d 100644 --- a/html/071channel.mu.html +++ b/html/071channel.mu.html @@ -67,10 +67,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] <span class="Comment"># result:address:channel <- new-channel capacity:number</span> -<span class="muRecipe">recipe</span> new-channel [ +<span class="muRecipe">recipe</span> new-channel capacity:number<span class="muRecipe"> -> </span>result:address:channel [ <span class="Constant">local-scope</span> - <span class="Comment"># result = new channel</span> - result:address:channel<span class="Special"> <- </span>new <span class="Constant">channel:type</span> + <span class="Constant">load-ingredients</span> + result<span class="Special"> <- </span>new <span class="Constant">channel:type</span> <span class="Comment"># result.first-full = 0</span> full:address:number<span class="Special"> <- </span>get-address *result, <span class="Constant">first-full:offset</span> *full<span class="Special"> <- </span>copy <span class="Constant">0</span> @@ -78,18 +78,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } free:address:number<span class="Special"> <- </span>get-address *result, <span class="Constant">first-free:offset</span> *free<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># result.data = new location[ingredient+1]</span> - capacity:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> capacity<span class="Special"> <- </span>add capacity, <span class="Constant">1</span> <span class="Comment"># unused slot for 'full?' below</span> dest:address:address:array:character<span class="Special"> <- </span>get-address *result, <span class="Constant">data:offset</span> *dest<span class="Special"> <- </span>new <span class="Constant">character:type</span>, capacity - <span class="muControl">reply</span> result ] -<span class="Comment"># chan <- write chan:address:channel, val:character</span> -<span class="muRecipe">recipe</span> write [ +<span class="muRecipe">recipe</span> write chan:address:channel, val:character<span class="muRecipe"> -> </span>chan:address:channel [ <span class="Constant">local-scope</span> - chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - val:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Delimiter">{</span> <span class="Comment"># block if chan is full</span> full:boolean<span class="Special"> <- </span>channel-full? chan @@ -111,13 +107,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">break-unless</span> at-end? *free<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> chan/same-as-ingredient:<span class="Constant">0</span> ] -<span class="Comment"># result:character, chan <- read chan:address:channel</span> -<span class="muRecipe">recipe</span> read [ +<span class="muRecipe">recipe</span> read chan:address:channel<span class="muRecipe"> -> </span>result:character, chan:address:channel [ <span class="Constant">local-scope</span> - chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Delimiter">{</span> <span class="Comment"># block if chan is empty</span> empty?:boolean<span class="Special"> <- </span>channel-empty? chan @@ -128,7 +122,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment"># read result</span> full:address:number<span class="Special"> <- </span>get-address *chan, <span class="Constant">first-full:offset</span> circular-buffer:address:array:character<span class="Special"> <- </span>get *chan, <span class="Constant">data:offset</span> - result:character<span class="Special"> <- </span>index *circular-buffer, *full + result<span class="Special"> <- </span>index *circular-buffer, *full <span class="Comment"># mark its slot as empty</span> *full<span class="Special"> <- </span>add *full, <span class="Constant">1</span> <span class="Delimiter">{</span> @@ -138,18 +132,16 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">break-unless</span> at-end? *full<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> result, chan/same-as-ingredient:<span class="Constant">0</span> ] -<span class="muRecipe">recipe</span> clear-channel [ +<span class="muRecipe">recipe</span> clear-channel chan:address:channel<span class="muRecipe"> -> </span>chan:address:channel [ <span class="Constant">local-scope</span> - chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Delimiter">{</span> empty?:boolean<span class="Special"> <- </span>channel-empty? chan <span class="muControl">break-if</span> empty? _, chan<span class="Special"> <- </span>read chan <span class="Delimiter">}</span> - <span class="muControl">reply</span> chan/same-as-ingredient:<span class="Constant">0</span> ] <span class="muScenario">scenario</span> channel-initialization [ @@ -219,21 +211,20 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="SalientComment">## helpers</span> <span class="Comment"># An empty channel has first-empty and first-full both at the same value.</span> -<span class="muRecipe">recipe</span> channel-empty? [ +<span class="muRecipe">recipe</span> channel-empty? chan:address:channel<span class="muRecipe"> -> </span>result:boolean [ <span class="Constant">local-scope</span> - chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># return chan.first-full == chan.first-free</span> full:number<span class="Special"> <- </span>get *chan, <span class="Constant">first-full:offset</span> free:number<span class="Special"> <- </span>get *chan, <span class="Constant">first-free:offset</span> - result:boolean<span class="Special"> <- </span>equal full, free - <span class="muControl">reply</span> result + result<span class="Special"> <- </span>equal full, free ] <span class="Comment"># A full channel has first-empty just before first-full, wasting one slot.</span> <span class="Comment"># (Other alternatives: <a href="https://en.wikipedia.org/wiki/Circular_buffer#Full_.2F_Empty_Buffer_Distinction)">https://en.wikipedia.org/wiki/Circular_buffer#Full_.2F_Empty_Buffer_Distinction)</a></span> -<span class="muRecipe">recipe</span> channel-full? [ +<span class="muRecipe">recipe</span> channel-full? chan:address:channel<span class="muRecipe"> -> </span>result:boolean [ <span class="Constant">local-scope</span> - chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># tmp = chan.first-free + 1</span> tmp:number<span class="Special"> <- </span>get *chan, <span class="Constant">first-free:offset</span> tmp<span class="Special"> <- </span>add tmp, <span class="Constant">1</span> @@ -246,17 +237,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">}</span> <span class="Comment"># return chan.first-full == tmp</span> full:number<span class="Special"> <- </span>get *chan, <span class="Constant">first-full:offset</span> - result:boolean<span class="Special"> <- </span>equal full, tmp - <span class="muControl">reply</span> result + result<span class="Special"> <- </span>equal full, tmp ] <span class="Comment"># result:number <- channel-capacity chan:address:channel</span> -<span class="muRecipe">recipe</span> channel-capacity [ +<span class="muRecipe">recipe</span> channel-capacity chan:address:channel<span class="muRecipe"> -> </span>result:number [ <span class="Constant">local-scope</span> - chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> q:address:array:character<span class="Special"> <- </span>get *chan, <span class="Constant">data:offset</span> - result:number<span class="Special"> <- </span>length *q - <span class="muControl">reply</span> result + result<span class="Special"> <- </span>length *q ] <span class="muScenario">scenario</span> channel-new-empty-not-full [ @@ -312,11 +301,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] <span class="Comment"># helper for channels of characters in particular</span> -<span class="Comment"># out <- buffer-lines in:address:channel, out:address:channel</span> -<span class="muRecipe">recipe</span> buffer-lines [ +<span class="muRecipe">recipe</span> buffer-lines in:address:channel, out:address:channel<span class="muRecipe"> -> </span>out:address:channel, in:address:channel [ <span class="Constant">local-scope</span> - in:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - out:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># repeat forever</span> <span class="Delimiter">{</span> line:address:buffer<span class="Special"> <- </span>new-buffer, <span class="Constant">30</span> @@ -340,7 +327,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">loop</span> <span class="Constant">+next-character:label</span> <span class="Delimiter">}</span> <span class="Comment"># append anything else</span> - line<span class="Special"> <- </span>buffer-append line, c + line<span class="Special"> <- </span>append line, c line-done?:boolean<span class="Special"> <- </span>equal c, <span class="Constant">10/newline</span> <span class="muControl">break-if</span> line-done? <span class="Comment"># stop buffering on eof (currently only generated by fake console)</span> @@ -362,7 +349,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">}</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> out/same-as-ingredient:<span class="Constant">1</span> ] <span class="muScenario">scenario</span> buffer-lines-blocks-until-newline [ diff --git a/html/073list.mu.html b/html/073list.mu.html index c274436b..a14399dd 100644 --- a/html/073list.mu.html +++ b/html/073list.mu.html @@ -20,6 +20,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .Special { color: #ff6060; } +.CommentedCode { color: #6c6c6c; } .Delimiter { color: #a04060; } --> </style> @@ -85,6 +86,92 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">3</span> ] ] + +<span class="muRecipe">recipe</span> to-text in:address:list:_elem<span class="muRecipe"> -> </span>result:address:array:character [ + <span class="Constant">local-scope</span> +<span class="CommentedCode">#? $print [to text: list], 10/newline</span> + <span class="Constant">load-ingredients</span> + buf:address:buffer<span class="Special"> <- </span>new-buffer <span class="Constant">80</span> + buf<span class="Special"> <- </span>to-buffer in, buf + result<span class="Special"> <- </span>buffer-to-array buf +] + +<span class="Comment"># variant of 'to-text' which stops printing after a few elements (and so is robust to cycles)</span> +<span class="muRecipe">recipe</span> to-text-line in:address:list:_elem<span class="muRecipe"> -> </span>result:address:array:character [ + <span class="Constant">local-scope</span> +<span class="CommentedCode">#? $print [to text line: list], 10/newline</span> + <span class="Constant">load-ingredients</span> + buf:address:buffer<span class="Special"> <- </span>new-buffer <span class="Constant">80</span> + buf<span class="Special"> <- </span>to-buffer in, buf, <span class="Constant">6</span> <span class="Comment"># max elements to display</span> + result<span class="Special"> <- </span>buffer-to-array buf +] + +<span class="muRecipe">recipe</span> to-buffer in:address:list:_elem, buf:address:buffer<span class="muRecipe"> -> </span>buf:address:buffer [ + <span class="Constant">local-scope</span> +<span class="CommentedCode">#? $print [to buffer: list], 10/newline</span> + <span class="Constant">load-ingredients</span> + <span class="Delimiter">{</span> + <span class="muControl">break-if</span> in + $print <span class="Constant">[000]</span>, <span class="Constant">10/newline</span> + buf<span class="Special"> <- </span>append buf, <span class="Constant">48/0</span> + <span class="muControl">reply</span> + <span class="Delimiter">}</span> + <span class="Comment"># append in.value to buf</span> + val:_elem<span class="Special"> <- </span>get *in, <span class="Constant">value:offset</span> + buf<span class="Special"> <- </span>append buf, val + <span class="Comment"># now prepare next</span> + next:address:list:_elem<span class="Special"> <- </span>rest in + nextn:number<span class="Special"> <- </span>copy next +<span class="CommentedCode">#? buf <- append buf, nextn</span> + <span class="muControl">reply-unless</span> next + space:character<span class="Special"> <- </span>copy <span class="Constant">32/space</span> + buf<span class="Special"> <- </span>append buf, space:character + s:address:array:character<span class="Special"> <- </span>new <span class="Constant">[-> ]</span> + n:number<span class="Special"> <- </span>length *s + buf<span class="Special"> <- </span>append buf, s + <span class="Comment"># and recurse</span> + remaining:number, optional-ingredient-found?:boolean<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Delimiter">{</span> + <span class="muControl">break-if</span> optional-ingredient-found? + <span class="Comment"># unlimited recursion</span> + buf<span class="Special"> <- </span>to-buffer next, buf + <span class="muControl">reply</span> + <span class="Delimiter">}</span> + <span class="Delimiter">{</span> + <span class="muControl">break-unless</span> remaining + <span class="Comment"># limited recursion</span> + remaining<span class="Special"> <- </span>subtract remaining, <span class="Constant">1</span> + buf<span class="Special"> <- </span>to-buffer next, buf, remaining + <span class="muControl">reply</span> + <span class="Delimiter">}</span> + <span class="Comment"># past recursion depth; insert ellipses and stop</span> + s:address:array:character<span class="Special"> <- </span>new <span class="Constant">[...]</span> + append buf, s +] + +<span class="muScenario">scenario</span> stash-on-list-converts-to-text [ + run [ + x:address:list:number<span class="Special"> <- </span>push <span class="Constant">4</span>, <span class="Constant">0</span> + x<span class="Special"> <- </span>push <span class="Constant">5</span>, x + x<span class="Special"> <- </span>push <span class="Constant">6</span>, x + stash <span class="Constant">[foo foo]</span>, x + ] + trace-should-contain [ + app: foo foo <span class="Constant">6</span><span class="muRecipe"> -> </span><span class="Constant">5</span><span class="muRecipe"> -> </span><span class="Constant">4</span> + ] +] + +<span class="muScenario">scenario</span> stash-handles-list-with-cycle [ + run [ + x:address:list:number<span class="Special"> <- </span>push <span class="Constant">4</span>, <span class="Constant">0</span> + y:address:address:list:number<span class="Special"> <- </span>get-address *x, <span class="Constant">next:offset</span> + *y<span class="Special"> <- </span>copy x + stash <span class="Constant">[foo foo]</span>, x + ] + trace-should-contain [ + app: foo foo <span class="Constant">4</span><span class="muRecipe"> -> </span><span class="Constant">4</span><span class="muRecipe"> -> </span><span class="Constant">4</span><span class="muRecipe"> -> </span><span class="Constant">4</span><span class="muRecipe"> -> </span><span class="Constant">4</span><span class="muRecipe"> -> </span><span class="Constant">4</span><span class="muRecipe"> -> </span><span class="Constant">4</span><span class="muRecipe"> -> </span>... + ] +] </pre> </body> </html> diff --git a/html/076stream.mu.html b/html/076stream.mu.html index feaa978b..91861d7d 100644 --- a/html/076stream.mu.html +++ b/html/076stream.mu.html @@ -13,7 +13,6 @@ 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; } .muData { color: #ffff00; } .Comment { color: #9090ff; } @@ -30,49 +29,46 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } </head> <body> <pre id='vimCodeElement'> -<span class="Comment"># new type to help incrementally read strings</span> +<span class="Comment"># new type to help incrementally read texts (arrays of characters)</span> <span class="muData">container</span> stream [ index:number data:address:array:character ] -<span class="muRecipe">recipe</span> new-stream [ +<span class="muRecipe">recipe</span> new-stream s:address:array:character<span class="muRecipe"> -> </span>result:address:stream [ <span class="Constant">local-scope</span> - result:address:stream<span class="Special"> <- </span>new <span class="Constant">stream:type</span> + <span class="Constant">load-ingredients</span> + result<span class="Special"> <- </span>new <span class="Constant">stream:type</span> i:address:number<span class="Special"> <- </span>get-address *result, <span class="Constant">index:offset</span> *i<span class="Special"> <- </span>copy <span class="Constant">0</span> d:address:address:array:character<span class="Special"> <- </span>get-address *result, <span class="Constant">data:offset</span> - *d<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - <span class="muControl">reply</span> result + *d<span class="Special"> <- </span>copy s ] -<span class="muRecipe">recipe</span> rewind-stream [ +<span class="muRecipe">recipe</span> rewind-stream in:address:stream<span class="muRecipe"> -> </span>in:address:stream [ <span class="Constant">local-scope</span> - in:address:stream<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> x:address:number<span class="Special"> <- </span>get-address *in, <span class="Constant">index:offset</span> *x<span class="Special"> <- </span>copy <span class="Constant">0</span> - <span class="muControl">reply</span> in/same-as-arg:<span class="Constant">0</span> ] -<span class="muRecipe">recipe</span> read-line [ +<span class="muRecipe">recipe</span> read-line in:address:stream<span class="muRecipe"> -> </span>result:address:array:character, in:address:stream [ <span class="Constant">local-scope</span> - in:address:stream<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> idx:address:number<span class="Special"> <- </span>get-address *in, <span class="Constant">index:offset</span> s:address:array:character<span class="Special"> <- </span>get *in, <span class="Constant">data:offset</span> next-idx:number<span class="Special"> <- </span>find-next s, <span class="Constant">10/newline</span>, *idx - result:address:array:character<span class="Special"> <- </span>string-copy s, *idx, next-idx + result<span class="Special"> <- </span>copy s, *idx, next-idx *idx<span class="Special"> <- </span>add next-idx, <span class="Constant">1</span> <span class="Comment"># skip newline</span> - <span class="muControl">reply</span> result ] -<span class="muRecipe">recipe</span> end-of-stream? [ +<span class="muRecipe">recipe</span> end-of-stream? in:address:stream<span class="muRecipe"> -> </span>result:boolean [ <span class="Constant">local-scope</span> - in:address:stream<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> idx:number<span class="Special"> <- </span>get *in, <span class="Constant">index:offset</span> s:address:array:character<span class="Special"> <- </span>get *in, <span class="Constant">data:offset</span> len:number<span class="Special"> <- </span>length *s - result:boolean<span class="Special"> <- </span>greater-or-equal idx, len - <span class="muControl">reply</span> result + result<span class="Special"> <- </span>greater-or-equal idx, len ] </pre> </body> diff --git a/html/081print.mu.html b/html/081print.mu.html index 19efbb1c..7bfdc7dc 100644 --- a/html/081print.mu.html +++ b/html/081print.mu.html @@ -48,13 +48,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } color:number ] -<span class="muRecipe">recipe</span> new-fake-screen [ +<span class="muRecipe">recipe</span> new-fake-screen w:number, h:number<span class="muRecipe"> -> </span>result:address:screen [ <span class="Constant">local-scope</span> - result:address:screen<span class="Special"> <- </span>new <span class="Constant">screen:type</span> + <span class="Constant">load-ingredients</span> + result<span class="Special"> <- </span>new <span class="Constant">screen:type</span> width:address:number<span class="Special"> <- </span>get-address *result, <span class="Constant">num-columns:offset</span> - *width<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + *width<span class="Special"> <- </span>copy w height:address:number<span class="Special"> <- </span>get-address *result, <span class="Constant">num-rows:offset</span> - *height<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + *height<span class="Special"> <- </span>copy h row:address:number<span class="Special"> <- </span>get-address *result, <span class="Constant">cursor-row:offset</span> *row<span class="Special"> <- </span>copy <span class="Constant">0</span> column:address:number<span class="Special"> <- </span>get-address *result, <span class="Constant">cursor-column:offset</span> @@ -62,18 +63,17 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } bufsize:number<span class="Special"> <- </span>multiply *width, *height buf:address:address:array:screen-cell<span class="Special"> <- </span>get-address *result, <span class="Constant">data:offset</span> *buf<span class="Special"> <- </span>new <span class="Constant">screen-cell:type</span>, bufsize - clear-screen result - <span class="muControl">reply</span> result + result<span class="Special"> <- </span>clear-screen result ] -<span class="muRecipe">recipe</span> clear-screen [ +<span class="muRecipe">recipe</span> clear-screen screen:address:screen<span class="muRecipe"> -> </span>screen:address:screen [ <span class="Constant">local-scope</span> - sc:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># if x exists</span> <span class="Delimiter">{</span> - <span class="muControl">break-unless</span> sc + <span class="muControl">break-unless</span> screen <span class="Comment"># clear fake screen</span> - buf:address:array:screen-cell<span class="Special"> <- </span>get *sc, <span class="Constant">data:offset</span> + buf:address:array:screen-cell<span class="Special"> <- </span>get *screen, <span class="Constant">data:offset</span> max:number<span class="Special"> <- </span>length *buf i:number<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Delimiter">{</span> @@ -88,32 +88,31 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">loop</span> <span class="Delimiter">}</span> <span class="Comment"># reset cursor</span> - x:address:number<span class="Special"> <- </span>get-address *sc, <span class="Constant">cursor-row:offset</span> + x:address:number<span class="Special"> <- </span>get-address *screen, <span class="Constant">cursor-row:offset</span> *x<span class="Special"> <- </span>copy <span class="Constant">0</span> - x<span class="Special"> <- </span>get-address *sc, <span class="Constant">cursor-column:offset</span> + x<span class="Special"> <- </span>get-address *screen, <span class="Constant">cursor-column:offset</span> *x<span class="Special"> <- </span>copy <span class="Constant">0</span> - <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span> + <span class="muControl">reply</span> <span class="Delimiter">}</span> <span class="Comment"># otherwise, real screen</span> clear-display - <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span> ] -<span class="muRecipe">recipe</span> sync-screen [ +<span class="muRecipe">recipe</span> sync-screen screen:address:screen<span class="muRecipe"> -> </span>screen:address:screen [ <span class="Constant">local-scope</span> - sc:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Delimiter">{</span> - <span class="muControl">break-if</span> sc + <span class="muControl">break-if</span> screen sync-display <span class="Delimiter">}</span> <span class="Comment"># do nothing for fake screens</span> ] -<span class="muRecipe">recipe</span> fake-screen-is-empty? [ +<span class="muRecipe">recipe</span> fake-screen-is-empty? screen:address:screen<span class="muRecipe"> -> </span>result:boolean [ <span class="Constant">local-scope</span> - sc:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - <span class="muControl">reply-unless</span> sc, <span class="Constant">1/true</span> - buf:address:array:screen-cell<span class="Special"> <- </span>get *sc, <span class="Constant">data:offset</span> + <span class="Constant">load-ingredients</span> + <span class="muControl">reply-unless</span> screen, <span class="Constant">1/true</span> + buf:address:array:screen-cell<span class="Special"> <- </span>get *screen, <span class="Constant">data:offset</span> i:number<span class="Special"> <- </span>copy <span class="Constant">0</span> len:number<span class="Special"> <- </span>length *buf <span class="Delimiter">{</span> @@ -129,10 +128,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">reply</span> <span class="Constant">1/true</span> ] -<span class="muRecipe">recipe</span> print-character [ +<span class="muRecipe">recipe</span> print screen:address:screen, c:character<span class="muRecipe"> -> </span>screen:address:screen [ <span class="Constant">local-scope</span> - sc:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - c:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> color:number, color-found?:boolean<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Delimiter">{</span> <span class="Comment"># default color to white</span> @@ -149,20 +147,20 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">{</span> <span class="Comment"># if x exists</span> <span class="Comment"># (handle special cases exactly like in the real screen)</span> - <span class="muControl">break-unless</span> sc - width:number<span class="Special"> <- </span>get *sc, <span class="Constant">num-columns:offset</span> - height:number<span class="Special"> <- </span>get *sc, <span class="Constant">num-rows:offset</span> + <span class="muControl">break-unless</span> screen + width:number<span class="Special"> <- </span>get *screen, <span class="Constant">num-columns:offset</span> + height:number<span class="Special"> <- </span>get *screen, <span class="Constant">num-rows:offset</span> <span class="Comment"># if cursor is out of bounds, silently exit</span> - row:address:number<span class="Special"> <- </span>get-address *sc, <span class="Constant">cursor-row:offset</span> + row:address:number<span class="Special"> <- </span>get-address *screen, <span class="Constant">cursor-row:offset</span> legal?:boolean<span class="Special"> <- </span>greater-or-equal *row, <span class="Constant">0</span> - <span class="muControl">reply-unless</span> legal?, sc + <span class="muControl">reply-unless</span> legal? legal?<span class="Special"> <- </span>lesser-than *row, height - <span class="muControl">reply-unless</span> legal?, sc - column:address:number<span class="Special"> <- </span>get-address *sc, <span class="Constant">cursor-column:offset</span> + <span class="muControl">reply-unless</span> legal? + column:address:number<span class="Special"> <- </span>get-address *screen, <span class="Constant">cursor-column:offset</span> legal?<span class="Special"> <- </span>greater-or-equal *column, <span class="Constant">0</span> - <span class="muControl">reply-unless</span> legal?, sc + <span class="muControl">reply-unless</span> legal? legal?<span class="Special"> <- </span>lesser-than *column, width - <span class="muControl">reply-unless</span> legal?, sc + <span class="muControl">reply-unless</span> legal? <span class="Comment"># special-case: newline</span> <span class="Delimiter">{</span> newline?:boolean<span class="Special"> <- </span>equal c, <span class="Constant">10/newline</span> @@ -176,12 +174,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } *column<span class="Special"> <- </span>copy <span class="Constant">0</span> *row<span class="Special"> <- </span>add *row, <span class="Constant">1</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span> + <span class="muControl">reply</span> <span class="Delimiter">}</span> <span class="Comment"># save character in fake screen</span> index:number<span class="Special"> <- </span>multiply *row, width index<span class="Special"> <- </span>add index, *column - buf:address:array:screen-cell<span class="Special"> <- </span>get *sc, <span class="Constant">data:offset</span> + buf:address:array:screen-cell<span class="Special"> <- </span>get *screen, <span class="Constant">data:offset</span> len:number<span class="Special"> <- </span>length *buf <span class="Comment"># special-case: backspace</span> <span class="Delimiter">{</span> @@ -200,7 +198,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } cursor-color:address:number<span class="Special"> <- </span>get-address *cursor, <span class="Constant">color:offset</span> *cursor-color<span class="Special"> <- </span>copy <span class="Constant">7/white</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span> + <span class="muControl">reply</span> <span class="Delimiter">}</span> cursor:address:screen-cell<span class="Special"> <- </span>index-address *buf, index cursor-contents:address:character<span class="Special"> <- </span>get-address *cursor, <span class="Constant">contents:offset</span> @@ -214,17 +212,16 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">break-if</span> at-right? *column<span class="Special"> <- </span>add *column, <span class="Constant">1</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span> + <span class="muControl">reply</span> <span class="Delimiter">}</span> <span class="Comment"># otherwise, real screen</span> print-character-to-display c, color, bg-color - <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span> ] <span class="muScenario">scenario</span> print-character-at-top-left [ run [ <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>new-fake-screen <span class="Constant">3/width</span>, <span class="Constant">2/height</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">97</span> <span class="Comment"># 'a'</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">97</span> <span class="Comment"># 'a'</span> <span class="Constant">2</span>:address:array:screen-cell<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">data:offset</span> <span class="Constant">3</span>:array:screen-cell<span class="Special"> <- </span>copy *<span class="Constant">2</span>:address:array:screen-cell ] @@ -236,10 +233,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<span class="muScenario">scenario</span> print-character-color [ +<span class="muScenario">scenario</span> print-character-in-color [ run [ <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>new-fake-screen <span class="Constant">3/width</span>, <span class="Constant">2/height</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">97/a</span>, <span class="Constant">1/red</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">97/a</span>, <span class="Constant">1/red</span> <span class="Constant">2</span>:address:array:screen-cell<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">data:offset</span> <span class="Constant">3</span>:array:screen-cell<span class="Special"> <- </span>copy *<span class="Constant">2</span>:address:array:screen-cell ] @@ -254,8 +251,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muScenario">scenario</span> print-backspace-character [ run [ <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>new-fake-screen <span class="Constant">3/width</span>, <span class="Constant">2/height</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">97</span> <span class="Comment"># 'a'</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">8</span> <span class="Comment"># backspace</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">97</span> <span class="Comment"># 'a'</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">8</span> <span class="Comment"># backspace</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">cursor-column:offset</span> <span class="Constant">3</span>:address:array:screen-cell<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">data:offset</span> <span class="Constant">4</span>:array:screen-cell<span class="Special"> <- </span>copy *<span class="Constant">3</span>:address:array:screen-cell @@ -272,9 +269,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muScenario">scenario</span> print-extra-backspace-character [ run [ <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>new-fake-screen <span class="Constant">3/width</span>, <span class="Constant">2/height</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">97</span> <span class="Comment"># 'a'</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">8</span> <span class="Comment"># backspace</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">8</span> <span class="Comment"># backspace</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">97</span> <span class="Comment"># 'a'</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">8</span> <span class="Comment"># backspace</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">8</span> <span class="Comment"># backspace</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">cursor-column:offset</span> <span class="Constant">3</span>:address:array:screen-cell<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">data:offset</span> <span class="Constant">4</span>:array:screen-cell<span class="Special"> <- </span>copy *<span class="Constant">3</span>:address:array:screen-cell @@ -288,12 +285,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<span class="muScenario">scenario</span> print-at-right-margin [ +<span class="muScenario">scenario</span> print-character-at-right-margin [ run [ <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>new-fake-screen <span class="Constant">2/width</span>, <span class="Constant">2/height</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">97</span> <span class="Comment"># 'a'</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">98</span> <span class="Comment"># 'b'</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">99</span> <span class="Comment"># 'c'</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">97</span> <span class="Comment"># 'a'</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">98</span> <span class="Comment"># 'b'</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">99</span> <span class="Comment"># 'c'</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">cursor-column:offset</span> <span class="Constant">3</span>:address:array:screen-cell<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">data:offset</span> <span class="Constant">4</span>:array:screen-cell<span class="Special"> <- </span>copy *<span class="Constant">3</span>:address:array:screen-cell @@ -312,8 +309,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muScenario">scenario</span> print-newline-character [ run [ <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>new-fake-screen <span class="Constant">3/width</span>, <span class="Constant">2/height</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">97</span> <span class="Comment"># 'a'</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">97</span> <span class="Comment"># 'a'</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">cursor-row:offset</span> <span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">cursor-column:offset</span> <span class="Constant">4</span>:address:array:screen-cell<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">data:offset</span> @@ -332,9 +329,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muScenario">scenario</span> print-newline-at-bottom-line [ run [ <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>new-fake-screen <span class="Constant">3/width</span>, <span class="Constant">2/height</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">cursor-row:offset</span> <span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">cursor-column:offset</span> ] @@ -344,15 +341,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<span class="muScenario">scenario</span> print-at-bottom-right [ +<span class="muScenario">scenario</span> print-character-at-bottom-right [ run [ <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>new-fake-screen <span class="Constant">2/width</span>, <span class="Constant">2/height</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">97</span> <span class="Comment"># 'a'</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">98</span> <span class="Comment"># 'b'</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">99</span> <span class="Comment"># 'c'</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">100</span> <span class="Comment"># 'd'</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">97</span> <span class="Comment"># 'a'</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">98</span> <span class="Comment"># 'b'</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">99</span> <span class="Comment"># 'c'</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">100</span> <span class="Comment"># 'd'</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">cursor-row:offset</span> <span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">cursor-column:offset</span> <span class="Constant">4</span>:address:array:screen-cell<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">data:offset</span> @@ -374,70 +371,65 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<span class="muRecipe">recipe</span> clear-line [ +<span class="muRecipe">recipe</span> clear-line screen:address:screen<span class="muRecipe"> -> </span>screen:address:screen [ <span class="Constant">local-scope</span> - sc:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># if x exists, clear line in fake screen</span> <span class="Delimiter">{</span> - <span class="muControl">break-unless</span> sc - width:number<span class="Special"> <- </span>get *sc, <span class="Constant">num-columns:offset</span> - column:address:number<span class="Special"> <- </span>get-address *sc, <span class="Constant">cursor-column:offset</span> + <span class="muControl">break-unless</span> screen + width:number<span class="Special"> <- </span>get *screen, <span class="Constant">num-columns:offset</span> + column:address:number<span class="Special"> <- </span>get-address *screen, <span class="Constant">cursor-column:offset</span> original-column:number<span class="Special"> <- </span>copy *column <span class="Comment"># space over the entire line</span> <span class="Delimiter">{</span> right:number<span class="Special"> <- </span>subtract width, <span class="Constant">1</span> done?:boolean<span class="Special"> <- </span>greater-or-equal *column, right <span class="muControl">break-if</span> done? - print-character sc, <span class="Constant">[ ]</span> <span class="Comment"># implicitly updates 'column'</span> + print screen, <span class="Constant">[ ]</span> <span class="Comment"># implicitly updates 'column'</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> <span class="Comment"># now back to where the cursor was</span> *column<span class="Special"> <- </span>copy original-column - <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span> + <span class="muControl">reply</span> <span class="Delimiter">}</span> <span class="Comment"># otherwise, real screen</span> clear-line-on-display - <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span> ] -<span class="muRecipe">recipe</span> cursor-position [ +<span class="muRecipe">recipe</span> cursor-position screen:address:screen<span class="muRecipe"> -> </span>row:number, column:number [ <span class="Constant">local-scope</span> - sc:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># if x exists, lookup cursor in fake screen</span> <span class="Delimiter">{</span> - <span class="muControl">break-unless</span> sc - row:number<span class="Special"> <- </span>get *sc, <span class="Constant">cursor-row:offset</span> - column:number<span class="Special"> <- </span>get *sc, <span class="Constant">cursor-column:offset</span> - <span class="muControl">reply</span> row, column, sc/same-as-ingredient:<span class="Constant">0</span> + <span class="muControl">break-unless</span> screen + row:number<span class="Special"> <- </span>get *screen, <span class="Constant">cursor-row:offset</span> + column:number<span class="Special"> <- </span>get *screen, <span class="Constant">cursor-column:offset</span> + <span class="muControl">reply</span> <span class="Delimiter">}</span> row, column<span class="Special"> <- </span>cursor-position-on-display - <span class="muControl">reply</span> row, column, sc/same-as-ingredient:<span class="Constant">0</span> ] -<span class="muRecipe">recipe</span> move-cursor [ +<span class="muRecipe">recipe</span> move-cursor screen:address:screen, new-row:number, new-column:number<span class="muRecipe"> -> </span>screen:address:screen [ <span class="Constant">local-scope</span> - sc:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - new-row:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - new-column:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># if x exists, move cursor in fake screen</span> <span class="Delimiter">{</span> - <span class="muControl">break-unless</span> sc - row:address:number<span class="Special"> <- </span>get-address *sc, <span class="Constant">cursor-row:offset</span> + <span class="muControl">break-unless</span> screen + row:address:number<span class="Special"> <- </span>get-address *screen, <span class="Constant">cursor-row:offset</span> *row<span class="Special"> <- </span>copy new-row - column:address:number<span class="Special"> <- </span>get-address *sc, <span class="Constant">cursor-column:offset</span> + column:address:number<span class="Special"> <- </span>get-address *screen, <span class="Constant">cursor-column:offset</span> *column<span class="Special"> <- </span>copy new-column - <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span> + <span class="muControl">reply</span> <span class="Delimiter">}</span> <span class="Comment"># otherwise, real screen</span> move-cursor-on-display new-row, new-column - <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span> ] <span class="muScenario">scenario</span> clear-line-erases-printed-characters [ run [ <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>new-fake-screen <span class="Constant">3/width</span>, <span class="Constant">2/height</span> <span class="Comment"># print a character</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">97</span> <span class="Comment"># 'a'</span> + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">97</span> <span class="Comment"># 'a'</span> <span class="Comment"># move cursor to start of line</span> <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>move-cursor <span class="Constant">1</span>:address:screen, <span class="Constant">0/row</span>, <span class="Constant">0/column</span> <span class="Comment"># clear line</span> @@ -463,193 +455,180 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<span class="muRecipe">recipe</span> cursor-down [ +<span class="muRecipe">recipe</span> cursor-down screen:address:screen<span class="muRecipe"> -> </span>screen:address:screen [ <span class="Constant">local-scope</span> - sc:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># if x exists, move cursor in fake screen</span> <span class="Delimiter">{</span> - <span class="muControl">break-unless</span> sc + <span class="muControl">break-unless</span> screen <span class="Delimiter">{</span> <span class="Comment"># increment row unless it's already all the way down</span> - height:number<span class="Special"> <- </span>get *sc, <span class="Constant">num-rows:offset</span> - row:address:number<span class="Special"> <- </span>get-address *sc, <span class="Constant">cursor-row:offset</span> + height:number<span class="Special"> <- </span>get *screen, <span class="Constant">num-rows:offset</span> + row:address:number<span class="Special"> <- </span>get-address *screen, <span class="Constant">cursor-row:offset</span> max:number<span class="Special"> <- </span>subtract height, <span class="Constant">1</span> at-bottom?:boolean<span class="Special"> <- </span>greater-or-equal *row, max <span class="muControl">break-if</span> at-bottom? *row<span class="Special"> <- </span>add *row, <span class="Constant">1</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span> + <span class="muControl">reply</span> <span class="Delimiter">}</span> <span class="Comment"># otherwise, real screen</span> move-cursor-down-on-display - <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span> ] -<span class="muRecipe">recipe</span> cursor-up [ +<span class="muRecipe">recipe</span> cursor-up screen:address:screen<span class="muRecipe"> -> </span>screen:address:screen [ <span class="Constant">local-scope</span> - sc:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># if x exists, move cursor in fake screen</span> <span class="Delimiter">{</span> - <span class="muControl">break-unless</span> sc + <span class="muControl">break-unless</span> screen <span class="Delimiter">{</span> <span class="Comment"># decrement row unless it's already all the way up</span> - row:address:number<span class="Special"> <- </span>get-address *sc, <span class="Constant">cursor-row:offset</span> + row:address:number<span class="Special"> <- </span>get-address *screen, <span class="Constant">cursor-row:offset</span> at-top?:boolean<span class="Special"> <- </span>lesser-or-equal *row, <span class="Constant">0</span> <span class="muControl">break-if</span> at-top? *row<span class="Special"> <- </span>subtract *row, <span class="Constant">1</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span> + <span class="muControl">reply</span> <span class="Delimiter">}</span> <span class="Comment"># otherwise, real screen</span> move-cursor-up-on-display - <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span> ] -<span class="muRecipe">recipe</span> cursor-right [ +<span class="muRecipe">recipe</span> cursor-right screen:address:screen<span class="muRecipe"> -> </span>screen:address:screen [ <span class="Constant">local-scope</span> - sc:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># if x exists, move cursor in fake screen</span> <span class="Delimiter">{</span> - <span class="muControl">break-unless</span> sc + <span class="muControl">break-unless</span> screen <span class="Delimiter">{</span> <span class="Comment"># increment column unless it's already all the way to the right</span> - width:number<span class="Special"> <- </span>get *sc, <span class="Constant">num-columns:offset</span> - column:address:number<span class="Special"> <- </span>get-address *sc, <span class="Constant">cursor-column:offset</span> + width:number<span class="Special"> <- </span>get *screen, <span class="Constant">num-columns:offset</span> + column:address:number<span class="Special"> <- </span>get-address *screen, <span class="Constant">cursor-column:offset</span> max:number<span class="Special"> <- </span>subtract width, <span class="Constant">1</span> at-bottom?:boolean<span class="Special"> <- </span>greater-or-equal *column, max <span class="muControl">break-if</span> at-bottom? *column<span class="Special"> <- </span>add *column, <span class="Constant">1</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span> + <span class="muControl">reply</span> <span class="Delimiter">}</span> <span class="Comment"># otherwise, real screen</span> move-cursor-right-on-display - <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span> ] -<span class="muRecipe">recipe</span> cursor-left [ +<span class="muRecipe">recipe</span> cursor-left screen:address:screen<span class="muRecipe"> -> </span>screen:address:screen [ <span class="Constant">local-scope</span> - sc:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># if x exists, move cursor in fake screen</span> <span class="Delimiter">{</span> - <span class="muControl">break-unless</span> sc + <span class="muControl">break-unless</span> screen <span class="Delimiter">{</span> <span class="Comment"># decrement column unless it's already all the way to the left</span> - column:address:number<span class="Special"> <- </span>get-address *sc, <span class="Constant">cursor-column:offset</span> + column:address:number<span class="Special"> <- </span>get-address *screen, <span class="Constant">cursor-column:offset</span> at-top?:boolean<span class="Special"> <- </span>lesser-or-equal *column, <span class="Constant">0</span> <span class="muControl">break-if</span> at-top? *column<span class="Special"> <- </span>subtract *column, <span class="Constant">1</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span> + <span class="muControl">reply</span> <span class="Delimiter">}</span> <span class="Comment"># otherwise, real screen</span> move-cursor-left-on-display - <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span> ] -<span class="muRecipe">recipe</span> cursor-to-start-of-line [ +<span class="muRecipe">recipe</span> cursor-to-start-of-line screen:address:screen<span class="muRecipe"> -> </span>screen:address:screen [ <span class="Constant">local-scope</span> - sc:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - row:number, _, sc<span class="Special"> <- </span>cursor-position sc + <span class="Constant">load-ingredients</span> + row:number<span class="Special"> <- </span>cursor-position screen column:number<span class="Special"> <- </span>copy <span class="Constant">0</span> - sc<span class="Special"> <- </span>move-cursor sc, row, column - <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span> + screen<span class="Special"> <- </span>move-cursor screen, row, column ] -<span class="muRecipe">recipe</span> cursor-to-next-line [ +<span class="muRecipe">recipe</span> cursor-to-next-line screen:address:screen<span class="muRecipe"> -> </span>screen:address:screen [ <span class="Constant">local-scope</span> - screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> screen<span class="Special"> <- </span>cursor-down screen screen<span class="Special"> <- </span>cursor-to-start-of-line screen - <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span> ] -<span class="muRecipe">recipe</span> screen-width [ +<span class="muRecipe">recipe</span> screen-width screen:address:screen<span class="muRecipe"> -> </span>width:number [ <span class="Constant">local-scope</span> - sc:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># if x exists, move cursor in fake screen</span> <span class="Delimiter">{</span> - <span class="muControl">break-unless</span> sc - width:number<span class="Special"> <- </span>get *sc, <span class="Constant">num-columns:offset</span> - <span class="muControl">reply</span> width + <span class="muControl">break-unless</span> screen + width<span class="Special"> <- </span>get *screen, <span class="Constant">num-columns:offset</span> + <span class="muControl">reply</span> <span class="Delimiter">}</span> <span class="Comment"># otherwise, real screen</span> - width:number<span class="Special"> <- </span>display-width - <span class="muControl">reply</span> width + width<span class="Special"> <- </span>display-width ] -<span class="muRecipe">recipe</span> screen-height [ +<span class="muRecipe">recipe</span> screen-height screen:address:screen<span class="muRecipe"> -> </span>height:number [ <span class="Constant">local-scope</span> - sc:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># if x exists, move cursor in fake screen</span> <span class="Delimiter">{</span> - <span class="muControl">break-unless</span> sc - height:number<span class="Special"> <- </span>get *sc, <span class="Constant">num-rows:offset</span> - <span class="muControl">reply</span> height + <span class="muControl">break-unless</span> screen + height<span class="Special"> <- </span>get *screen, <span class="Constant">num-rows:offset</span> + <span class="muControl">reply</span> <span class="Delimiter">}</span> <span class="Comment"># otherwise, real screen</span> - height:number<span class="Special"> <- </span>display-height - <span class="muControl">reply</span> height + height<span class="Special"> <- </span>display-height ] -<span class="muRecipe">recipe</span> hide-cursor [ +<span class="muRecipe">recipe</span> hide-cursor screen:address:screen<span class="muRecipe"> -> </span>screen:address:screen [ <span class="Constant">local-scope</span> - screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># if x exists (not real display), do nothing</span> <span class="Delimiter">{</span> <span class="muControl">break-unless</span> screen - <span class="muControl">reply</span> screen + <span class="muControl">reply</span> <span class="Delimiter">}</span> <span class="Comment"># otherwise, real screen</span> hide-cursor-on-display - <span class="muControl">reply</span> screen ] -<span class="muRecipe">recipe</span> show-cursor [ +<span class="muRecipe">recipe</span> show-cursor screen:address:screen<span class="muRecipe"> -> </span>screen:address:screen [ <span class="Constant">local-scope</span> - screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># if x exists (not real display), do nothing</span> <span class="Delimiter">{</span> <span class="muControl">break-unless</span> screen - <span class="muControl">reply</span> screen + <span class="muControl">reply</span> <span class="Delimiter">}</span> <span class="Comment"># otherwise, real screen</span> show-cursor-on-display - <span class="muControl">reply</span> screen ] -<span class="muRecipe">recipe</span> hide-screen [ +<span class="muRecipe">recipe</span> hide-screen screen:address:screen<span class="muRecipe"> -> </span>screen:address:screen [ <span class="Constant">local-scope</span> - screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</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 + <span class="muControl">reply</span> <span class="Delimiter">}</span> <span class="Comment"># otherwise, real screen</span> hide-display - <span class="muControl">reply</span> screen ] -<span class="muRecipe">recipe</span> show-screen [ +<span class="muRecipe">recipe</span> show-screen screen:address:screen<span class="muRecipe"> -> </span>screen:address:screen [ <span class="Constant">local-scope</span> - screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</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 + <span class="muControl">reply</span> <span class="Delimiter">}</span> <span class="Comment"># otherwise, real screen</span> show-display - <span class="muControl">reply</span> screen ] -<span class="muRecipe">recipe</span> print-string [ +<span class="muRecipe">recipe</span> print screen:address:screen, s:address:array:character<span class="muRecipe"> -> </span>screen:address:screen [ <span class="Constant">local-scope</span> - screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - s:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> color:number, color-found?:boolean<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Delimiter">{</span> <span class="Comment"># default color to white</span> @@ -668,18 +647,17 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } done?:boolean<span class="Special"> <- </span>greater-or-equal i, len <span class="muControl">break-if</span> done? c:character<span class="Special"> <- </span>index *s, i - print-character screen, c, color, bg-color + print screen, c, color, bg-color 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> screen/same-as-ingredient:<span class="Constant">0</span> ] -<span class="muScenario">scenario</span> print-string-stops-at-right-margin [ +<span class="muScenario">scenario</span> print-text-stops-at-right-margin [ run [ <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>new-fake-screen <span class="Constant">3/width</span>, <span class="Constant">2/height</span> <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcd]</span> - <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print-string <span class="Constant">1</span>:address:screen, <span class="Constant">2</span>:address:array:character + <span class="Constant">1</span>:address:screen<span class="Special"> <- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">2</span>:address:array:character <span class="Constant">3</span>:address:array:screen-cell<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">data:offset</span> <span class="Constant">4</span>:array:screen-cell<span class="Special"> <- </span>copy *<span class="Constant">3</span>:address:array:screen-cell ] @@ -695,7 +673,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] -<span class="muRecipe">recipe</span> print-integer [ +<span class="muRecipe">recipe</span> print-integer screen:address:screen, n:number<span class="muRecipe"> -> </span>screen:address:screen [ <span class="Constant">local-scope</span> screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> n:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> @@ -712,9 +690,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } bg-color<span class="Special"> <- </span>copy <span class="Constant">0/black</span> <span class="Delimiter">}</span> <span class="Comment"># todo: other bases besides decimal</span> - s:address:array:character<span class="Special"> <- </span>integer-to-decimal-string n - print-string screen, s, color, bg-color - <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span> + s:address:array:character<span class="Special"> <- </span>to-text n + screen<span class="Special"> <- </span>print screen, s, color, bg-color ] </pre> </body> diff --git a/html/082scenario_screen.cc.html b/html/082scenario_screen.cc.html index 037fc9ff..bca387d9 100644 --- a/html/082scenario_screen.cc.html +++ b/html/082scenario_screen.cc.html @@ -21,6 +21,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } .Special { color: #ff6060; } .Identifier { color: #804000; } .Constant { color: #00a0a0; } +.CommentedCode { color: #6c6c6c; } --> </style> @@ -43,7 +44,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 [ - screen:address:screen<span class="Special"> <- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span> <span class="Comment"># 'a'</span> + screen:address:screen<span class="Special"> <- </span>print screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span> <span class="Comment"># 'a'</span> ] screen-should-contain [ <span class="Comment"># 01234</span> @@ -57,8 +58,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 [ - screen:address:screen<span class="Special"> <- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">955</span>/greek-small-lambda<span class="Delimiter">,</span> <span class="Constant">1</span>/red - screen:address:screen<span class="Special"> <- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span>/a + screen:address:screen<span class="Special"> <- </span>print screen:address:screen<span class="Delimiter">,</span> <span class="Constant">955</span>/greek-small-lambda<span class="Delimiter">,</span> <span class="Constant">1</span>/red + screen:address:screen<span class="Special"> <- </span>print screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span>/a ] screen-should-contain [ <span class="Comment"># 01234</span> @@ -73,8 +74,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 [ - screen:address:screen<span class="Special"> <- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">955</span>/greek-small-lambda<span class="Delimiter">,</span> <span class="Constant">1</span>/red - screen:address:screen<span class="Special"> <- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span>/a<span class="Delimiter">,</span> <span class="Constant">7</span>/white + screen:address:screen<span class="Special"> <- </span>print screen:address:screen<span class="Delimiter">,</span> <span class="Constant">955</span>/greek-small-lambda<span class="Delimiter">,</span> <span class="Constant">1</span>/red + screen:address:screen<span class="Special"> <- </span>print screen:address:screen<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 [ @@ -106,7 +107,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 [ - screen:address:screen<span class="Special"> <- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span> <span class="Comment"># 'a'</span> + screen:address:screen<span class="Special"> <- </span>print screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span> <span class="Comment"># 'a'</span> ] screen-should-contain [ <span class="Comment"># 01234</span> @@ -124,7 +125,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 [ - screen:address:screen<span class="Special"> <- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span>/a<span class="Delimiter">,</span> <span class="Constant">1</span>/red + screen:address:screen<span class="Special"> <- </span>print screen:address:screen<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> @@ -192,6 +193,8 @@ case SCREEN_SHOULD_CONTAIN: <span class="Delimiter">{</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> case SCREEN_SHOULD_CONTAIN: <span class="Delimiter">{</span> +<span class="CommentedCode">//? cerr << SIZE(get(Recipe_variants, "insert")) << '\n';</span> +<span class="CommentedCode">//? cerr << debug_string(get(Recipe, get(Recipe_ordinal, "insert_4"))) << '\n';</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> diff --git a/html/083scenario_screen_test.mu.html b/html/083scenario_screen_test.mu.html index a93c7c20..2fdd57bc 100644 --- a/html/083scenario_screen_test.mu.html +++ b/html/083scenario_screen_test.mu.html @@ -33,7 +33,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <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:screen<span class="Special"> <- </span>print-character screen:address:screen, <span class="Constant">97/a</span> + screen:address:screen<span class="Special"> <- </span>print screen:address:screen, <span class="Constant">97/a</span> ] screen-should-contain [ <span class="Constant"> .a .</span> @@ -45,7 +45,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } assume-screen <span class="Constant">5/width</span>, <span class="Constant">3/height</span> run [ <span class="Comment"># print a character</span> - screen:address:screen<span class="Special"> <- </span>print-character screen:address:screen, <span class="Constant">97/a</span> + screen:address:screen<span class="Special"> <- </span>print screen:address:screen, <span class="Constant">97/a</span> <span class="Comment"># move cursor to start of line</span> screen:address:screen<span class="Special"> <- </span>move-cursor screen:address:screen, <span class="Constant">0/row</span>, <span class="Constant">0/column</span> <span class="Comment"># clear line</span> diff --git a/html/084console.mu.html b/html/084console.mu.html index c91544f9..b8619762 100644 --- a/html/084console.mu.html +++ b/html/084console.mu.html @@ -58,45 +58,45 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } data:address:array:event ] -<span class="muRecipe">recipe</span> new-fake-console [ +<span class="muRecipe">recipe</span> new-fake-console events:address:array:event<span class="muRecipe"> -> </span>result:address:console [ <span class="Constant">local-scope</span> + <span class="Constant">load-ingredients</span> result:address:console<span class="Special"> <- </span>new <span class="Constant">console:type</span> buf:address:address:array:event<span class="Special"> <- </span>get-address *result, <span class="Constant">data:offset</span> - *buf<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + *buf<span class="Special"> <- </span>copy events idx:address:number<span class="Special"> <- </span>get-address *result, <span class="Constant">index:offset</span> *idx<span class="Special"> <- </span>copy <span class="Constant">0</span> - <span class="muControl">reply</span> result ] -<span class="muRecipe">recipe</span> read-event [ +<span class="muRecipe">recipe</span> read-event console:address:console<span class="muRecipe"> -> </span>result:event, console:address:console, found?:boolean, quit?:boolean [ <span class="Constant">local-scope</span> - x:address:console<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Delimiter">{</span> - <span class="muControl">break-unless</span> x - idx:address:number<span class="Special"> <- </span>get-address *x, <span class="Constant">index:offset</span> - buf:address:array:event<span class="Special"> <- </span>get *x, <span class="Constant">data:offset</span> + <span class="muControl">break-unless</span> console + idx:address:number<span class="Special"> <- </span>get-address *console, <span class="Constant">index:offset</span> + buf:address:array:event<span class="Special"> <- </span>get *console, <span class="Constant">data:offset</span> <span class="Delimiter">{</span> max:number<span class="Special"> <- </span>length *buf done?:boolean<span class="Special"> <- </span>greater-or-equal *idx, max <span class="muControl">break-unless</span> done? dummy:address:event<span class="Special"> <- </span>new <span class="Constant">event:type</span> - <span class="muControl">reply</span> *dummy, x/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">1/found</span>, <span class="Constant">1/quit</span> + <span class="muControl">reply</span> *dummy, console/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">1/found</span>, <span class="Constant">1/quit</span> <span class="Delimiter">}</span> - result:event<span class="Special"> <- </span>index *buf, *idx + result<span class="Special"> <- </span>index *buf, *idx *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="muControl">reply</span> result, console/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">1/found</span>, <span class="Constant">0/quit</span> <span class="Delimiter">}</span> 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> + <span class="muControl">reply</span> result, console/same-as-ingredient:<span class="Constant">0</span>, found?, <span class="Constant">0/quit</span> ] <span class="Comment"># variant of read-event for just keyboard events. Discards everything that</span> <span class="Comment"># isn't unicode, so no arrow keys, page-up/page-down, etc. But you still get</span> <span class="Comment"># newlines, tabs, ctrl-d..</span> -<span class="muRecipe">recipe</span> read-key [ +<span class="muRecipe">recipe</span> read-key console:address:console<span class="muRecipe"> -> </span>result:character, console:address:console, found?:boolean, quit?:boolean [ <span class="Constant">local-scope</span> - console:address:console<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> x:event, console, found?:boolean, quit?:boolean<span class="Special"> <- </span>read-event console <span class="muControl">reply-if</span> quit?, <span class="Constant">0</span>, console/same-as-ingredient:<span class="Constant">0</span>, found?, quit? <span class="muControl">reply-unless</span> found?, <span class="Constant">0</span>, console/same-as-ingredient:<span class="Constant">0</span>, found?, quit? @@ -105,44 +105,39 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">reply</span> *c, console/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">1/found</span>, <span class="Constant">0/quit</span> ] -<span class="muRecipe">recipe</span> send-keys-to-channel [ +<span class="muRecipe">recipe</span> send-keys-to-channel console:address:console, chan:address:channel, screen:address:screen<span class="muRecipe"> -> </span>console:address:console, chan:address:channel, screen:address:screen [ <span class="Constant">local-scope</span> - console:address:console<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Delimiter">{</span> c:character, console, found?:boolean, quit?:boolean<span class="Special"> <- </span>read-key console <span class="muControl">loop-unless</span> found? <span class="muControl">break-if</span> quit? assert c, <span class="Constant">[invalid event, expected text]</span> - screen<span class="Special"> <- </span>print-character screen, c + screen<span class="Special"> <- </span>print screen, c chan<span class="Special"> <- </span>write chan, c <span class="muControl">loop</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> console/same-as-ingredient:<span class="Constant">0</span>, chan/same-as-ingredient:<span class="Constant">1</span>, screen/same-as-ingredient:<span class="Constant">2</span> ] -<span class="muRecipe">recipe</span> wait-for-event [ +<span class="muRecipe">recipe</span> wait-for-event console:address:console<span class="muRecipe"> -> </span>console:address:console [ <span class="Constant">local-scope</span> - console:address:console<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Delimiter">{</span> _, console, found?:boolean<span class="Special"> <- </span>read-event console <span class="muControl">loop-unless</span> found? <span class="Delimiter">}</span> - <span class="muControl">reply</span> console/same-as-ingredient:<span class="Constant">0</span> ] <span class="Comment"># use this helper to skip rendering if there's lots of other events queued up</span> -<span class="muRecipe">recipe</span> has-more-events? [ +<span class="muRecipe">recipe</span> has-more-events? console:address:console<span class="muRecipe"> -> </span>result:boolean [ <span class="Constant">local-scope</span> - console:address:console<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Delimiter">{</span> <span class="muControl">break-unless</span> console <span class="Comment"># fake consoles should be plenty fast; never skip</span> <span class="muControl">reply</span> <span class="Constant">0/false</span> <span class="Delimiter">}</span> - result:boolean<span class="Special"> <- </span>interactions-left? - <span class="muControl">reply</span> result + result<span class="Special"> <- </span>interactions-left? ] </pre> </body> diff --git a/html/090trace_browser.cc.html b/html/090trace_browser.cc.html index 62aa2fbe..3da39a9b 100644 --- a/html/090trace_browser.cc.html +++ b/html/090trace_browser.cc.html @@ -29,6 +29,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } </head> <body> <pre id='vimCodeElement'> +<span class="Comment">//: A debugging helper that lets you zoom in/out on a trace.</span> + +<span class="Comment">//: browse the trace we just created</span> <span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> _BROWSE_TRACE<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> @@ -43,6 +46,14 @@ case _BROWSE_TRACE: <span class="Delimiter">{</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> +<span class="Comment">//: browse a trace loaded from a file</span> +<span class="Delimiter">:(after "Commandline Parsing")</span> +if <span class="Delimiter">(</span>argc == <span class="Constant">3</span> && is_equal<span class="Delimiter">(</span>argv[<span class="Constant">1</span>]<span class="Delimiter">,</span> <span class="Constant">"browse-trace"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> + load_trace<span class="Delimiter">(</span>argv[<span class="Constant">2</span>]<span class="Delimiter">);</span> + start_trace_browser<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">:(before "End Globals")</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> @@ -242,6 +253,25 @@ void render_line<span class="Delimiter">(</span>int screen_row<span class="Delim 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> + +void load_trace<span class="Delimiter">(</span>const char* filename<span class="Delimiter">)</span> <span class="Delimiter">{</span> + ifstream tin<span class="Delimiter">(</span>filename<span class="Delimiter">);</span> + if <span class="Delimiter">(</span>!tin<span class="Delimiter">)</span> <span class="Delimiter">{</span> + cerr << <span class="Constant">"no such file: "</span> << filename << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + exit<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Delimiter">}</span> + Trace_stream = new trace_stream<span class="Delimiter">;</span> + while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>tin<span class="Delimiter">))</span> <span class="Delimiter">{</span> + int depth<span class="Delimiter">;</span> + tin >> depth<span class="Delimiter">;</span> + string label<span class="Delimiter">;</span> + tin >> label<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>*--label<span class="Delimiter">.</span>end<span class="Delimiter">()</span> == <span class="Constant">':'</span><span class="Delimiter">)</span> label<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>--label<span class="Delimiter">.</span>end<span class="Delimiter">());</span> + string line<span class="Delimiter">;</span> + getline<span class="Delimiter">(</span>tin<span class="Delimiter">,</span> line<span class="Delimiter">);</span> + Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>trace_line<span class="Delimiter">(</span>depth<span class="Delimiter">,</span> label<span class="Delimiter">,</span> line<span class="Delimiter">));</span> + <span class="Delimiter">}</span> +<span class="Delimiter">}</span> </pre> </body> </html> diff --git a/html/091run_interactive.cc.html b/html/091run_interactive.cc.html index b96eeb50..94a1284a 100644 --- a/html/091run_interactive.cc.html +++ b/html/091run_interactive.cc.html @@ -15,6 +15,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } .traceContains { color: #008000; } .cSpecial { color: #008000; } +.CommentedCode { color: #6c6c6c; } .Comment { color: #9090ff; } .Delimiter { color: #a04060; } .Special { color: #ff6060; } @@ -45,7 +46,7 @@ recipe main [ <span class="Delimiter">:(scenario run_interactive_empty)</span> recipe main [ - <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>copy <span class="Constant">0</span>/<span class="Special">raw</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>copy <span class="Constant">0</span>/unsafe <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>run-interactive <span class="Constant">1</span>:address:array:character ] <span class="Comment"># result is null</span> @@ -140,6 +141,7 @@ bool run_interactive<span class="Delimiter">(</span>long long int address<span c <span class="Delimiter">}</span> void run_code_begin<span class="Delimiter">()</span> <span class="Delimiter">{</span> +<span class="CommentedCode">//? cerr << "loading new trace\n";</span> <span class="Comment">// stuff to undo later, in run_code_end()</span> Hide_warnings = <span class="Constant">true</span><span class="Delimiter">;</span> Hide_errors = <span class="Constant">true</span><span class="Delimiter">;</span> @@ -152,6 +154,7 @@ void run_code_begin<span class="Delimiter">()</span> <span class="Delimiter">{</ <span class="Delimiter">}</span> void run_code_end<span class="Delimiter">()</span> <span class="Delimiter">{</span> +<span class="CommentedCode">//? cerr << "back to old trace\n";</span> Hide_warnings = <span class="Constant">false</span><span class="Delimiter">;</span> Hide_errors = <span class="Constant">false</span><span class="Delimiter">;</span> Disable_redefine_warnings = <span class="Constant">false</span><span class="Delimiter">;</span> @@ -160,6 +163,7 @@ void run_code_end<span class="Delimiter">()</span> <span class="Delimiter">{</sp Save_trace_stream = <span class="Constant">NULL</span><span class="Delimiter">;</span> Trace_file = Save_trace_file<span class="Delimiter">;</span> Save_trace_file<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> + Recipe<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"interactive"</span><span class="Delimiter">));</span> <span class="Comment">// keep past sandboxes from inserting errors</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Load Recipes")</span> @@ -283,7 +287,7 @@ case _CLEANUP_RUN_INTERACTIVE: <span class="Delimiter">{</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Delimiter">:(scenario "run_interactive_returns_stringified_result")</span> +<span class="Delimiter">:(scenario "run_interactive_converts_result_to_text")</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>new [add <span class="Constant">2</span><span class="Delimiter">,</span> <span class="Constant">2</span>] @@ -293,13 +297,13 @@ recipe main [ <span class="Comment"># first letter in the output should be '4' in unicode</span> <span class="traceContains">+mem: storing 52 in location 11</span> -<span class="Delimiter">:(scenario "run_interactive_returns_string")</span> +<span class="Delimiter">:(scenario "run_interactive_returns_text")</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>new [ x:address:array:character<span class="Special"> <- </span>new [a] y:address:array:character<span class="Special"> <- </span>new [b] - z:address:array:character<span class="Special"> <- </span>string-append x:address:array:character<span class="Delimiter">,</span> y:address:array:character + z:address:array:character<span class="Special"> <- </span>append x:address:array:character<span class="Delimiter">,</span> y: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 <span class="Constant">10</span>:array:character<span class="Special"> <- </span>copy <span class="Constant">2</span>:address:array:character/lookup @@ -450,25 +454,45 @@ case RELOAD: <span class="Delimiter">{</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> case RELOAD: <span class="Delimiter">{</span> +<span class="CommentedCode">//? cerr << "== reload\n";</span> <span class="Comment">// clear any containers in advance</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> Type_ordinal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> recently_added_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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> <span class="Delimiter">}</span> + for <span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> vector<recipe_ordinal> >::iterator p = Recipe_variants<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Recipe_variants<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> +<span class="CommentedCode">//? cerr << p->first << ":\n";</span> + vector<recipe_ordinal>& variants = p<span class="Delimiter">-></span>second<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>p<span class="Delimiter">-></span>second<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>find<span class="Delimiter">(</span>recently_added_shape_shifting_recipes<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> recently_added_shape_shifting_recipes<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> != recently_added_shape_shifting_recipes<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> +<span class="CommentedCode">//? cerr << " " << variants.at(i) << ' ' << get(Recipe, variants.at(i)).name << '\n';</span> + variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> = -<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Comment">// ghost</span> + <span class="Delimiter">}</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>recently_added_shape_shifting_recipes<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> +<span class="CommentedCode">//? cerr << "erasing " << get(Recipe, recently_added_shape_shifting_recipes.at(i)).name << '\n';</span> + Recipe_ordinal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> recently_added_shape_shifting_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)).</span>name<span class="Delimiter">);</span> + Recipe<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>recently_added_shape_shifting_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> + <span class="Delimiter">}</span> + recently_added_shape_shifting_recipes<span class="Delimiter">.</span>clear<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> run_code_begin<span class="Delimiter">();</span> routine* save_current_routine = Current_routine<span class="Delimiter">;</span> Current_routine = <span class="Constant">NULL</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> + <span class="Comment">// clear a few things from previous runs</span> + <span class="Comment">// ad hoc list; we've probably missed a few</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> 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> Current_routine = save_current_routine<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_error_warning_contents<span class="Delimiter">());</span> run_code_end<span class="Delimiter">();</span> <span class="Comment">// wait until we're done with the trace contents</span> +<span class="CommentedCode">//? cerr << "reload done\n";</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> diff --git a/html/092persist.cc.html b/html/092persist.cc.html index cce4913f..c2056b8c 100644 --- a/html/092persist.cc.html +++ b/html/092persist.cc.html @@ -88,7 +88,7 @@ string slurp<span class="Delimiter">(</span>const string& filename<span clas 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> + while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>fin<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> diff --git a/html/998check_type_pointers.cc.html b/html/998check_type_pointers.cc.html index 6532702e..308113a8 100644 --- a/html/998check_type_pointers.cc.html +++ b/html/998check_type_pointers.cc.html @@ -13,10 +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; } -.cSpecial { color: #008000; } -.Constant { color: #00a0a0; } -.Delimiter { color: #a04060; } -.Identifier { color: #804000; } +.Comment { color: #9090ff; } +.CommentedCode { color: #6c6c6c; } --> </style> @@ -28,39 +26,42 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } </head> <body> <pre id='vimCodeElement'> -<span class="Delimiter">:(before "End Transform All")</span> -check_type_pointers<span class="Delimiter">();</span> - -<span class="Delimiter">:(code)</span> -void check_type_pointers<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> - if <span class="Delimiter">(</span>any_type_ingredient_in_header<span class="Delimiter">(</span>p<span class="Delimiter">-></span>first<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - const recipe& r = p<span class="Delimiter">-></span>second<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& inst = r<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<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>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++j<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>j<span class="Delimiter">).</span>type<span class="Delimiter">)</span> <span class="Delimiter">{</span> - raise_error << maybe<span class="Delimiter">(</span>r<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">" '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"' -- "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> << <span class="Constant">" has no type</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> - if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<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="Delimiter">{</span> - raise_error << maybe<span class="Delimiter">(</span>r<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">" '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"' -- "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> << <span class="Constant">" has no type name</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">}</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>!inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>type<span class="Delimiter">)</span> <span class="Delimiter">{</span> - raise_error << maybe<span class="Delimiter">(</span>r<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">" '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"' -- "</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="Constant">" has no type</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> - 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>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="Delimiter">{</span> - raise_error << maybe<span class="Delimiter">(</span>r<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">" '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"' -- "</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="Constant">" has no type name</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">}</span> - <span class="Delimiter">}</span> - <span class="Delimiter">}</span> -<span class="Delimiter">}</span> +<span class="Comment">//: enable this when tracking down null types</span> +<span class="Comment">//: (but it interferes with edit/; since recipes created in the environment</span> +<span class="Comment">//: can raise warnings here which will stop running the entire environment)</span> +<span class="CommentedCode">//? :(before "End Transform All")</span> +<span class="CommentedCode">//? check_type_pointers();</span> +<span class="CommentedCode">//? </span> +<span class="CommentedCode">//? :(code)</span> +<span class="CommentedCode">//? void check_type_pointers() {</span> +<span class="CommentedCode">//? for (map<recipe_ordinal, recipe>::iterator p = Recipe.begin(); p != Recipe.end(); ++p) {</span> +<span class="CommentedCode">//? if (any_type_ingredient_in_header(p->first)) continue;</span> +<span class="CommentedCode">//? const recipe& r = p->second;</span> +<span class="CommentedCode">//? for (long long int i = 0; i < SIZE(r.steps); ++i) {</span> +<span class="CommentedCode">//? const instruction& inst = r.steps.at(i);</span> +<span class="CommentedCode">//? for (long long int j = 0; j < SIZE(inst.ingredients); ++j) {</span> +<span class="CommentedCode">//? if (!inst.ingredients.at(j).type) {</span> +<span class="CommentedCode">//? raise_error << maybe(r.name) << " '" << inst.to_string() << "' -- " << inst.ingredients.at(j).to_string() << " has no type\n" << end();</span> +<span class="CommentedCode">//? return;</span> +<span class="CommentedCode">//? }</span> +<span class="CommentedCode">//? if (!inst.ingredients.at(j).properties.at(0).second) {</span> +<span class="CommentedCode">//? raise_error << maybe(r.name) << " '" << inst.to_string() << "' -- " << inst.ingredients.at(j).to_string() << " has no type name\n" << end();</span> +<span class="CommentedCode">//? return;</span> +<span class="CommentedCode">//? }</span> +<span class="CommentedCode">//? }</span> +<span class="CommentedCode">//? for (long long int j = 0; j < SIZE(inst.products); ++j) {</span> +<span class="CommentedCode">//? if (!inst.products.at(j).type) {</span> +<span class="CommentedCode">//? raise_error << maybe(r.name) << " '" << inst.to_string() << "' -- " << inst.products.at(j).to_string() << " has no type\n" << end();</span> +<span class="CommentedCode">//? return;</span> +<span class="CommentedCode">//? }</span> +<span class="CommentedCode">//? if (!inst.products.at(j).properties.at(0).second) {</span> +<span class="CommentedCode">//? raise_error << maybe(r.name) << " '" << inst.to_string() << "' -- " << inst.products.at(j).to_string() << " has no type name\n" << end();</span> +<span class="CommentedCode">//? return;</span> +<span class="CommentedCode">//? }</span> +<span class="CommentedCode">//? }</span> +<span class="CommentedCode">//? }</span> +<span class="CommentedCode">//? }</span> +<span class="CommentedCode">//? }</span> </pre> </body> </html> diff --git a/html/999spaces.cc.html b/html/999spaces.cc.html index dac58e9d..531efb53 100644 --- a/html/999spaces.cc.html +++ b/html/999spaces.cc.html @@ -61,6 +61,57 @@ assert<span class="Delimiter">(</span>Next_recipe_ordinal == <span class="Consta assert<span class="Delimiter">(</span>Initial_callstack_depth == <span class="Constant">101</span><span class="Delimiter">);</span> assert<span class="Delimiter">(</span>Max_callstack_depth == <span class="Constant">9989</span><span class="Delimiter">);</span> <span class="Comment">//: 9990-9999 - intra-instruction lines (mostly label mem)</span> + +<span class="SalientComment">//:: Summary of transforms and their dependencies</span> +<span class="Comment">//: begin transforms</span> +<span class="Comment">//: begin instruction inserting transforms</span> +<span class="Comment">//: 52 insert fragments</span> +<span class="Comment">//: ↳ 52.2 check fragments</span> +<span class="Comment">//: ---</span> +<span class="Comment">//: 53 rewrite 'stash' instructions</span> +<span class="Comment">//: end instruction inserting transforms</span> +<span class="Comment">//:</span> +<span class="Comment">//: begin instruction modifying transforms</span> +<span class="Comment">//: 56.2 check header ingredients</span> +<span class="Comment">//: ↳ 56.4 fill in reply ingredients</span> +<span class="Comment">//:</span> +<span class="Comment">//: begin type modifying transforms</span> +<span class="Comment">//: 56.3 deduce types from header</span> +<span class="Comment">//: 48 check or set types by name</span> +<span class="Comment">//: ---</span> +<span class="Comment">//: 30 check or set invalid containers</span> +<span class="Comment">//: end type modifying transforms</span> +<span class="Comment">//: ↳ 57 static dispatch</span> +<span class="Comment">//: ---</span> +<span class="Comment">//: 13 update instruction operation</span> +<span class="Comment">//: 40 transform braces</span> +<span class="Comment">//: 41 transform labels</span> +<span class="Comment">//:</span> +<span class="Comment">//: ↱ 46 collect surrounding spaces</span> +<span class="Comment">//: 42 transform names</span> +<span class="Comment">//: end instruction modifying transforms</span> +<span class="Comment">//:</span> +<span class="Comment">//: begin checks</span> +<span class="Comment">//: ---</span> +<span class="Comment">//: 21 check instruction</span> +<span class="Comment">//: ↳ 43 transform 'new' to 'allocate'</span> +<span class="Comment">//:</span> +<span class="Comment">//: 56 check reply instructions against header</span> +<span class="Comment">//: end checks</span> +<span class="Comment">//: end transforms</span> + +<span class="SalientComment">//:: Summary of type-checking in different phases</span> +<span class="Comment">//: when dispatching instructions we accept first recipe that:</span> +<span class="Comment">//: strictly matches all types</span> +<span class="Comment">//: maps literal 0 or literal 1 to boolean for some ingredients</span> +<span class="Comment">//: performs some other acceptable type conversion</span> +<span class="Comment">//: literal 0 -> address</span> +<span class="Comment">//: literal -> character</span> +<span class="Comment">//: when checking instructions we ensure that types match, and that literals map to some scalar</span> +<span class="Comment">//: (address can only map to literal 0)</span> +<span class="Comment">//: (boolean can only map to literal 0 or literal 1)</span> +<span class="Comment">//: (but conditionals can take any scalar)</span> +<span class="Comment">//: at runtime we perform no checks</span> </pre> </body> </html> diff --git a/html/channel.mu.html b/html/channel.mu.html index 12babbde..15a75d1f 100644 --- a/html/channel.mu.html +++ b/html/channel.mu.html @@ -32,10 +32,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <pre id='vimCodeElement'> <span class="Comment"># example program: communicating between routines using channels</span> -<span class="muRecipe">recipe</span> producer [ +<span class="muRecipe">recipe</span> producer chan:address:channel<span class="muRecipe"> -> </span>chan:address:channel [ <span class="Comment"># produce characters 1 to 5 on a channel</span> <span class="Constant">local-scope</span> - chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># n = 0</span> n:character<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Delimiter">{</span> @@ -50,10 +50,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">}</span> ] -<span class="muRecipe">recipe</span> consumer [ +<span class="muRecipe">recipe</span> consumer chan:address:channel<span class="muRecipe"> -> </span>chan:address:channel [ <span class="Comment"># consume and print integers from a channel</span> <span class="Constant">local-scope</span> - chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Delimiter">{</span> <span class="Comment"># read an integer from the channel</span> n:character, chan:address:channel<span class="Special"> <- </span>read chan diff --git a/html/chessboard.mu.html b/html/chessboard.mu.html index 5e11ad01..338e92dc 100644 --- a/html/chessboard.mu.html +++ b/html/chessboard.mu.html @@ -15,14 +15,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 1.05em; } .muControl { color: #c0a020; } .muRecipe { color: #ff8700; } -.SalientComment { color: #00ffff; } +.muScenario { color: #00af00; } .muData { color: #ffff00; } +.Special { color: #ff6060; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } -.Special { color: #ff6060; } +.SalientComment { color: #00ffff; } .CommentedCode { color: #6c6c6c; } .Delimiter { color: #a04060; } -.muScenario { color: #00af00; } --> </style> @@ -53,7 +53,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <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> + chessboard <span class="Constant">0/screen</span>, <span class="Constant">0/console</span> close-console <span class="Comment"># cleanup screen, keyboard and mouse</span> ] @@ -72,7 +72,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } run [ screen:address:screen, console:address:console<span class="Special"> <- </span>chessboard screen:address:screen, console:address:console <span class="Comment"># icon for the cursor</span> - screen<span class="Special"> <- </span>print-character screen, <span class="Constant">9251/␣</span> + screen<span class="Special"> <- </span>print screen, <span class="Constant">9251/␣</span> ] screen-should-contain [ <span class="Comment"># 1 2 3 4 5 6 7 8 9 10 11</span> @@ -102,10 +102,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="SalientComment">## Here's how 'chessboard' is implemented.</span> -<span class="muRecipe">recipe</span> chessboard [ +<span class="muRecipe">recipe</span> chessboard screen:address:screen, console:address:console<span class="muRecipe"> -> </span>screen:address:screen, console:address:console [ <span class="Constant">local-scope</span> - screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - console:address:console<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> board:address:array:address:array:character<span class="Special"> <- </span>initial-position <span class="Comment"># hook up stdin</span> stdin:address:channel<span class="Special"> <- </span>new-channel <span class="Constant">10/capacity</span> @@ -116,28 +115,28 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">{</span> msg:address:array:character<span class="Special"> <- </span>new <span class="Constant">[Stupid text-mode chessboard. White pieces in uppercase; black pieces in lowercase. No checking for legal moves.</span> <span class="Constant">]</span> - print-string screen, msg + print screen, msg cursor-to-next-line screen print-board screen, board cursor-to-next-line screen msg<span class="Special"> <- </span>new <span class="Constant">[Type in your move as <from square>-<to square>. For example: 'a2-a4'. Then press <enter>.</span> <span class="Constant">]</span> - print-string screen, msg + print screen, msg cursor-to-next-line screen msg<span class="Special"> <- </span>new <span class="Constant">[Hit 'q' to exit.</span> <span class="Constant">]</span> - print-string screen, msg + print screen, msg <span class="Delimiter">{</span> cursor-to-next-line screen msg<span class="Special"> <- </span>new <span class="Constant">[move: ]</span> - print-string screen, msg + screen<span class="Special"> <- </span>print screen, msg m:address:move, quit:boolean, error:boolean<span class="Special"> <- </span>read-move buffered-stdin, screen <span class="muControl">break-if</span> quit, <span class="Constant">+quit:label</span> buffered-stdin<span class="Special"> <- </span>clear-channel buffered-stdin <span class="Comment"># cleanup after error. todo: test this?</span> <span class="muControl">loop-if</span> error <span class="Delimiter">}</span> board<span class="Special"> <- </span>make-move board, m - clear-screen screen + screen<span class="Special"> <- </span>clear-screen screen <span class="muControl">loop</span> <span class="Delimiter">}</span> <span class="Constant"> +quit</span> @@ -145,15 +144,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="SalientComment">## a board is an array of files, a file is an array of characters (squares)</span> -<span class="muRecipe">recipe</span> new-board [ +<span class="muRecipe">recipe</span> new-board initial-position:address:array:character<span class="muRecipe"> -> </span>board:address:array:address:array:character [ <span class="Constant">local-scope</span> - initial-position:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> <span class="Comment"># assert(length(initial-position) == 64)</span> len:number<span class="Special"> <- </span>length *initial-position correct-length?:boolean<span class="Special"> <- </span>equal len, <span class="Constant">64</span> assert correct-length?, <span class="Constant">[chessboard had incorrect size]</span> <span class="Comment"># board is an array of pointers to files; file is an array of characters</span> - board:address:array:address:array:character<span class="Special"> <- </span>new <span class="Constant">location:type</span>, <span class="Constant">8</span> + board<span class="Special"> <- </span>new <span class="Constant">location:type</span>, <span class="Constant">8</span> col:number<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Delimiter">{</span> done?:boolean<span class="Special"> <- </span>equal col, <span class="Constant">8</span> @@ -163,15 +162,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } col<span class="Special"> <- </span>add col, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> board ] -<span class="muRecipe">recipe</span> new-file [ +<span class="muRecipe">recipe</span> new-file position:address:array:character, index:number<span class="muRecipe"> -> </span>result:address:array:character [ <span class="Constant">local-scope</span> - position:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - index:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> index<span class="Special"> <- </span>multiply index, <span class="Constant">8</span> - result:address:array:character<span class="Special"> <- </span>new <span class="Constant">character:type</span>, <span class="Constant">8</span> + result<span class="Special"> <- </span>new <span class="Constant">character:type</span>, <span class="Constant">8</span> row:number<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Delimiter">{</span> done?:boolean<span class="Special"> <- </span>equal row, <span class="Constant">8</span> @@ -182,13 +179,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } index<span class="Special"> <- </span>add index, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> - <span class="muControl">reply</span> result ] -<span class="muRecipe">recipe</span> print-board [ +<span class="muRecipe">recipe</span> print-board screen:address:screen, board:address:array:address:array:character<span class="muRecipe"> -> </span>screen:address:screen [ <span class="Constant">local-scope</span> - screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - board:address:array:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> row:number<span class="Special"> <- </span>copy <span class="Constant">7</span> <span class="Comment"># start printing from the top of the board</span> <span class="Comment"># print each row</span> <span class="Delimiter">{</span> @@ -198,7 +193,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } rank:number<span class="Special"> <- </span>add row, <span class="Constant">1</span> print-integer screen, rank s:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ | ]</span> - print-string screen, s + print screen, s <span class="Comment"># print each square in the row</span> col:number<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Delimiter">{</span> @@ -206,8 +201,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">break-if</span> done?:boolean f:address:array:character<span class="Special"> <- </span>index *board, col c:character<span class="Special"> <- </span>index *f, row - print-character screen, c - print-character screen, <span class="Constant">32/space</span> + print screen, c + print screen, <span class="Constant">32/space</span> col<span class="Special"> <- </span>add col, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> @@ -217,15 +212,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">}</span> <span class="Comment"># print file letters as legend</span> s<span class="Special"> <- </span>new <span class="Constant">[ +----------------]</span> - print-string screen, s + print screen, s screen<span class="Special"> <- </span>cursor-to-next-line screen s<span class="Special"> <- </span>new <span class="Constant">[ a b c d e f g h]</span> - screen<span class="Special"> <- </span>print-string screen, s + screen<span class="Special"> <- </span>print screen, s screen<span class="Special"> <- </span>cursor-to-next-line screen ] -<span class="Comment"># board:address:array:address:array:character <- initial-position</span> -<span class="muRecipe">recipe</span> initial-position [ +<span class="muRecipe">recipe</span> initial-position<span class="muRecipe"> -> </span>board:address:array:address:array:character [ <span class="Constant">local-scope</span> <span class="Comment"># layout in memory (in raster order):</span> <span class="Comment"># R P _ _ _ _ p r</span> @@ -245,8 +239,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="CommentedCode">#? 66/B, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 98/b,</span> <span class="CommentedCode">#? 78/N, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 110/n,</span> <span class="CommentedCode">#? 82/R, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 114/r</span> - board:address:array:address:array:character<span class="Special"> <- </span>new-board initial-position - <span class="muControl">reply</span> board + board<span class="Special"> <- </span>new-board initial-position ] <span class="muScenario">scenario</span> printing-the-board [ @@ -282,12 +275,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } to-rank:number ] -<span class="Comment"># result:address:move, quit?:boolean, error?:boolean <- read-move stdin:address:channel, screen:address:screen</span> <span class="Comment"># prints only error messages to screen</span> -<span class="muRecipe">recipe</span> read-move [ +<span class="muRecipe">recipe</span> read-move stdin:address:channel, screen:address:screen<span class="muRecipe"> -> </span>result:address:move, quit?:boolean, error?:boolean [ <span class="Constant">local-scope</span> - stdin:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> from-file:number, quit?:boolean, error?:boolean<span class="Special"> <- </span>read-file stdin, screen <span class="muControl">reply-if</span> quit?, <span class="Constant">0/dummy</span>, quit?, error? <span class="muControl">reply-if</span> error?, <span class="Constant">0/dummy</span>, quit?, error? @@ -314,12 +305,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">reply</span> result, quit?, error? ] -<span class="Comment"># file:number, quit:boolean, error:boolean <- read-file stdin:address:channel, screen:address:screen</span> <span class="Comment"># valid values for file: 0-7</span> -<span class="muRecipe">recipe</span> read-file [ +<span class="muRecipe">recipe</span> read-file stdin:address:channel, screen:address:screen<span class="muRecipe"> -> </span>file:number, quit:boolean, error:boolean [ <span class="Constant">local-scope</span> - stdin:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> c:character, stdin<span class="Special"> <- </span>read stdin <span class="Delimiter">{</span> q-pressed?:boolean<span class="Special"> <- </span>equal c, <span class="Constant">81/Q</span> @@ -340,7 +329,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } newline?:boolean<span class="Special"> <- </span>equal c, <span class="Constant">10/newline</span> <span class="muControl">break-unless</span> newline? error-message:address:array:character<span class="Special"> <- </span>new <span class="Constant">[that's not enough]</span> - print-string screen, error-message + print screen, error-message <span class="muControl">reply</span> <span class="Constant">0/dummy</span>, <span class="Constant">0/quit</span>, <span class="Constant">1/error</span> <span class="Delimiter">}</span> file:number<span class="Special"> <- </span>subtract c, <span class="Constant">97/a</span> @@ -349,8 +338,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } above-min:boolean<span class="Special"> <- </span>greater-or-equal file, <span class="Constant">0</span> <span class="muControl">break-if</span> above-min error-message:address:array:character<span class="Special"> <- </span>new <span class="Constant">[file too low: ]</span> - print-string screen, error-message - print-character screen, c + print screen, error-message + print screen, c cursor-to-next-line screen <span class="muControl">reply</span> <span class="Constant">0/dummy</span>, <span class="Constant">0/quit</span>, <span class="Constant">1/error</span> <span class="Delimiter">}</span> @@ -358,19 +347,17 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } below-max:boolean<span class="Special"> <- </span>lesser-than file, <span class="Constant">8</span> <span class="muControl">break-if</span> below-max error-message<span class="Special"> <- </span>new <span class="Constant">[file too high: ]</span> - print-string screen, error-message - print-character screen, c + print screen, error-message + print screen, c <span class="muControl">reply</span> <span class="Constant">0/dummy</span>, <span class="Constant">0/quit</span>, <span class="Constant">1/error</span> <span class="Delimiter">}</span> <span class="muControl">reply</span> file, <span class="Constant">0/quit</span>, <span class="Constant">0/error</span> ] -<span class="Comment"># rank:number <- read-rank stdin:address:channel, screen:address:screen</span> <span class="Comment"># valid values: 0-7, -1 (quit), -2 (error)</span> -<span class="muRecipe">recipe</span> read-rank [ +<span class="muRecipe">recipe</span> read-rank stdin:address:channel, screen:address:screen<span class="muRecipe"> -> </span>rank:number, quit?:boolean, error?:boolean, stdin:address:channel, screen:address:screen [ <span class="Constant">local-scope</span> - stdin:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> c:character, stdin<span class="Special"> <- </span>read stdin <span class="Delimiter">{</span> q-pressed?:boolean<span class="Special"> <- </span>equal c, <span class="Constant">8/Q</span> @@ -386,7 +373,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } newline?:boolean<span class="Special"> <- </span>equal c, <span class="Constant">10</span> <span class="Comment"># newline</span> <span class="muControl">break-unless</span> newline? error-message:address:array:character<span class="Special"> <- </span>new <span class="Constant">[that's not enough]</span> - print-string screen, error-message + print screen, error-message <span class="muControl">reply</span> <span class="Constant">0/dummy</span>, <span class="Constant">0/quit</span>, <span class="Constant">1/error</span> <span class="Delimiter">}</span> rank:number<span class="Special"> <- </span>subtract c, <span class="Constant">49/'1'</span> @@ -395,16 +382,16 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } above-min:boolean<span class="Special"> <- </span>greater-or-equal rank, <span class="Constant">0</span> <span class="muControl">break-if</span> above-min error-message<span class="Special"> <- </span>new <span class="Constant">[rank too low: ]</span> - print-string screen, error-message - print-character screen, c + print screen, error-message + print screen, c <span class="muControl">reply</span> <span class="Constant">0/dummy</span>, <span class="Constant">0/quit</span>, <span class="Constant">1/error</span> <span class="Delimiter">}</span> <span class="Delimiter">{</span> below-max:boolean<span class="Special"> <- </span>lesser-or-equal rank, <span class="Constant">7</span> <span class="muControl">break-if</span> below-max error-message<span class="Special"> <- </span>new <span class="Constant">[rank too high: ]</span> - print-string screen, error-message - print-character screen, c + print screen, error-message + print screen, c <span class="muControl">reply</span> <span class="Constant">0/dummy</span>, <span class="Constant">0/quit</span>, <span class="Constant">1/error</span> <span class="Delimiter">}</span> <span class="muControl">reply</span> rank, <span class="Constant">0/quit</span>, <span class="Constant">0/error</span> @@ -412,20 +399,17 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment"># read a character from the given channel and check that it's what we expect</span> <span class="Comment"># return true on error</span> -<span class="muRecipe">recipe</span> expect-from-channel [ +<span class="muRecipe">recipe</span> expect-from-channel stdin:address:channel, expected:character, screen:address:screen<span class="muRecipe"> -> </span>result:boolean [ <span class="Constant">local-scope</span> - stdin:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - expected:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> c:character, stdin<span class="Special"> <- </span>read stdin <span class="Delimiter">{</span> match?:boolean<span class="Special"> <- </span>equal c, expected <span class="muControl">break-if</span> match? s:address:array:character<span class="Special"> <- </span>new <span class="Constant">[expected character not found]</span> - print-string screen, s + print screen, s <span class="Delimiter">}</span> - result:boolean<span class="Special"> <- </span>not match? - <span class="muControl">reply</span> result + result<span class="Special"> <- </span>not match? ] <span class="muScenario">scenario</span> read-move-blocking [ @@ -592,21 +576,19 @@ F read-move-file: routine failed to pause <span class="muRecipe">after</span> co ] ] -<span class="muRecipe">recipe</span> make-move [ +<span class="muRecipe">recipe</span> make-move board:address:array:address:array:character, m:address:move<span class="muRecipe"> -> </span>board:address:array:address:array:character [ <span class="Constant">local-scope</span> - b:address:array:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span> - m:address:move<span class="Special"> <- </span><span class="Constant">next-ingredient</span> + <span class="Constant">load-ingredients</span> from-file:number<span class="Special"> <- </span>get *m, <span class="Constant">from-file:offset</span> from-rank:number<span class="Special"> <- </span>get *m, <span class="Constant">from-rank:offset</span> to-file:number<span class="Special"> <- </span>get *m, <span class="Constant">to-file:offset</span> to-rank:number<span class="Special"> <- </span>get *m, <span class="Constant">to-rank:offset</span> - f:address:array:character<span class="Special"> <- </span>index *b, from-file + f:address:array:character<span class="Special"> <- </span>index *board, from-file src:address:character/square<span class="Special"> <- </span>index-address *f, from-rank - f<span class="Special"> <- </span>index *b, to-file + f<span class="Special"> <- </span>index *board, to-file dest:address:character/square<span class="Special"> <- </span>index-address *f, to-rank *dest<span class="Special"> <- </span>copy *src *src<span class="Special"> <- </span>copy <span class="Constant">32/space</span> - <span class="muControl">reply</span> b/same-as-ingredient:<span class="Constant">0</span> ] <span class="muScenario">scenario</span> making-a-move [ diff --git a/html/edit/001-editor.mu.html b/html/edit/001-editor.mu.html index cf10dc6c..59982193 100644 --- a/html/edit/001-editor.mu.html +++ b/html/edit/001-editor.mu.html @@ -35,7 +35,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <pre id='vimCodeElement'> <span class="SalientComment">## the basic editor data structure, and how it displays text to the screen</span> -<span class="Comment"># temporary main for this layer: just render the given string at the given</span> +<span class="Comment"># temporary main for this layer: just render the given text at the given</span> <span class="Comment"># screen dimensions, then stop</span> <span class="muRecipe">recipe!</span> main text:address:array:character [ <span class="Constant">local-scope</span> @@ -48,7 +48,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } close-console ] -<span class="muScenario">scenario</span> editor-initially-prints-string-to-screen [ +<span class="muScenario">scenario</span> editor-initially-prints-text-to-screen [ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> run [ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span> @@ -82,7 +82,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <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> -<span class="muRecipe">recipe</span> new-editor s:address:array:character, screen:address:screen, left:number, right:number<span class="muRecipe"> -> </span>result:address:editor-data [ +<span class="muRecipe">recipe</span> new-editor s:address:array:character, screen:address:screen, left:number, right:number<span class="muRecipe"> -> </span>result:address:editor-data, screen:address:screen [ <span class="Constant">local-scope</span> <span class="Constant">load-ingredients</span> <span class="Comment"># no clipping of bounds</span> @@ -228,14 +228,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } at-right?:boolean<span class="Special"> <- </span>equal column, right <span class="muControl">break-unless</span> at-right? <span class="Comment"># print wrap icon</span> - print-character screen, <span class="Constant">8617/loop-back-to-left</span>, <span class="Constant">245/grey</span> + print 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> 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> - print-character screen, c, color + print screen, c, color curr<span class="Special"> <- </span>next curr prev<span class="Special"> <- </span>next prev column<span class="Special"> <- </span>add column, <span class="Constant">1</span> @@ -259,13 +259,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <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="muRecipe">recipe</span> clear-line-delimited screen:address:screen, column:number, right:number [ +<span class="muRecipe">recipe</span> clear-line-delimited screen:address:screen, column:number, right:number<span class="muRecipe"> -> </span>screen:address:screen [ <span class="Constant">local-scope</span> <span class="Constant">load-ingredients</span> <span class="Delimiter">{</span> done?:boolean<span class="Special"> <- </span>greater-than column, right <span class="muControl">break-if</span> done? - print-character screen, <span class="Constant">32/space</span> + screen<span class="Special"> <- </span>print screen, <span class="Constant">32/space</span> column<span class="Special"> <- </span>add column, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> diff --git a/html/edit/002-typing.mu.html b/html/edit/002-typing.mu.html index 538bbf5d..efed71b6 100644 --- a/html/edit/002-typing.mu.html +++ b/html/edit/002-typing.mu.html @@ -259,7 +259,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } 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 + print screen, c go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span> <span class="muControl">reply</span> <span class="Delimiter">}</span> @@ -281,7 +281,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } 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 + print screen, currc curr-column<span class="Special"> <- </span>add curr-column, <span class="Constant">1</span> curr<span class="Special"> <- </span>next curr <span class="muControl">loop</span> @@ -1070,7 +1070,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <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? - print-character screen, style, color, bg-color + print screen, style, color, bg-color x<span class="Special"> <- </span>add x, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> diff --git a/html/edit/003-shortcuts.mu.html b/html/edit/003-shortcuts.mu.html index aabe23e0..5518a680 100644 --- a/html/edit/003-shortcuts.mu.html +++ b/html/edit/003-shortcuts.mu.html @@ -152,13 +152,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } 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 + screen<span class="Special"> <- </span>print screen, currc curr-column<span class="Special"> <- </span>add curr-column, <span class="Constant">1</span> curr<span class="Special"> <- </span>next 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> + screen<span class="Special"> <- </span>print screen, <span class="Constant">32/space</span> go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span> ] @@ -392,13 +392,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } 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 + screen<span class="Special"> <- </span>print screen, currc curr-column<span class="Special"> <- </span>add curr-column, <span class="Constant">1</span> curr<span class="Special"> <- </span>next 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> + screen<span class="Special"> <- </span>print screen, <span class="Constant">32/space</span> go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span> ] diff --git a/html/edit/004-programming-environment.mu.html b/html/edit/004-programming-environment.mu.html index 172b1dcc..a2001520 100644 --- a/html/edit/004-programming-environment.mu.html +++ b/html/edit/004-programming-environment.mu.html @@ -20,7 +20,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .SalientComment { color: #00ffff; } -.CommentedCode { color: #6c6c6c; } .Delimiter { color: #a04060; } .muScenario { color: #00af00; } --> @@ -70,7 +69,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } 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> + print 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> @@ -303,7 +302,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] <span class="Comment"># show the cursor at the right window</span> run [ - print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span> + print screen:address:screen, <span class="Constant">9251/␣/cursor</span> ] screen-should-contain [ <span class="Constant"> . run (F4) .</span> @@ -343,7 +342,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } assume-console <span class="Constant">[]</span> run [ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data - print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span> + print screen:address:screen, <span class="Constant">9251/␣/cursor</span> ] <span class="Comment"># is cursor at the right place?</span> screen-should-contain [ @@ -358,7 +357,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] run [ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data - print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span> + print screen:address:screen, <span class="Constant">9251/␣/cursor</span> ] <span class="Comment"># cursor should still be right</span> screen-should-contain [ @@ -392,7 +391,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] run [ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data - print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span> + print screen:address:screen, <span class="Constant">9251/␣/cursor</span> ] <span class="Comment"># cursor moves to end of old line</span> screen-should-contain [ @@ -417,7 +416,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } 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> + print screen, run-button, <span class="Constant">255/white</span>, <span class="Constant">161/reddish</span> <span class="Comment"># dotted line down the middle</span> trace <span class="Constant">11</span>, <span class="Constant">[app]</span>, <span class="Constant">[render divider]</span> divider:number, _<span class="Special"> <- </span>divide-with-remainder width, <span class="Constant">2</span> @@ -486,9 +485,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } screen<span class="Special"> <- </span>move-cursor screen, cursor-row, cursor-column ] -<span class="Comment"># print a string 's' to 'editor' in 'color' starting at 'row'</span> +<span class="Comment"># print a text 's' to 'editor' in 'color' starting at 'row'</span> <span class="Comment"># clear rest of last line, move cursor to next line</span> -<span class="muRecipe">recipe</span> render-string screen:address:screen, s:address:array:character, left:number, right:number, color:number, row:number<span class="muRecipe"> -> </span>row:number, screen:address:screen [ +<span class="muRecipe">recipe</span> render screen:address:screen, s:address:array:character, left:number, right:number, color:number, row:number<span class="muRecipe"> -> </span>row:number, screen:address:screen [ <span class="Constant">local-scope</span> <span class="Constant">load-ingredients</span> <span class="muControl">reply-unless</span> s @@ -509,7 +508,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } at-right?:boolean<span class="Special"> <- </span>equal column, right <span class="muControl">break-unless</span> at-right? <span class="Comment"># print wrap icon</span> - print-character screen, <span class="Constant">8617/loop-back-to-left</span>, <span class="Constant">245/grey</span> + print 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> screen<span class="Special"> <- </span>move-cursor screen, row, column @@ -524,7 +523,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">{</span> done?:boolean<span class="Special"> <- </span>greater-than column, right <span class="muControl">break-if</span> done? - print-character screen, <span class="Constant">32/space</span> + print screen, <span class="Constant">32/space</span> column<span class="Special"> <- </span>add column, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> @@ -533,7 +532,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } 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 + print screen, c, color column<span class="Special"> <- </span>add column, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> @@ -546,8 +545,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } move-cursor screen, row, left ] -<span class="Comment"># like 'render-string' but with colorization for comments like in the editor</span> -<span class="muRecipe">recipe</span> render-code-string screen:address:screen, s:address:array:character, left:number, right:number, row:number<span class="muRecipe"> -> </span>row:number, screen:address:screen [ +<span class="Comment"># like 'render' for texts, but with colorization for comments like in the editor</span> +<span class="muRecipe">recipe</span> render-code screen:address:screen, s:address:array:character, left:number, right:number, row:number<span class="muRecipe"> -> </span>row:number, screen:address:screen [ <span class="Constant">local-scope</span> <span class="Constant">load-ingredients</span> <span class="muControl">reply-unless</span> s @@ -564,13 +563,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } done?<span class="Special"> <- </span>greater-or-equal row, screen-height <span class="muControl">break-if</span> done? c:character<span class="Special"> <- </span>index *s, i - <span class="Constant"><character-c-received></span> <span class="Comment"># only line different from render-string</span> + <span class="Constant"><character-c-received></span> <span class="Comment"># only line different from render</span> <span class="Delimiter">{</span> <span class="Comment"># at right? wrap.</span> at-right?:boolean<span class="Special"> <- </span>equal column, right <span class="muControl">break-unless</span> at-right? <span class="Comment"># print wrap icon</span> - print-character screen, <span class="Constant">8617/loop-back-to-left</span>, <span class="Constant">245/grey</span> + print 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> screen<span class="Special"> <- </span>move-cursor screen, row, column @@ -585,7 +584,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">{</span> done?:boolean<span class="Special"> <- </span>greater-than column, right <span class="muControl">break-if</span> done? - print-character screen, <span class="Constant">32/space</span> + print screen, <span class="Constant">32/space</span> column<span class="Special"> <- </span>add column, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> @@ -594,7 +593,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } 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 + print screen, c, color column<span class="Special"> <- </span>add column, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> @@ -632,131 +631,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">}</span> ] -<span class="Comment"># ctrl-x - maximize/unmaximize the side with focus</span> - -<span class="muScenario">scenario</span> maximize-side [ - trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</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:screen, <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 [ - press ctrl-x - ] - run [ - event-loop screen:address:screen, console:address:console, <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 ctrl-x - ] - run [ - event-loop screen:address:screen, console:address:console, <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="CommentedCode">#? # ctrl-t - browse trace</span> -<span class="CommentedCode">#? after <global-type> [</span> -<span class="CommentedCode">#? {</span> -<span class="CommentedCode">#? browse-trace?:boolean <- equal *c, 20/ctrl-t</span> -<span class="CommentedCode">#? break-unless browse-trace?</span> -<span class="CommentedCode">#? $browse-trace</span> -<span class="CommentedCode">#? screen <- render-all screen, env:address:programming-environment-data</span> -<span class="CommentedCode">#? loop +next-event:label</span> -<span class="CommentedCode">#? }</span> -<span class="CommentedCode">#? ]</span> - -<span class="muData">container</span> programming-environment-data [ - maximized?:boolean -] - -<span class="muRecipe">after</span> <span class="Constant"><global-type></span> [ - <span class="Delimiter">{</span> - maximize?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">24/ctrl-x</span> - <span class="muControl">break-unless</span> maximize? - 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 screen:address:screen, console:address:console, env:address:programming-environment-data<span class="muRecipe"> -> </span>screen:address:screen, console:address:console [ - <span class="Constant">local-scope</span> - <span class="Constant">load-ingredients</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="Comment"># when maximized, wait for any event and simply unmaximize</span> -<span class="muRecipe">after</span> <span class="Constant"><handle-event></span> [ - <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">## helpers</span> <span class="muRecipe">recipe</span> draw-vertical screen:address:screen, col:number, y:number, bottom:number [ @@ -777,7 +651,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } continue?:boolean<span class="Special"> <- </span>lesser-than y, bottom <span class="muControl">break-unless</span> continue? screen<span class="Special"> <- </span>move-cursor screen, y, col - print-character screen, style, color + print screen, style, color y<span class="Special"> <- </span>add y, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> diff --git a/html/edit/005-sandbox.mu.html b/html/edit/005-sandbox.mu.html index 85fdf7da..9c219526 100644 --- a/html/edit/005-sandbox.mu.html +++ b/html/edit/005-sandbox.mu.html @@ -229,7 +229,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant">local-scope</span> <span class="Constant">load-ingredients</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> + screen<span class="Special"> <- </span>print screen, msg, color, <span class="Constant">238/grey/background</span> ] <span class="muRecipe">recipe</span> save-sandboxes env:address:programming-environment-data [ @@ -244,12 +244,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">{</span> <span class="muControl">break-unless</span> curr data:address:array:character<span class="Special"> <- </span>get *curr, <span class="Constant">data:offset</span> - filename:address:array:character<span class="Special"> <- </span>integer-to-decimal-string idx + filename:address:array:character<span class="Special"> <- </span>to-text idx save filename, data <span class="Delimiter">{</span> expected-response:address:array:character<span class="Special"> <- </span>get *curr, <span class="Constant">expected-response:offset</span> <span class="muControl">break-unless</span> expected-response - filename<span class="Special"> <- </span>string-append filename, suffix + filename<span class="Special"> <- </span>append filename, suffix save filename, expected-response <span class="Delimiter">}</span> idx<span class="Special"> <- </span>add idx, <span class="Constant">1</span> @@ -285,7 +285,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } row<span class="Special"> <- </span>add row, <span class="Constant">1</span> 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> + print 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> starting-row:address:number<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">starting-row-on-screen:offset</span> *starting-row<span class="Special"> <- </span>copy row @@ -293,7 +293,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } row<span class="Special"> <- </span>add row, <span class="Constant">1</span> screen<span class="Special"> <- </span>move-cursor screen, row, left sandbox-data:address:array:character<span class="Special"> <- </span>get *sandbox, <span class="Constant">data:offset</span> - row, screen<span class="Special"> <- </span>render-code-string screen, sandbox-data, left, right, row + row, screen<span class="Special"> <- </span>render-code screen, sandbox-data, left, right, 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> @@ -310,7 +310,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">break-unless</span> empty-screen? *response-starting-row<span class="Special"> <- </span>copy row <span class="Constant"> <render-sandbox-response></span> - row, screen<span class="Special"> <- </span>render-string screen, sandbox-response, left, right, <span class="Constant">245/grey</span>, row + row, screen<span class="Special"> <- </span>render screen, sandbox-response, left, right, <span class="Constant">245/grey</span>, row <span class="Delimiter">}</span> <span class="Constant"> +render-sandbox-end</span> at-bottom?:boolean<span class="Special"> <- </span>greater-or-equal row, screen-height @@ -331,7 +331,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } idx:number<span class="Special"> <- </span>copy <span class="Constant">0</span> curr:address:address:sandbox-data<span class="Special"> <- </span>get-address *env, <span class="Constant">sandbox:offset</span> <span class="Delimiter">{</span> - filename:address:array:character<span class="Special"> <- </span>integer-to-decimal-string idx + filename:address:array:character<span class="Special"> <- </span>to-text idx contents:address:array:character<span class="Special"> <- </span>restore filename <span class="muControl">break-unless</span> contents <span class="Comment"># stop at first error; assuming file didn't exist</span> <span class="Comment"># create new sandbox for file</span> @@ -340,7 +340,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } *data<span class="Special"> <- </span>copy contents <span class="Comment"># restore expected output for sandbox if it exists</span> <span class="Delimiter">{</span> - filename<span class="Special"> <- </span>string-append filename, suffix + filename<span class="Special"> <- </span>append filename, suffix contents<span class="Special"> <- </span>restore filename <span class="muControl">break-unless</span> contents expected-response:address:address:array:character<span class="Special"> <- </span>get-address **curr, <span class="Constant">expected-response:offset</span> @@ -361,7 +361,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">reply-unless</span> sandbox-screen <span class="Comment"># print 'screen:'</span> header:address:array:character<span class="Special"> <- </span>new <span class="Constant">[screen:]</span> - row<span class="Special"> <- </span>render-string screen, header, left, right, <span class="Constant">245/grey</span>, row + row<span class="Special"> <- </span>render screen, header, left, right, <span class="Constant">245/grey</span>, row screen<span class="Special"> <- </span>move-cursor screen, row, left <span class="Comment"># start printing sandbox-screen</span> column:number<span class="Special"> <- </span>copy left @@ -381,9 +381,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } column<span class="Special"> <- </span>copy left 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> - print-character screen, <span class="Constant">46/full-stop</span>, <span class="Constant">245/grey</span> + print screen, <span class="Constant">32/space</span>, <span class="Constant">245/grey</span> + print screen, <span class="Constant">32/space</span>, <span class="Constant">245/grey</span> + print screen, <span class="Constant">46/full-stop</span>, <span class="Constant">245/grey</span> column<span class="Special"> <- </span>add left, <span class="Constant">3</span> <span class="Delimiter">{</span> <span class="Comment"># print row</span> @@ -398,19 +398,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">break-unless</span> white? color<span class="Special"> <- </span>copy <span class="Constant">245/grey</span> <span class="Delimiter">}</span> - print-character screen, c, color + print screen, c, color column<span class="Special"> <- </span>add column, <span class="Constant">1</span> i<span class="Special"> <- </span>add i, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> <span class="Comment"># print final '.'</span> - print-character screen, <span class="Constant">46/full-stop</span>, <span class="Constant">245/grey</span> + print screen, <span class="Constant">46/full-stop</span>, <span class="Constant">245/grey</span> column<span class="Special"> <- </span>add column, <span class="Constant">1</span> <span class="Delimiter">{</span> <span class="Comment"># clear rest of current line</span> line-done?:boolean<span class="Special"> <- </span>greater-than column, right <span class="muControl">break-if</span> line-done? - print-character screen, <span class="Constant">32/space</span> + print screen, <span class="Constant">32/space</span> column<span class="Special"> <- </span>add column, <span class="Constant">1</span> <span class="muControl">loop</span> <span class="Delimiter">}</span> @@ -514,7 +514,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">{</span> <span class="muControl">break-unless</span> curr c:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span> - buffer-append buf, c + buf<span class="Special"> <- </span>append buf, c curr<span class="Special"> <- </span>next curr <span class="muControl">loop</span> <span class="Delimiter">}</span> @@ -535,7 +535,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant">4</span>:array:character<span class="Special"> <- </span>copy *<span class="Constant">3</span>:address:array:character ] memory-should-contain [ - <span class="Constant">4</span>:string<span class="Special"> <- </span><span class="Constant">[abdefc]</span> + <span class="Constant">4</span>:array:character<span class="Special"> <- </span><span class="Constant">[abdefc]</span> ] ] </pre> diff --git a/html/edit/008-sandbox-test.mu.html b/html/edit/008-sandbox-test.mu.html index 08b62ddc..bdf918e8 100644 --- a/html/edit/008-sandbox-test.mu.html +++ b/html/edit/008-sandbox-test.mu.html @@ -79,7 +79,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] <span class="Comment"># cursor should remain unmoved</span> run [ - print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span> + print screen:address:screen, <span class="Constant">9251/␣/cursor</span> ] screen-should-contain [ <span class="Constant"> . run (F4) .</span> @@ -191,14 +191,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">break-unless</span> sandbox-response expected-response:address:array:character<span class="Special"> <- </span>get *sandbox, <span class="Constant">expected-response:offset</span> <span class="muControl">break-unless</span> expected-response <span class="Comment"># fall-through to print in grey</span> - response-is-expected?:boolean<span class="Special"> <- </span>string-equal expected-response, sandbox-response + response-is-expected?:boolean<span class="Special"> <- </span>equal expected-response, sandbox-response <span class="Delimiter">{</span> <span class="muControl">break-if</span> response-is-expected?:boolean - row, screen<span class="Special"> <- </span>render-string screen, sandbox-response, left, right, <span class="Constant">1/red</span>, row + row, screen<span class="Special"> <- </span>render screen, sandbox-response, left, right, <span class="Constant">1/red</span>, row <span class="Delimiter">}</span> <span class="Delimiter">{</span> <span class="muControl">break-unless</span> response-is-expected?:boolean - row, screen<span class="Special"> <- </span>render-string screen, sandbox-response, left, right, <span class="Constant">2/green</span>, row + row, screen<span class="Special"> <- </span>render screen, sandbox-response, left, right, <span class="Constant">2/green</span>, row <span class="Delimiter">}</span> <span class="muControl">jump</span> <span class="Constant">+render-sandbox-end:label</span> <span class="Delimiter">}</span> diff --git a/html/edit/009-sandbox-trace.mu.html b/html/edit/009-sandbox-trace.mu.html index 071f62af..6d5603bd 100644 --- a/html/edit/009-sandbox-trace.mu.html +++ b/html/edit/009-sandbox-trace.mu.html @@ -65,7 +65,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] run [ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data - print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span> + print screen:address:screen, <span class="Constant">9251/␣/cursor</span> ] <span class="Comment"># trace now printed and cursor shouldn't have budged</span> screen-should-contain [ @@ -94,7 +94,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] run [ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data - print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span> + print screen:address:screen, <span class="Constant">9251/␣/cursor</span> ] <span class="Comment"># trace hidden again</span> screen-should-contain [ @@ -238,7 +238,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">break-unless</span> display-trace? sandbox-trace:address:array:character<span class="Special"> <- </span>get *sandbox, <span class="Constant">trace:offset</span> <span class="muControl">break-unless</span> sandbox-trace <span class="Comment"># nothing to print; move on</span> - row, screen<span class="Special"> <- </span>render-string, screen, sandbox-trace, left, right, <span class="Constant">245/grey</span>, row + row, screen<span class="Special"> <- </span>render screen, sandbox-trace, left, right, <span class="Constant">245/grey</span>, row <span class="Delimiter">}</span> <span class="Constant"> <render-sandbox-trace-done></span> ] diff --git a/html/edit/010-warnings.mu.html b/html/edit/010-warnings.mu.html index 335bfb42..6d746bf5 100644 --- a/html/edit/010-warnings.mu.html +++ b/html/edit/010-warnings.mu.html @@ -20,6 +20,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } .SalientComment { color: #00ffff; } +.CommentedCode { color: #6c6c6c; } .Delimiter { color: #a04060; } .muScenario { color: #00af00; } --> @@ -73,7 +74,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">{</span> recipe-warnings:address:array:character<span class="Special"> <- </span>get *env, <span class="Constant">recipe-warnings:offset</span> <span class="muControl">break-unless</span> recipe-warnings - row, screen<span class="Special"> <- </span>render-string screen, recipe-warnings, left, right, <span class="Constant">1/red</span>, row + row, screen<span class="Special"> <- </span>render screen, recipe-warnings, left, right, <span class="Constant">1/red</span>, row <span class="Delimiter">}</span> ] @@ -89,6 +90,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } warnings:address:address:array:character<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">warnings:offset</span> trace:address:address:array:character<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">trace:offset</span> fake-screen:address:address:screen<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">screen:offset</span> +<span class="CommentedCode">#? $print [run-interactive], 10/newline</span> *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 @@ -96,6 +98,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } *warnings<span class="Special"> <- </span>new <span class="Constant">[took too long!</span> <span class="Constant">]</span> <span class="Delimiter">}</span> +<span class="CommentedCode">#? $print [done with run-interactive], 10/newline</span> ] <span class="Comment"># make sure we render any trace</span> @@ -104,7 +107,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } sandbox-warnings:address:array:character<span class="Special"> <- </span>get *sandbox, <span class="Constant">warnings:offset</span> <span class="muControl">break-unless</span> sandbox-warnings *response-starting-row<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># no response</span> - row, screen<span class="Special"> <- </span>render-string screen, sandbox-warnings, left, right, <span class="Constant">1/red</span>, row + row, screen<span class="Special"> <- </span>render screen, sandbox-warnings, left, right, <span class="Constant">1/red</span>, row <span class="Comment"># don't try to print anything more for this sandbox</span> <span class="muControl">jump</span> <span class="Constant">+render-sandbox-end:label</span> <span class="Delimiter">}</span> @@ -150,6 +153,88 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] +<span class="muScenario">scenario</span> run-hides-warnings-from-past-sandboxes [ + trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</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">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[get foo, x:offset]</span> <span class="Comment"># invalid</span> + <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character + assume-console [ + press F4 <span class="Comment"># generate error</span> + ] + run [ + event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data + ] + assume-console [ + left-click <span class="Constant">3</span>, <span class="Constant">80</span> + press ctrl-k + type <span class="Constant">[add 2, 2]</span> <span class="Comment"># valid code</span> + press F4 <span class="Comment"># error should disappear</span> + ] + run [ + event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data + ] + 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"> . ┊add 2, 2 .</span> + <span class="Constant"> . ┊4 .</span> + <span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ .</span> + ] +] + +<span class="muScenario">scenario</span> run-updates-warnings-for-shape-shifting-recipes [ + trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span> + assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span> + <span class="Comment"># define a shape-shifting recipe with an error</span> + <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[recipe foo x:_elem -> z:_elem [</span> +<span class="Constant">local-scope</span> +<span class="Constant">load-ingredients</span> +<span class="Constant">z <- add x, [a]</span> +]] + <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo 2]</span> + <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character + assume-console [ + press F4 + ] + run [ + event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data + ] + screen-should-contain [ + <span class="Constant"> . run (F4) .</span> + <span class="Constant"> .recipe foo x:_elem -> z:_elem [ ┊ .</span> + <span class="Constant"> .local-scope ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> .load-ingredients ┊ x.</span> + <span class="Constant"> .z <- add x, [a] ┊foo 2 .</span> + <span class="Constant"> .] ┊foo_2: 'add' requires number ingredients, but go↩.</span> + <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊t [a] .</span> + <span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ .</span> + ] + <span class="Comment"># now rerun everything</span> + assume-console [ + press F4 + ] + run [ + event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data + ] + <span class="Comment"># error should remain unchanged</span> + screen-should-contain [ + <span class="Constant"> . run (F4) .</span> + <span class="Constant"> .recipe foo x:_elem -> z:_elem [ ┊ .</span> + <span class="Constant"> .local-scope ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> .load-ingredients ┊ x.</span> + <span class="Constant"> .z <- add x, [a] ┊foo 2 .</span> + <span class="Constant"> .] ┊foo_2: 'add' requires number ingredients, but go↩.</span> + <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊t [a] .</span> + <span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . ┊ .</span> + ] +] + <span class="muScenario">scenario</span> run-shows-missing-type-warnings [ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span> assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span> @@ -183,7 +268,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <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> + 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:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character assume-console [ diff --git a/html/edit/011-editor-undo.mu.html b/html/edit/011-editor-undo.mu.html index 5a3f537e..801ca648 100644 --- a/html/edit/011-editor-undo.mu.html +++ b/html/edit/011-editor-undo.mu.html @@ -2105,10 +2105,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant"> . .</span> ] ] - -<span class="Comment"># todo:</span> -<span class="Comment"># operations for recipe side and each sandbox-data</span> -<span class="Comment"># undo delete sandbox as a separate primitive on the status bar</span> </pre> </body> </html> diff --git a/html/screen.mu.html b/html/screen.mu.html index 6efea923..ea2b0232 100644 --- a/html/screen.mu.html +++ b/html/screen.mu.html @@ -35,12 +35,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muRecipe">recipe</span> main [ open-console - print-character <span class="Constant">0/screen</span>, <span class="Constant">97/a</span>, <span class="Constant">2/red</span> + print <span class="Constant">0/screen</span>, <span class="Constant">97/a</span>, <span class="Constant">2/red</span> <span class="Constant">1</span>:number/<span class="Special">raw</span>, <span class="Constant">2</span>:number/<span class="Special">raw <- </span>cursor-position <span class="Constant">0/screen</span> wait-for-event <span class="Constant">0/console</span> clear-screen <span class="Constant">0/screen</span> move-cursor <span class="Constant">0/screen</span>, <span class="Constant">0/row</span>, <span class="Constant">4/column</span> - print-character <span class="Constant">0/screen</span>, <span class="Constant">98/b</span> + print <span class="Constant">0/screen</span>, <span class="Constant">98/b</span> wait-for-event <span class="Constant">0/console</span> move-cursor <span class="Constant">0/screen</span>, <span class="Constant">0/row</span>, <span class="Constant">0/column</span> clear-line <span class="Constant">0/screen</span> diff --git a/index.html b/index.html index 24b8e0c0..e498b82f 100644 --- a/index.html +++ b/index.html @@ -166,7 +166,7 @@ various address spaces in the core, and the conventions that regulate their use in previous layers. <p><b>Part IV</b>: beginnings of a standard library -<p/><a href='html/070string.mu.html'>070string.mu</a>: strings in Mu are +<p/><a href='html/070text.mu.html'>070text.mu</a>: strings in Mu are bounds-checked rather than null-terminated. They're also unicode-aware (code points only; no control characters, no combining characters, no normalization). <br/><a href='html/071channel.mu.html'>071channel.mu</a>: channels are Mu's @@ -239,7 +239,8 @@ golden/expected. Any future changes to the output will then be flagged in red. <br/><a href='html/edit/009-sandbox-trace.mu.html'>edit/009-sandbox-trace.mu</a>: click on code in a sandbox to open up a drawer containing its trace. The trace can be added to using the <span style='font-family:courier,fixed'>stash</span> -command. +command, which renders arbitrary data structures using <span style='font-family:courier,fixed'>to-text</span> +with the appropriate recipe header. <br/><a href='html/edit/010-warnings.mu.html'>edit/010-warnings.mu</a>: support for rendering warnings on both the left and in each sandbox. <br/><a href='html/edit/011-editor-undo.mu.html'>edit/011-editor-undo.mu</a>: |