diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-02-02 09:59:40 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-02-02 09:59:40 -0800 |
commit | b2566a847948ba808d4ca93d02bcc62ee6487255 (patch) | |
tree | d5c983969695b271b4821d90f0354af317d76891 | |
parent | 67d2a9c07dea2f100f526cf6cd0831b544cd73fa (diff) | |
download | mu-b2566a847948ba808d4ca93d02bcc62ee6487255.tar.gz |
2625
-rw-r--r-- | html/010vm.cc.html | 3 | ||||
-rw-r--r-- | html/011load.cc.html | 4 | ||||
-rw-r--r-- | html/020run.cc.html | 3 | ||||
-rw-r--r-- | html/021check_instruction.cc.html | 76 | ||||
-rw-r--r-- | html/029tools.cc.html | 2 | ||||
-rw-r--r-- | html/031address.cc.html | 6 | ||||
-rw-r--r-- | html/038new.cc.html | 99 | ||||
-rw-r--r-- | html/042name.cc.html | 10 | ||||
-rw-r--r-- | html/043space.cc.html | 49 | ||||
-rw-r--r-- | html/046global.cc.html | 2 | ||||
-rw-r--r-- | html/047check_type_by_name.cc.html | 4 | ||||
-rw-r--r-- | html/050scenario.cc.html | 7 | ||||
-rw-r--r-- | html/052tangle.cc.html | 2 | ||||
-rw-r--r-- | html/056recipe_header.cc.html | 6 | ||||
-rw-r--r-- | html/057static_dispatch.cc.html | 46 | ||||
-rw-r--r-- | html/059shape_shifting_recipe.cc.html | 63 | ||||
-rw-r--r-- | html/061recipe.cc.html | 14 | ||||
-rw-r--r-- | html/070text.mu.html | 8 | ||||
-rw-r--r-- | html/edit/003-shortcuts.mu.html | 81 | ||||
-rw-r--r-- | html/edit/005-sandbox.mu.html | 57 | ||||
-rw-r--r-- | html/edit/006-sandbox-edit.mu.html | 8 | ||||
-rw-r--r-- | html/edit/007-sandbox-delete.mu.html | 16 | ||||
-rw-r--r-- | html/edit/008-sandbox-test.mu.html | 29 | ||||
-rw-r--r-- | html/edit/010-warnings.mu.html | 20 |
24 files changed, 457 insertions, 158 deletions
diff --git a/html/010vm.cc.html b/html/010vm.cc.html index 40ae0c5e..3b090c34 100644 --- a/html/010vm.cc.html +++ b/html/010vm.cc.html @@ -69,6 +69,7 @@ struct instruction <span class="Delimiter">{</span> string label<span class="Delimiter">;</span> <span class="Comment">// only if is_label</span> string name<span class="Delimiter">;</span> <span class="Comment">// only if !is_label</span> string old_name<span class="Delimiter">;</span> <span class="Comment">// before our automatic rewrite rules</span> + string original_string<span class="Delimiter">;</span> recipe_ordinal operation<span class="Delimiter">;</span> <span class="Comment">// get(Recipe_ordinal, name)</span> vector<reagent> ingredients<span class="Delimiter">;</span> <span class="Comment">// only if !is_label</span> vector<reagent> products<span class="Delimiter">;</span> <span class="Comment">// only if !is_label</span> @@ -262,7 +263,7 @@ recipe::recipe<span class="Delimiter">()</span> <span class="Delimiter">{</span> instruction::instruction<span class="Delimiter">()</span> :is_label<span class="Delimiter">(</span><span class="Constant">false</span><span class="Delimiter">),</span> operation<span class="Delimiter">(</span>IDLE<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// End instruction Constructor</span> <span class="Delimiter">}</span> -void instruction::clear<span class="Delimiter">()</span> <span class="Delimiter">{</span> is_label=<span class="Constant">false</span><span class="Delimiter">;</span> label<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> name<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> old_name<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> operation=IDLE<span class="Delimiter">;</span> ingredients<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> products<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> <span class="Delimiter">}</span> +void instruction::clear<span class="Delimiter">()</span> <span class="Delimiter">{</span> is_label=<span class="Constant">false</span><span class="Delimiter">;</span> label<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> name<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> old_name<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> operation=IDLE<span class="Delimiter">;</span> ingredients<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> products<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> original_string<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> <span class="Delimiter">}</span> bool instruction::is_clear<span class="Delimiter">()</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> !is_label && name<span class="Delimiter">.</span>empty<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Comment">// Reagents have the form <name>:<type>:<type>:.../<property>/<property>/...</span> diff --git a/html/011load.cc.html b/html/011load.cc.html index 1bb04a8c..205faacf 100644 --- a/html/011load.cc.html +++ b/html/011load.cc.html @@ -109,8 +109,10 @@ void slurp_body<span class="Delimiter">(</span>istream& in<span class="Delim while <span class="Delimiter">(</span>next_instruction<span class="Delimiter">(</span>in<span class="Delimiter">,</span> &curr<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Comment">// End Rewrite Instruction(curr, recipe result)</span> trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">"load"</span><span class="Delimiter">)</span> << <span class="Constant">"after rewriting: "</span> << curr<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << end<span class="Delimiter">();</span> - if <span class="Delimiter">(</span>!curr<span class="Delimiter">.</span>is_clear<span class="Delimiter">())</span> + if <span class="Delimiter">(</span>!curr<span class="Delimiter">.</span>is_clear<span class="Delimiter">())</span> <span class="Delimiter">{</span> + curr<span class="Delimiter">.</span>original_string = curr<span class="Delimiter">.</span>to_string<span class="Delimiter">();</span> result<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>curr<span class="Delimiter">);</span> + <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> diff --git a/html/020run.cc.html b/html/020run.cc.html index 4194981e..9e3e13a3 100644 --- a/html/020run.cc.html +++ b/html/020run.cc.html @@ -97,6 +97,7 @@ void run_current_routine<span class="Delimiter">()</span> while <span class="Delimiter">(</span>!Current_routine<span class="Delimiter">-></span>completed<span class="Delimiter">())</span> <span class="Comment">// later layers will modify condition</span> <span class="Delimiter">{</span> <span class="Comment">// Running One Instruction</span> +<span class="CommentedCode">//? trace(9999, "aaaa") << "location 1 contains " << get_or_insert(Memory, 1) << end();</span> <span class="CommentedCode">//? Instructions_running[current_recipe_name()]++;</span> if <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>is_label<span class="Delimiter">)</span> <span class="Delimiter">{</span> ++current_step_index<span class="Delimiter">();</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> trace<span class="Delimiter">(</span>Initial_callstack_depth + Trace_stream<span class="Delimiter">-></span>callstack_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << end<span class="Delimiter">();</span> @@ -169,6 +170,7 @@ inline bool routine::completed<span class="Delimiter">()</span> const <span clas <span class="Comment">//: Step 1: load all .mu files with numeric prefixes (in order)</span> <span class="Delimiter">:(before "End Load Recipes")</span> +<span class="Comment">// Load .mu Core</span> <span class="CommentedCode">//? Trace_file = "interactive";</span> <span class="CommentedCode">//? START_TRACING_UNTIL_END_OF_SCOPE;</span> load_permanently<span class="Delimiter">(</span><span class="Constant">"core.mu"</span><span class="Delimiter">);</span> @@ -198,6 +200,7 @@ if <span class="Delimiter">(</span>argc > <span class="Constant">1</span><spa <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> <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> + <span class="Comment">// Running Main</span> setup<span class="Delimiter">();</span> <span class="CommentedCode">//? Trace_file = "interactive";</span> <span class="CommentedCode">//? START_TRACING_UNTIL_END_OF_SCOPE;</span> diff --git a/html/021check_instruction.cc.html b/html/021check_instruction.cc.html index c0229312..d98db0da 100644 --- a/html/021check_instruction.cc.html +++ b/html/021check_instruction.cc.html @@ -115,59 +115,69 @@ recipe main [ <span class="traceContains">+mem: storing 12 in location 2</span> $error: <span class="Constant">0</span> +<span class="Delimiter">:(scenario write_boolean_to_number_allowed)</span> +<span class="Special">% Hide_errors = true;</span> +recipe main [ + <span class="Constant">1</span>:boolean<span class="Special"> <- </span>copy <span class="Constant">1</span>/<span class="Constant">true</span> + <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:boolean +] +<span class="traceContains">+mem: storing 1 in location 2</span> +$error: <span class="Constant">0</span> + <span class="Delimiter">:(code)</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> +bool types_coercible<span class="Delimiter">(</span>const reagent& to<span class="Delimiter">,</span> const reagent& from<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>types_match<span class="Delimiter">(</span>to<span class="Delimiter">,</span> from<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>from<span class="Delimiter">)</span> && is_mu_number<span class="Delimiter">(</span>to<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_boolean<span class="Delimiter">(</span>from<span class="Delimiter">)</span> && is_mu_number<span class="Delimiter">(</span>to<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> +bool types_match<span class="Delimiter">(</span>const reagent& to<span class="Delimiter">,</span> const reagent& from<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> + if <span class="Delimiter">(</span>is_unsafe<span class="Delimiter">(</span>from<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>from<span class="Delimiter">))</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>is_mu_array<span class="Delimiter">(</span>to<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(to)</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> + if <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>to<span class="Delimiter">))</span> <span class="Identifier">return</span> from<span class="Delimiter">.</span>name == <span class="Constant">"0"</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!to<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>to<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>to<span class="Delimiter">,</span> from<span class="Delimiter">);</span> + <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>to<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="Identifier">return</span> types_strictly_match<span class="Delimiter">(</span>to<span class="Delimiter">,</span> from<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> +bool boolean_matches_literal<span class="Delimiter">(</span>const reagent& to<span class="Delimiter">,</span> const reagent& from<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>from<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!to<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>to<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> from<span class="Delimiter">.</span>name == <span class="Constant">"0"</span> || from<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> +bool types_strictly_match<span class="Delimiter">(</span>reagent to<span class="Delimiter">,</span> reagent from<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>from<span class="Delimiter">)</span> && to<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> + if <span class="Delimiter">(</span>is_unsafe<span class="Delimiter">(</span>from<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> - 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_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> + if <span class="Delimiter">(</span>is_dummy<span class="Delimiter">(</span>to<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!to<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span> !from<span class="Delimiter">.</span>type<span class="Delimiter">;</span> + <span class="Identifier">return</span> types_strictly_match<span class="Delimiter">(</span>to<span class="Delimiter">.</span>type<span class="Delimiter">,</span> from<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_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<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_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> +bool types_strictly_match<span class="Delimiter">(</span>type_tree* to<span class="Delimiter">,</span> type_tree* from<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!to<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!from<span class="Delimiter">)</span> <span class="Identifier">return</span> to<span class="Delimiter">-></span>value == <span class="Constant">0</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>to<span class="Delimiter">-></span>value != from<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_strictly_match<span class="Delimiter">(</span>to<span class="Delimiter">-></span>left<span class="Delimiter">,</span> from<span class="Delimiter">-></span>left<span class="Delimiter">)</span> && types_strictly_match<span class="Delimiter">(</span>to<span class="Delimiter">-></span>right<span class="Delimiter">,</span> from<span class="Delimiter">-></span>right<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> @@ -186,6 +196,12 @@ bool is_mu_address<span class="Delimiter">(</span>reagent r<span class="Delimite <span class="Identifier">return</span> r<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="Delimiter">}</span> +bool is_mu_boolean<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> + <span class="Identifier">return</span> r<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="Delimiter">}</span> + bool is_mu_number<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="Delimiter">{</span> diff --git a/html/029tools.cc.html b/html/029tools.cc.html index 69b67fb9..7944d991 100644 --- a/html/029tools.cc.html +++ b/html/029tools.cc.html @@ -359,7 +359,7 @@ case _LOG: <span class="Delimiter">{</span> for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> out << print_mu<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> <span class="Delimiter">}</span> - LOG << out<span class="Delimiter">.</span>str<span class="Delimiter">()</span> << <span class="Constant">"(length: "</span> << get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"length"</span><span class="Delimiter">)</span> << <span class="Constant">'/'</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">"length"</span><span class="Delimiter">))</span> << <span class="Constant">")</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span> + LOG << out<span class="Delimiter">.</span>str<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> </pre> diff --git a/html/031address.cc.html b/html/031address.cc.html index e039b331..a2da3614 100644 --- a/html/031address.cc.html +++ b/html/031address.cc.html @@ -106,9 +106,9 @@ recipe foo [ ] <span class="Comment"># don't crash</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> +<span class="Delimiter">:(after "bool types_strictly_match(reagent to, reagent from)")</span> + if <span class="Delimiter">(</span>!canonize_type<span class="Delimiter">(</span>to<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>from<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">:(after "bool is_mu_array(reagent r)")</span> if <span class="Delimiter">(</span>!canonize_type<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/038new.cc.html b/html/038new.cc.html index 1ba4365a..07a6d9ec 100644 --- a/html/038new.cc.html +++ b/html/038new.cc.html @@ -22,7 +22,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } .Special { color: #ff6060; } .Identifier { color: #804000; } .Constant { color: #00a0a0; } -.Todo { color: #000000; background-color: #ffff00; padding-bottom: 1px; } --> </style> @@ -130,21 +129,28 @@ case NEW: <span class="Delimiter">{</span> raise_error << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"result of 'new' should never be ignored</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - reagent product<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> + if <span class="Delimiter">(</span>!product_of_new_is_valid<span class="Delimiter">(</span>inst<span class="Delimiter">))</span> <span class="Delimiter">{</span> + raise_error << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"product of 'new' has incorrect type: "</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> +<span class="Delimiter">:(code)</span> +bool product_of_new_is_valid<span class="Delimiter">(</span>const instruction& inst<span class="Delimiter">)</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> canonize_type<span class="Delimiter">(</span>product<span class="Delimiter">);</span> + if <span class="Delimiter">(</span>!product<span class="Delimiter">.</span>type || product<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> <span class="Constant">false</span><span class="Delimiter">;</span> drop_from_type<span class="Delimiter">(</span>product<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">);</span> + if <span class="Delimiter">(</span>!product<span class="Delimiter">.</span>type || product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"shared"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> drop_from_type<span class="Delimiter">(</span>product<span class="Delimiter">,</span> <span class="Constant">"shared"</span><span class="Delimiter">);</span> if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// array allocation</span> + if <span class="Delimiter">(</span>!product<span class="Delimiter">.</span>type || product<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> drop_from_type<span class="Delimiter">(</span>product<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> - reagent expected_product<span class="Delimiter">(</span><span class="Constant">"x:"</span>+type<span class="Delimiter">.</span>name<span class="Delimiter">);</span> + reagent expected_product<span class="Delimiter">(</span><span class="Constant">"x:"</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> <span class="Comment">// End Post-processing(expected_product) When Checking 'new'</span> - if <span class="Delimiter">(</span>!types_strictly_match<span class="Delimiter">(</span>product<span class="Delimiter">,</span> expected_product<span class="Delimiter">))</span> <span class="Delimiter">{</span> - raise_error << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"product of 'new' has incorrect type: "</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> - <span class="Identifier">break</span><span class="Delimiter">;</span> - <span class="Delimiter">}</span> - <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Identifier">return</span> types_strictly_match<span class="Delimiter">(</span>product<span class="Delimiter">,</span> expected_product<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="SalientComment">//:: translate 'new' to 'allocate' instructions that take a size instead of a type</span> @@ -265,6 +271,13 @@ recipe main [ ] <span class="traceContains">+mem: storing 0 in location 2</span> +<span class="Delimiter">:(scenario new_error)</span> +<span class="Special">% Hide_errors = true;</span> +recipe main [ + <span class="Constant">1</span>:address:number/<span class="Special">raw <- </span>new number:type +] +<span class="traceContains">+error: main: product of 'new' has incorrect type: 1:address:number/raw <- new number:type</span> + <span class="Delimiter">:(scenario new_array)</span> recipe main [ <span class="Constant">1</span>:address:shared:array:number/<span class="Special">raw <- </span>new number:type<span class="Delimiter">,</span> <span class="Constant">5</span> @@ -457,6 +470,7 @@ if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span cl put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> old_address<span class="Delimiter">,</span> old_refcount-<span class="Constant">1</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Comment">// perform the write</span> +<span class="CommentedCode">//? trace(9999, "mem") << "038new.cc:424: location " << x.value << " contains " << old_address << " with refcount " << get_or_insert(Memory, old_address) << end();</span> trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"mem"</span><span class="Delimiter">)</span> << <span class="Constant">"storing "</span> << no_scientific<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">" in location "</span> << base << end<span class="Delimiter">();</span> put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> base<span class="Delimiter">,</span> new_address<span class="Delimiter">);</span> <span class="Comment">// increment refcount of new address</span> @@ -468,7 +482,9 @@ if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span cl <span class="Delimiter">}</span> <span class="Comment">// abandon old address if necessary</span> <span class="Comment">// do this after all refcount updates are done just in case old and new are identical</span> - <span class="Comment">// </span><span class="Todo">TODO</span><span class="Comment">: doesn't work yet</span> +<span class="CommentedCode">//? if (get_or_insert(Memory, old_address) < 0) {</span> +<span class="CommentedCode">//? DUMP("");</span> +<span class="CommentedCode">//? }</span> assert<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> old_address<span class="Delimiter">)</span> >= <span class="Constant">0</span><span class="Delimiter">);</span> if <span class="Delimiter">(</span>old_address && get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> old_address<span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// lookup_memory without drop_one_lookup {</span> @@ -478,11 +494,76 @@ if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span cl drop_from_type<span class="Delimiter">(</span>x<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">);</span> drop_from_type<span class="Delimiter">(</span>x<span class="Delimiter">,</span> <span class="Constant">"shared"</span><span class="Delimiter">);</span> <span class="Comment">// }</span> +<span class="CommentedCode">//? cerr << "ABANDON\n";</span> abandon<span class="Delimiter">(</span>old_address<span class="Delimiter">,</span> size_of<span class="Delimiter">(</span>x<span class="Delimiter">)</span>+<span class="Comment">/*</span><span class="Comment">refcount</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> +<span class="Delimiter">:(scenario refcounts_2)</span> +recipe main [ + <span class="Constant">1</span>:address:shared:number<span class="Special"> <- </span>new number:type + <span class="Comment"># over-writing one allocation with another</span> + <span class="Constant">1</span>:address:shared:number<span class="Special"> <- </span>new number:type + <span class="Constant">1</span>:address:shared:number<span class="Special"> <- </span>copy <span class="Constant">0</span> +] +<span class="traceContains">+run: 1:address:shared:number <- new number:type</span> +<span class="traceContains">+mem: incrementing refcount of 1000: 0 -> 1</span> +<span class="traceContains">+run: 1:address:shared:number <- new number:type</span> +<span class="traceContains">+mem: automatically abandoning 1000</span> + +<span class="Delimiter">:(scenario refcounts_3)</span> +recipe main [ + <span class="Constant">1</span>:address:shared:number<span class="Special"> <- </span>new number:type + <span class="Comment"># passing in addresses to recipes increments refcount</span> + foo <span class="Constant">1</span>:address:shared:number + <span class="Constant">1</span>:address:shared:number<span class="Special"> <- </span>copy <span class="Constant">0</span> +] +recipe foo [ + <span class="Constant">2</span>:address:shared:number<span class="Special"> <- </span>next-ingredient + <span class="Comment"># return does NOT yet decrement refcount; memory must be explicitly managed</span> + <span class="Constant">2</span>:address:shared:number<span class="Special"> <- </span>copy <span class="Constant">0</span> +] +<span class="traceContains">+run: 1:address:shared:number <- new number:type</span> +<span class="traceContains">+mem: incrementing refcount of 1000: 0 -> 1</span> +<span class="traceContains">+run: 2:address:shared:number <- next-ingredient</span> +<span class="traceContains">+mem: incrementing refcount of 1000: 1 -> 2</span> +<span class="traceContains">+run: 2:address:shared:number <- copy 0</span> +<span class="traceContains">+mem: decrementing refcount of 1000: 2 -> 1</span> +<span class="traceContains">+run: 1:address:shared:number <- copy 0</span> +<span class="traceContains">+mem: decrementing refcount of 1000: 1 -> 0</span> +<span class="traceContains">+mem: automatically abandoning 1000</span> + +<span class="Delimiter">:(scenario refcounts_4)</span> +recipe main [ + <span class="Constant">1</span>:address:shared:number<span class="Special"> <- </span>new number:type + <span class="Comment"># idempotent copies leave refcount unchanged</span> + <span class="Constant">1</span>:address:shared:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:address:shared:number +] +<span class="traceContains">+run: 1:address:shared:number <- new number:type</span> +<span class="traceContains">+mem: incrementing refcount of 1000: 0 -> 1</span> +<span class="traceContains">+run: 1:address:shared:number <- copy 1:address:shared:number</span> +<span class="traceContains">+mem: decrementing refcount of 1000: 1 -> 0</span> +<span class="traceContains">+mem: incrementing refcount of 1000: 0 -> 1</span> + +<span class="Delimiter">:(scenario refcounts_5)</span> +recipe main [ + <span class="Constant">1</span>:address:shared:number<span class="Special"> <- </span>new number:type + <span class="Comment"># passing in addresses to recipes increments refcount</span> + foo <span class="Constant">1</span>:address:shared:number + <span class="Comment"># return does NOT yet decrement refcount; memory must be explicitly managed</span> + <span class="Constant">1</span>:address:shared:number<span class="Special"> <- </span>new number:type +] +recipe foo [ + <span class="Constant">2</span>:address:shared:number<span class="Special"> <- </span>next-ingredient +] +<span class="traceContains">+run: 1:address:shared:number <- new number:type</span> +<span class="traceContains">+mem: incrementing refcount of 1000: 0 -> 1</span> +<span class="traceContains">+run: 2:address:shared:number <- next-ingredient</span> +<span class="traceContains">+mem: incrementing refcount of 1000: 1 -> 2</span> +<span class="traceContains">+run: 1:address:shared:number <- new number:type</span> +<span class="traceContains">+mem: decrementing refcount of 1000: 2 -> 1</span> + <span class="SalientComment">//:: Extend 'new' to handle a unicode string literal argument.</span> <span class="Delimiter">:(scenario new_string)</span> diff --git a/html/042name.cc.html b/html/042name.cc.html index e6f0b296..b39670fb 100644 --- a/html/042name.cc.html +++ b/html/042name.cc.html @@ -80,7 +80,7 @@ void transform_names<span class="Delimiter">(</span>const recipe_ordinal r<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>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>is_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>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>is_integer<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">).</span>name<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> @@ -90,7 +90,7 @@ void transform_names<span class="Delimiter">(</span>const recipe_ordinal r<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>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>is_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>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>is_integer<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> <span class="Identifier">continue</span><span class="Delimiter">;</span> @@ -106,15 +106,15 @@ void transform_names<span class="Delimiter">(</span>const recipe_ordinal r<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> +bool is_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> if <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Comment">// End transform_names Exceptions</span> + <span class="Comment">// End Null-type is_disqualified Exceptions</span> raise_error << maybe<span class="Delimiter">(</span>recipe_name<span class="Delimiter">)</span> << <span class="Constant">"missing type for "</span> << x<span class="Delimiter">.</span>original_string << <span class="Constant">" in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> if <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Comment">// End Disqualified Reagents</span> + <span class="Comment">// End is_disqualified Cases</span> if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>initialized<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> diff --git a/html/043space.cc.html b/html/043space.cc.html index 7f14f589..36e41bc1 100644 --- a/html/043space.cc.html +++ b/html/043space.cc.html @@ -22,6 +22,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } .Special { color: #ff6060; } .Identifier { color: #804000; } .Constant { color: #00a0a0; } +.CommentedCode { color: #6c6c6c; } --> </style> @@ -72,7 +73,7 @@ recipe main [ <span class="traceContains">+name: assign x 1</span> <span class="traceAbsent">-name: assign default-space 1</span> -<span class="Delimiter">:(before "End Disqualified Reagents")</span> +<span class="Delimiter">:(before "End is_disqualified Cases")</span> if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"default-space"</span><span class="Delimiter">)</span> x<span class="Delimiter">.</span>initialized = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End is_special_name Cases")</span> @@ -201,7 +202,7 @@ recipe main [ <span class="Comment"># allocate space for x and y, as well as the chaining slot at 0</span> <span class="traceContains">+mem: array size is 3</span> -<span class="Delimiter">:(before "End Disqualified Reagents")</span> +<span class="Delimiter">:(before "End is_disqualified Cases")</span> if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"number-of-locals"</span><span class="Delimiter">)</span> x<span class="Delimiter">.</span>initialized = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End is_special_name Cases")</span> @@ -278,6 +279,50 @@ void rewrite_default_space_instruction<span class="Delimiter">(</span>instructio raise_error << <span class="Constant">"new-default-space can't take any results</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> curr<span class="Delimiter">.</span>products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span><span class="Constant">"default-space:address:shared:array:location"</span><span class="Delimiter">));</span> <span class="Delimiter">}</span> + +<span class="SalientComment">//:: all recipes must set default-space one way or another</span> + +<span class="Delimiter">:(before "End Globals")</span> +bool Warn_on_missing_default_space = <span class="Constant">false</span><span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Checks")</span> +Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_default_space<span class="Delimiter">);</span> <span class="Comment">// idempotent</span> +<span class="Delimiter">:(code)</span> +void check_default_space<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!Warn_on_missing_default_space<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// skip previous core tests; this is only for mu code</span> + const recipe& caller = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span> + <span class="Comment">// skip scenarios (later layer)</span> + <span class="Comment">// user code should never create recipes with underscores in their names</span> + if <span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"scenario_"</span><span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// skip mu scenarios which will use raw memory locations</span> + if <span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"run_"</span><span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// skip calls to 'run', which should be in scenarios and will also use raw memory locations</span> + <span class="Comment">// assume recipes with only numeric addresses know what they're doing (usually tests)</span> + if <span class="Delimiter">(</span>!contains_non_special_name<span class="Delimiter">(</span>r<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">"--- check that recipe "</span> << caller<span class="Delimiter">.</span>name << <span class="Constant">" sets default-space"</span> << end<span class="Delimiter">();</span> + if <span class="Delimiter">(</span>caller<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>caller<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> + || caller<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name != <span class="Constant">"default-space"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">" does not seem to start with default-space or local-scope</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> +<span class="CommentedCode">//? cerr << maybe(caller.name) << " does not seem to start with default-space or local-scope\n" << '\n';</span> + <span class="Delimiter">}</span> +<span class="Delimiter">}</span> +<span class="Delimiter">:(after "Load .mu Core")</span> +Warn_on_missing_default_space = <span class="Constant">true</span><span class="Delimiter">;</span> +<span class="Delimiter">:(after "Test Runs")</span> +Warn_on_missing_default_space = <span class="Constant">false</span><span class="Delimiter">;</span> +<span class="Delimiter">:(after "Running Main")</span> +Warn_on_missing_default_space = <span class="Constant">true</span><span class="Delimiter">;</span> + +<span class="Delimiter">:(code)</span> +bool contains_non_special_name<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + for <span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> long long int>::iterator p = Name[r]<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Name[r]<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>p<span class="Delimiter">-></span>first<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> + if <span class="Delimiter">(</span>p<span class="Delimiter">-></span>first<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"stash_"</span><span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Comment">// generated by rewrite_stashes_to_text</span> + if <span class="Delimiter">(</span>!is_special_name<span class="Delimiter">(</span>p<span class="Delimiter">-></span>first<span class="Delimiter">))</span> <span class="Delimiter">{</span> +<span class="CommentedCode">//? cerr << " " << Recipe[r].name << ": " << p->first << '\n';</span> + <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</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> </pre> </body> </html> diff --git a/html/046global.cc.html b/html/046global.cc.html index d5a1331c..bb3869e7 100644 --- a/html/046global.cc.html +++ b/html/046global.cc.html @@ -56,7 +56,7 @@ recipe main [ <span class="traceContains">+mem: storing 24 in location 23</span> <span class="Comment">//: to support it, create another special variable called global space</span> -<span class="Delimiter">:(before "End Disqualified Reagents")</span> +<span class="Delimiter">:(before "End is_disqualified Cases")</span> if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"global-space"</span><span class="Delimiter">)</span> x<span class="Delimiter">.</span>initialized = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End is_special_name Cases")</span> diff --git a/html/047check_type_by_name.cc.html b/html/047check_type_by_name.cc.html index 0bc520b9..62456bf1 100644 --- a/html/047check_type_by_name.cc.html +++ b/html/047check_type_by_name.cc.html @@ -85,10 +85,10 @@ void check_type<span class="Delimiter">(</span>map<string<span class="Delimit 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">// might get filled in by other logic later</span> if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>type<span class="Delimiter">,</span> x<span class="Delimiter">.</span>name<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> << x<span class="Delimiter">.</span>name << <span class="Constant">" => "</span> << debug_string<span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << end<span class="Delimiter">();</span> - type[x<span class="Delimiter">.</span>name] = x<span class="Delimiter">.</span>type<span class="Delimiter">;</span> + put<span class="Delimiter">(</span>type<span class="Delimiter">,</span> x<span class="Delimiter">.</span>name<span class="Delimiter">,</span> x<span class="Delimiter">.</span>type<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> - 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> + put<span class="Delimiter">(</span>type_name<span class="Delimiter">,</span> x<span class="Delimiter">.</span>name<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>!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> diff --git a/html/050scenario.cc.html b/html/050scenario.cc.html index a44b76d0..f43664f9 100644 --- a/html/050scenario.cc.html +++ b/html/050scenario.cc.html @@ -147,6 +147,7 @@ long long int Num_core_mu_tests = <span class="Constant">0</span><span class="De <span class="Delimiter">:(after "Check For .mu Files")</span> Num_core_mu_tests = SIZE<span class="Delimiter">(</span>Scenarios<span class="Delimiter">);</span> <span class="Delimiter">:(before "End Tests")</span> +Warn_on_missing_default_space = <span class="Constant">true</span><span class="Delimiter">;</span> time_t mu_time<span class="Delimiter">;</span> time<span class="Delimiter">(</span>&mu_time<span class="Delimiter">);</span> cerr << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">Mu tests: "</span> << ctime<span class="Delimiter">(</span>&mu_time<span class="Delimiter">);</span> for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Scenarios<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -181,7 +182,7 @@ void run_mu_scenario<span class="Delimiter">(</span>const scenario& s<span c Trace_stream = new trace_stream<span class="Delimiter">;</span> setup<span class="Delimiter">();</span> <span class="Delimiter">}</span> - vector<recipe_ordinal> tmp = load<span class="Delimiter">(</span><span class="Constant">"recipe scenario-"</span>+s<span class="Delimiter">.</span>name+<span class="Constant">" [ "</span>+s<span class="Delimiter">.</span>to_run+<span class="Constant">" ]"</span><span class="Delimiter">);</span> + vector<recipe_ordinal> tmp = load<span class="Delimiter">(</span><span class="Constant">"recipe scenario_"</span>+s<span class="Delimiter">.</span>name+<span class="Constant">" [ "</span>+s<span class="Delimiter">.</span>to_run+<span class="Constant">" ]"</span><span class="Delimiter">);</span> bind_special_scenario_names<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> transform_all<span class="Delimiter">();</span> run<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>front<span class="Delimiter">());</span> @@ -238,8 +239,10 @@ case RUN: <span class="Delimiter">{</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> case RUN: <span class="Delimiter">{</span> + assert<span class="Delimiter">(</span>Name[Next_recipe_ordinal]<span class="Delimiter">.</span>empty<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> + 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 << tmp.str() << '\n';</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> diff --git a/html/052tangle.cc.html b/html/052tangle.cc.html index 42f5b7ca..00bbfb45 100644 --- a/html/052tangle.cc.html +++ b/html/052tangle.cc.html @@ -38,7 +38,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment">//: 'after' fragments will simply be inserted at all applicable waypoints.</span> <span class="Comment">//: Waypoints are always surrounded by '<>', e.g. <handle-request>.</span> <span class="Comment">//:</span> -<span class="Comment">//: TODO: switch recipe.steps to a more efficient data structure.</span> +<span class="Comment">//: todo: switch recipe.steps to a more efficient data structure.</span> <span class="Delimiter">:(scenario tangle_before)</span> recipe main [ diff --git a/html/056recipe_header.cc.html b/html/056recipe_header.cc.html index 48da455e..c4847398 100644 --- a/html/056recipe_header.cc.html +++ b/html/056recipe_header.cc.html @@ -253,6 +253,7 @@ void check_calls_against_header<span class="Delimiter">(</span>const recipe_ordi const recipe& callee = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>operation<span class="Delimiter">);</span> if <span class="Delimiter">(</span>!callee<span class="Delimiter">.</span>has_header<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> for <span class="Delimiter">(</span>long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < min<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">),</span> SIZE<span class="Delimiter">(</span>callee<span class="Delimiter">.</span>ingredients<span class="Delimiter">));</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Comment">// ingredients coerced from call to callee</span> if <span class="Delimiter">(</span>!types_coercible<span class="Delimiter">(</span>callee<span class="Delimiter">.</span>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> raise_error << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"ingredient "</span> << i << <span class="Constant">" has 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> if <span class="Delimiter">(</span>is_unique_address<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> @@ -260,7 +261,8 @@ void check_calls_against_header<span class="Delimiter">(</span>const recipe_ordi <span class="Delimiter">}</span> for <span class="Delimiter">(</span>long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < min<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">),</span> SIZE<span class="Delimiter">(</span>callee<span class="Delimiter">.</span>products<span class="Delimiter">));</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> if <span class="Delimiter">(</span>is_dummy<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="Identifier">continue</span><span class="Delimiter">;</span> - if <span class="Delimiter">(</span>!types_coercible<span class="Delimiter">(</span>callee<span class="Delimiter">.</span>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="Comment">// products coerced from callee to call</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> callee<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> raise_error << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"product "</span> << i << <span class="Constant">" has 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> if <span class="Delimiter">(</span>is_unique_address<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> raise << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"try to avoid getting non-shared addresses out of calls, like product "</span> << i << <span class="Constant">" 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> @@ -327,7 +329,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> - 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> + for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < min<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> ++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> diff --git a/html/057static_dispatch.cc.html b/html/057static_dispatch.cc.html index 319c72e9..adcf7995 100644 --- a/html/057static_dispatch.cc.html +++ b/html/057static_dispatch.cc.html @@ -175,6 +175,15 @@ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</ <span class="Delimiter">:(after "Transform.push_back(transform_names)")</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="Comment">//: In a later layer we'll introduce recursion in resolve_ambiguous_calls, by</span> +<span class="Comment">//: having it generate code for shape-shifting recipes and then transform such</span> +<span class="Comment">//: code. This data structure will help error messages be more useful.</span> +<span class="Comment">//:</span> +<span class="Comment">//: We're punning the 'call' data structure just because it has slots for</span> +<span class="Comment">//: calling recipe and calling instruction.</span> +<span class="Delimiter">:(before "End Globals")</span> +list<call> resolve_stack<span class="Delimiter">;</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> @@ -184,7 +193,12 @@ void resolve_ambiguous_calls<span class="Delimiter">(</span>recipe_ordinal r<spa 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>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> + resolve_stack<span class="Delimiter">.</span>push_front<span class="Delimiter">(</span>call<span class="Delimiter">(</span>r<span class="Delimiter">));</span> + resolve_stack<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_step_index = index<span class="Delimiter">;</span> replace_best_variant<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">);</span> + assert<span class="Delimiter">(</span>resolve_stack<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_recipe == r<span class="Delimiter">);</span> + assert<span class="Delimiter">(</span>resolve_stack<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_step_index == index<span class="Delimiter">);</span> + resolve_stack<span class="Delimiter">.</span>pop_front<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> @@ -195,6 +209,7 @@ void replace_best_variant<span class="Delimiter">(</span>instruction& inst<s 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> + 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> <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">"score for variant "</span> << i << <span class="Constant">": "</span> << current_score << end<span class="Delimiter">();</span> @@ -206,7 +221,38 @@ void replace_best_variant<span class="Delimiter">(</span>instruction& inst<s <span class="Comment">// End Instruction Dispatch(inst, best_score)</span> if <span class="Delimiter">(</span>best_score == -<span class="Constant">1</span> && get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">)</span> >= MAX_PRIMITIVE_RECIPES<span class="Delimiter">)</span> <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">"failed to find a matching call for '"</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>list<call>::iterator p = <span class="Comment">/*</span><span class="Comment">skip</span><span class="Comment">*/</span>++resolve_stack<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != resolve_stack<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span> + const recipe& specializer_recipe = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> p<span class="Delimiter">-></span>running_recipe<span class="Delimiter">);</span> + const instruction& specializer_inst = specializer_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>p<span class="Delimiter">-></span>running_step_index<span class="Delimiter">);</span> + if <span class="Delimiter">(</span>specializer_recipe<span class="Delimiter">.</span>name != <span class="Constant">"interactive"</span><span class="Delimiter">)</span> + raise_error << <span class="Constant">" (from '"</span> << specializer_inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"' in "</span> << specializer_recipe<span class="Delimiter">.</span>name << <span class="Constant">")</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + else + raise_error << <span class="Constant">" (from '"</span> << specializer_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="Comment">// One special-case to help with the rewrite_stash transform. (cross-layer)</span> + if <span class="Delimiter">(</span>specializer_inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"stash_"</span><span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + instruction stash_inst<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>next_stash<span class="Delimiter">(</span>*p<span class="Delimiter">,</span> &stash_inst<span class="Delimiter">))</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>specializer_recipe<span class="Delimiter">.</span>name != <span class="Constant">"interactive"</span><span class="Delimiter">)</span> + raise_error << <span class="Constant">" (part of '"</span> << stash_inst<span class="Delimiter">.</span>original_string << <span class="Constant">"' in "</span> << specializer_recipe<span class="Delimiter">.</span>name << <span class="Constant">")</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + else + raise_error << <span class="Constant">" (part of '"</span> << stash_inst<span class="Delimiter">.</span>original_string << <span class="Constant">"')</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Delimiter">}</span> + <span class="Delimiter">}</span> + <span class="Delimiter">}</span> + <span class="Delimiter">}</span> +<span class="Delimiter">}</span> + +bool next_stash<span class="Delimiter">(</span>const call& c<span class="Delimiter">,</span> instruction* stash_inst<span class="Delimiter">)</span> <span class="Delimiter">{</span> + const recipe& specializer_recipe = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> c<span class="Delimiter">.</span>running_recipe<span class="Delimiter">);</span> + long long int index = c<span class="Delimiter">.</span>running_step_index<span class="Delimiter">;</span> + for <span class="Delimiter">(</span>++index<span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>specializer_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> + const instruction& inst = specializer_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>name == <span class="Constant">"stash"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + *stash_inst = inst<span class="Delimiter">;</span> + <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> <span class="Delimiter">}</span> + <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <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> diff --git a/html/059shape_shifting_recipe.cc.html b/html/059shape_shifting_recipe.cc.html index dcbcd680..857bfca0 100644 --- a/html/059shape_shifting_recipe.cc.html +++ b/html/059shape_shifting_recipe.cc.html @@ -72,8 +72,8 @@ 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 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="Delimiter">:(before "End Matching Types For Literal(to)")</span> +if <span class="Delimiter">(</span>contains_type_ingredient_name<span class="Delimiter">(</span>to<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.</span> @@ -112,14 +112,16 @@ if <span class="Delimiter">(</span>best_score == -<span class="Constant">1</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> if <span class="Delimiter">(</span>new_recipe_ordinal == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">goto</span> done_constructing_variant<span class="Delimiter">;</span> variants<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_recipe_ordinal<span class="Delimiter">);</span> + recipe& variant = get<span class="Delimiter">(</span>Recipe<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> - 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> + if <span class="Delimiter">(</span>!variant<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>empty<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">"transforming new specialization: "</span> << variant<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span> + for <span class="Delimiter">(</span>long long int t = <span class="Constant">0</span><span class="Delimiter">;</span> t < SIZE<span class="Delimiter">(</span>Transform<span class="Delimiter">);</span> ++t<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <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> <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> - 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> + variant<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> + inst<span class="Delimiter">.</span>name = variant<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="Delimiter">}</span> done_constructing_variant:<span class="Delimiter">;</span> @@ -227,10 +229,10 @@ bool any_type_ingredient_in_header<span class="Delimiter">(</span>recipe_ordinal <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> - 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> +bool deeply_equal_concrete_types<span class="Delimiter">(</span>reagent to<span class="Delimiter">,</span> reagent from<span class="Delimiter">)</span> <span class="Delimiter">{</span> + canonize_type<span class="Delimiter">(</span>to<span class="Delimiter">);</span> + canonize_type<span class="Delimiter">(</span>from<span class="Delimiter">);</span> + <span class="Identifier">return</span> deeply_equal_concrete_types<span class="Delimiter">(</span>to<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> from<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> from<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> @@ -257,24 +259,24 @@ long long int number_of_concrete_types<span class="Delimiter">(</span>const stri <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>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> +bool deeply_equal_concrete_types<span class="Delimiter">(</span>const string_tree* to<span class="Delimiter">,</span> const string_tree* from<span class="Delimiter">,</span> const reagent& rhs_reagent<span class="Delimiter">)</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!to<span class="Delimiter">)</span> <span class="Identifier">return</span> !from<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>!from<span class="Delimiter">)</span> <span class="Identifier">return</span> !to<span class="Delimiter">;</span> + if <span class="Delimiter">(</span>is_type_ingredient_name<span class="Delimiter">(</span>to<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>to<span class="Delimiter">-></span>value == <span class="Constant">"literal"</span> && from<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> + if <span class="Delimiter">(</span>to<span class="Delimiter">-></span>value == <span class="Constant">"literal"</span> + && Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>from<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> + if <span class="Delimiter">(</span>from<span class="Delimiter">-></span>value == <span class="Constant">"literal"</span> + && Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>to<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> + if <span class="Delimiter">(</span>from<span class="Delimiter">-></span>value == <span class="Constant">"literal"</span> && to<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> - <span class="Identifier">return</span> lhs<span class="Delimiter">-></span>value == rhs<span class="Delimiter">-></span>value - && deeply_equal_concrete_types<span class="Delimiter">(</span>lhs<span class="Delimiter">-></span>left<span class="Delimiter">,</span> rhs<span class="Delimiter">-></span>left<span class="Delimiter">,</span> rhs_reagent<span class="Delimiter">)</span> - && deeply_equal_concrete_types<span class="Delimiter">(</span>lhs<span class="Delimiter">-></span>right<span class="Delimiter">,</span> rhs<span class="Delimiter">-></span>right<span class="Delimiter">,</span> rhs_reagent<span class="Delimiter">);</span> +<span class="CommentedCode">//? cerr << to->value << " vs " << from->value << '\n';</span> + <span class="Identifier">return</span> to<span class="Delimiter">-></span>value == from<span class="Delimiter">-></span>value + && deeply_equal_concrete_types<span class="Delimiter">(</span>to<span class="Delimiter">-></span>left<span class="Delimiter">,</span> from<span class="Delimiter">-></span>left<span class="Delimiter">,</span> rhs_reagent<span class="Delimiter">)</span> + && deeply_equal_concrete_types<span class="Delimiter">(</span>to<span class="Delimiter">-></span>right<span class="Delimiter">,</span> from<span class="Delimiter">-></span>right<span class="Delimiter">,</span> rhs_reagent<span class="Delimiter">);</span> <span class="Delimiter">}</span> bool contains_type_ingredient_name<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -568,6 +570,15 @@ container foo:_t [ <span class="traceContains">+mem: storing 14 in location 20</span> <span class="traceContains">+mem: storing 15 in location 21</span> +<span class="Delimiter">:(scenario shape_shifting_recipe_empty)</span> +recipe main [ + foo <span class="Constant">1</span> +] +<span class="Comment"># shape-shifting recipe with no body</span> +recipe foo a:_t [ +] +<span class="Comment"># shouldn't crash</span> + <span class="Delimiter">:(scenario shape_shifting_recipe_handles_shape_shifting_new_ingredient)</span> recipe main [ <span class="Constant">1</span>:address:shared:foo:point<span class="Special"> <- </span>bar <span class="Constant">3</span> diff --git a/html/061recipe.cc.html b/html/061recipe.cc.html index 163347ff..1bfc9758 100644 --- a/html/061recipe.cc.html +++ b/html/061recipe.cc.html @@ -65,7 +65,7 @@ put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type_ordinal recipe = put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"recipe"</span><span class="Delimiter">,</span> Next_type_ordinal++<span class="Delimiter">);</span> get_or_insert<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> recipe<span class="Delimiter">).</span>name = <span class="Constant">"recipe"</span><span class="Delimiter">;</span> -<span class="Delimiter">:(before "End transform_names Exceptions")</span> +<span class="Delimiter">:(before "End Null-type is_disqualified Exceptions")</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>Recipe_ordinal<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><span class="Constant">"recipe-literal"</span><span class="Delimiter">);</span> x<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">"recipe-literal"</span><span class="Delimiter">));</span> @@ -211,14 +211,14 @@ recipe f x:boolean <span class="Delimiter">-></span> y:boolean [ ] <span class="traceContains">+error: main: can't copy f to {1: (recipe number -> number)}; types don't match</span> -<span class="Delimiter">:(before "End Matching Types For Literal(lhs)")</span> -if <span class="Delimiter">(</span>is_mu_recipe<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Delimiter">{</span> - if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> rhs<span class="Delimiter">.</span>value<span class="Delimiter">))</span> <span class="Delimiter">{</span> - raise_error << <span class="Constant">"trying to store recipe "</span> << rhs<span class="Delimiter">.</span>name << <span class="Constant">" into "</span> << debug_string<span class="Delimiter">(</span>lhs<span class="Delimiter">)</span> << <span class="Constant">" but there's no such recipe</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> +<span class="Delimiter">:(before "End Matching Types For Literal(to)")</span> +if <span class="Delimiter">(</span>is_mu_recipe<span class="Delimiter">(</span>to<span class="Delimiter">))</span> <span class="Delimiter">{</span> + if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> from<span class="Delimiter">.</span>value<span class="Delimiter">))</span> <span class="Delimiter">{</span> + raise_error << <span class="Constant">"trying to store recipe "</span> << from<span class="Delimiter">.</span>name << <span class="Constant">" into "</span> << debug_string<span class="Delimiter">(</span>to<span class="Delimiter">)</span> << <span class="Constant">" but there's no such 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> - const recipe& rrhs = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> rhs<span class="Delimiter">.</span>value<span class="Delimiter">);</span> - const recipe& rlhs = from_reagent<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span> + const recipe& rrhs = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> from<span class="Delimiter">.</span>value<span class="Delimiter">);</span> + const recipe& rlhs = from_reagent<span class="Delimiter">(</span>to<span class="Delimiter">);</span> for <span class="Delimiter">(</span>long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < min<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>rlhs<span class="Delimiter">.</span>ingredients<span class="Delimiter">),</span> SIZE<span class="Delimiter">(</span>rrhs<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>rlhs<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> rrhs<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">false</span><span class="Delimiter">;</span> diff --git a/html/070text.mu.html b/html/070text.mu.html index fc695ef5..a517c13f 100644 --- a/html/070text.mu.html +++ b/html/070text.mu.html @@ -347,6 +347,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">}</span> ] +<span class="muRecipe">recipe</span> to-text x:boolean<span class="muRecipe"> -> </span>result:address:shared:array:character [ + <span class="Constant">local-scope</span> + <span class="Constant">load-ingredients</span> + n:number<span class="Special"> <- </span>copy x:boolean + result<span class="Special"> <- </span>to-text n +] + + <span class="muRecipe">recipe</span> buffer-to-array in:address:shared:buffer<span class="muRecipe"> -> </span>result:address:shared:array:character [ <span class="Constant">local-scope</span> <span class="Constant">load-ingredients</span> diff --git a/html/edit/003-shortcuts.mu.html b/html/edit/003-shortcuts.mu.html index 243635b0..d47c0614 100644 --- a/html/edit/003-shortcuts.mu.html +++ b/html/edit/003-shortcuts.mu.html @@ -201,7 +201,18 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } trace <span class="Constant">10</span>, <span class="Constant">[app]</span>, <span class="Constant">[switching to previous line]</span> d:address:shared:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">data:offset</span> end-of-line:number<span class="Special"> <- </span>previous-line-length before-cursor, d - *cursor-column<span class="Special"> <- </span>add left, end-of-line + right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span> + width:number<span class="Special"> <- </span>subtract right, left + wrap?:boolean<span class="Special"> <- </span>greater-than end-of-line, width + <span class="Delimiter">{</span> + <span class="muControl">break-unless</span> wrap? + _, column-offset:number<span class="Special"> <- </span>divide-with-remainder end-of-line, width + *cursor-column<span class="Special"> <- </span>add left, column-offset + <span class="Delimiter">}</span> + <span class="Delimiter">{</span> + <span class="muControl">break-if</span> wrap? + *cursor-column<span class="Special"> <- </span>add left, end-of-line + <span class="Delimiter">}</span> <span class="muControl">reply</span> <span class="Delimiter">}</span> <span class="Comment"># case 2: if previous-character was not newline, we're just at a wrapped line</span> @@ -836,7 +847,7 @@ d] <span class="muScenario">scenario</span> editor-moves-across-screen-lines-across-wrap-with-left-arrow [ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> - <span class="Comment"># initialize editor with text containing an empty line</span> + <span class="Comment"># initialize editor with a wrapping line</span> <span class="Constant">1</span>:address:shared:array:character<span class="Special"> <- </span>new <span class="Constant">[abcdef]</span> <span class="Constant">2</span>:address:shared:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:shared:array:character, screen:address:shared:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span> editor-render screen, <span class="Constant">2</span>:address:shared:editor-data @@ -860,7 +871,71 @@ d] ] memory-should-contain [ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Comment"># previous row</span> - <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">3</span> <span class="Comment"># end of wrapped line</span> + <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">3</span> <span class="Comment"># right margin except wrap icon</span> + ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> +] + +<span class="muScenario">scenario</span> editor-moves-across-screen-lines-to-wrapping-line-with-left-arrow [ + assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> + <span class="Comment"># initialize editor with a wrapping line followed by a second line</span> + <span class="Constant">1</span>:address:shared:array:character<span class="Special"> <- </span>new <span class="Constant">[abcdef</span> +<span class="Constant">g]</span> + <span class="Constant">2</span>:address:shared:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:shared:array:character, screen:address:shared:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span> + editor-render screen, <span class="Constant">2</span>:address:shared:editor-data +<span class="Constant"> $clear-trace</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .abcd↩ .</span> + <span class="Constant"> .ef .</span> + <span class="Constant"> .g .</span> + <span class="Constant"> .┈┈┈┈┈ .</span> + ] + <span class="Comment"># position cursor right after empty line</span> + assume-console [ + left-click <span class="Constant">3</span>, <span class="Constant">0</span> + press left-arrow + ] + run [ + editor-event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">2</span>:address:shared:editor-data + <span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:shared:editor-data, <span class="Constant">cursor-row:offset</span> + <span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:shared:editor-data, <span class="Constant">cursor-column:offset</span> + ] + memory-should-contain [ + <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">2</span> <span class="Comment"># previous row</span> + <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">2</span> <span class="Comment"># end of wrapped line</span> + ] + check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> +] + +<span class="muScenario">scenario</span> editor-moves-across-screen-lines-to-non-wrapping-line-with-left-arrow [ + assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span> + <span class="Comment"># initialize editor with a line on the verge of wrapping, followed by a second line</span> + <span class="Constant">1</span>:address:shared:array:character<span class="Special"> <- </span>new <span class="Constant">[abcd</span> +<span class="Constant">e]</span> + <span class="Constant">2</span>:address:shared:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:shared:array:character, screen:address:shared:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span> + editor-render screen, <span class="Constant">2</span>:address:shared:editor-data +<span class="Constant"> $clear-trace</span> + screen-should-contain [ + <span class="Constant"> . .</span> + <span class="Constant"> .abcd .</span> + <span class="Constant"> .e .</span> + <span class="Constant"> .┈┈┈┈┈ .</span> + <span class="Constant"> . .</span> + ] + <span class="Comment"># position cursor right after empty line</span> + assume-console [ + left-click <span class="Constant">2</span>, <span class="Constant">0</span> + press left-arrow + ] + run [ + editor-event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">2</span>:address:shared:editor-data + <span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:shared:editor-data, <span class="Constant">cursor-row:offset</span> + <span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:shared:editor-data, <span class="Constant">cursor-column:offset</span> + ] + memory-should-contain [ + <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span> <span class="Comment"># previous row</span> + <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">4</span> <span class="Comment"># end of wrapped line</span> ] check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span> ] diff --git a/html/edit/005-sandbox.mu.html b/html/edit/005-sandbox.mu.html index c079109e..d7a18512 100644 --- a/html/edit/005-sandbox.mu.html +++ b/html/edit/005-sandbox.mu.html @@ -67,12 +67,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muData">container</span> sandbox-data [ data:address:shared:array:character response:address:shared:array:character - expected-response:address:shared:array:character <span class="Comment"># coordinates to track clicks</span> <span class="Comment"># constraint: will be 0 for sandboxes at positions before env.render-from</span> starting-row-on-screen:number code-ending-row-on-screen:number <span class="Comment"># past end of code</span> - response-starting-row-on-screen:number screen:address:shared:screen <span class="Comment"># prints in the sandbox go here</span> next-sandbox:address:shared:sandbox-data ] @@ -271,12 +269,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } data:address:shared:array:character<span class="Special"> <- </span>get *curr, <span class="Constant">data:offset</span> filename:address:shared:array:character<span class="Special"> <- </span>to-text idx save filename, data - <span class="Delimiter">{</span> - expected-response:address:shared: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>append filename, suffix - save filename, expected-response - <span class="Delimiter">}</span> +<span class="Constant"> <end-save-sandbox></span> idx<span class="Special"> <- </span>add idx, <span class="Constant">1</span> curr<span class="Special"> <- </span>get *curr, <span class="Constant">next-sandbox:offset</span> <span class="muControl">loop</span> @@ -337,7 +330,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } code-ending-row:address:number<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">code-ending-row-on-screen:offset</span> *code-ending-row<span class="Special"> <- </span>copy row <span class="Comment"># render sandbox warnings, screen or response, in that order</span> - response-starting-row:address:number<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">response-starting-row-on-screen:offset</span> sandbox-response:address:shared:array:character<span class="Special"> <- </span>get *sandbox, <span class="Constant">response:offset</span> <span class="Constant"> <render-sandbox-results></span> <span class="Delimiter">{</span> @@ -348,7 +340,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">}</span> <span class="Delimiter">{</span> <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 screen, sandbox-response, left, right, <span class="Constant">245/grey</span>, row <span class="Delimiter">}</span> @@ -365,8 +356,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } *tmp<span class="Special"> <- </span>copy <span class="Constant">0</span> tmp:address:number<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">code-ending-row-on-screen:offset</span> *tmp<span class="Special"> <- </span>copy <span class="Constant">0</span> - tmp:address:number<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">response-starting-row-on-screen:offset</span> - *tmp<span class="Special"> <- </span>copy <span class="Constant">0</span> +<span class="Constant"> <end-render-sandbox-reset-hidden></span> <span class="Delimiter">}</span> <span class="Comment"># draw next sandbox</span> next-sandbox:address:shared:sandbox-data<span class="Special"> <- </span>get *sandbox, <span class="Constant">next-sandbox:offset</span> @@ -395,8 +385,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } 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:shared:array:character<span class="Special"> <- </span>get-address **curr, <span class="Constant">expected-response:offset</span> - *expected-response<span class="Special"> <- </span>copy contents +<span class="Constant"> <end-restore-sandbox></span> <span class="Delimiter">}</span> <span class="Constant"> +continue</span> idx<span class="Special"> <- </span>add idx, <span class="Constant">1</span> @@ -482,6 +471,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Comment"># define a recipe (no indent for the 'add' line below so column numbers are more obvious)</span> <span class="Constant">1</span>:address:shared:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span> <span class="Constant">recipe foo [</span> +<span class="Constant">local-scope</span> <span class="Constant">z:number <- add 2, 2</span> <span class="Constant">reply z</span> <span class="Constant">]</span>] @@ -497,15 +487,16 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant"> . run (F4) .</span> <span class="Constant"> . ┊ .</span> <span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> - <span class="Constant"> .z:number <- add 2, 2 ┊0 x.</span> - <span class="Constant"> .reply z ┊foo .</span> - <span class="Constant"> .] ┊4 .</span> -<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> .local-scope ┊0 x.</span> + <span class="Constant"> .z:number <- add 2, 2 ┊foo .</span> + <span class="Constant"> .reply z ┊4 .</span> + <span class="Constant"> .] ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊ .</span> <span class="Constant"> . ┊ .</span> ] <span class="Comment"># make a change (incrementing one of the args to 'add'), then rerun</span> assume-console [ - left-click <span class="Constant">3</span>, <span class="Constant">28</span> <span class="Comment"># one past the value of the second arg</span> + left-click <span class="Constant">4</span>, <span class="Constant">28</span> <span class="Comment"># one past the value of the second arg</span> press backspace type <span class="Constant">[3]</span> press F4 @@ -518,10 +509,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant"> . run (F4) .</span> <span class="Constant"> . ┊ .</span> <span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> - <span class="Constant"> .z:number <- add 2, 3 ┊0 x.</span> - <span class="Constant"> .reply z ┊foo .</span> - <span class="Constant"> .] ┊5 .</span> -<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> .local-scope ┊0 x.</span> + <span class="Constant"> .z:number <- add 2, 3 ┊foo .</span> + <span class="Constant"> .reply z ┊5 .</span> + <span class="Constant"> .] ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊ .</span> <span class="Constant"> . ┊ .</span> ] ] @@ -757,9 +749,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } assume-console [ press F4 ] - run [ - event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data - ] + event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data <span class="Comment"># hit 'down' in recipe editor</span> assume-console [ press down-arrow @@ -769,8 +759,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant">4</span>:character/cursor<span class="Special"> <- </span>copy <span class="Constant">9251/␣</span> print screen:address:shared:screen, <span class="Constant">4</span>:character/cursor ] - <span class="Comment"># sandbox editor hidden; first sandbox displayed</span> - <span class="Comment"># cursor moves to first sandbox</span> + <span class="Comment"># cursor moves down on recipe side</span> screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> . ┊ .</span> @@ -799,11 +788,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } type <span class="Constant">[add 1, 1]</span> press F4 ] - run [ - event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data - <span class="Constant">4</span>:character/cursor<span class="Special"> <- </span>copy <span class="Constant">9251/␣</span> - print screen:address:shared:screen, <span class="Constant">4</span>:character/cursor - ] + event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data + <span class="Constant">4</span>:character/cursor<span class="Special"> <- </span>copy <span class="Constant">9251/␣</span> + print screen:address:shared:screen, <span class="Constant">4</span>:character/cursor screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> . ┊␣ .</span> @@ -953,9 +940,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } type <span class="Constant">[add 1, 1]</span> press F4 ] - run [ - event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data - ] + event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> . ┊ .</span> diff --git a/html/edit/006-sandbox-edit.mu.html b/html/edit/006-sandbox-edit.mu.html index a4830985..f5b59339 100644 --- a/html/edit/006-sandbox-edit.mu.html +++ b/html/edit/006-sandbox-edit.mu.html @@ -224,9 +224,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } press down-arrow press down-arrow ] - run [ - event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data - ] + event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> . ┊━━━━━━━━━━━━━━.</span> @@ -272,9 +270,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } type <span class="Constant">[add 1, 1]</span> press F4 ] - run [ - event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data - ] + event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> . ┊ .</span> diff --git a/html/edit/007-sandbox-delete.mu.html b/html/edit/007-sandbox-delete.mu.html index b88de17f..954dcd58 100644 --- a/html/edit/007-sandbox-delete.mu.html +++ b/html/edit/007-sandbox-delete.mu.html @@ -168,9 +168,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } press F4 press down-arrow ] - run [ - event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data - ] + event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> . ┊━━━━━━━━━━━━━━.</span> @@ -216,9 +214,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } press F4 press down-arrow ] - run [ - event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data - ] + event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> . ┊━━━━━━━━━━━━━━.</span> @@ -265,9 +261,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } press down-arrow press down-arrow ] - run [ - event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data - ] + event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> . ┊━━━━━━━━━━━━━━.</span> @@ -313,9 +307,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } type <span class="Constant">[add 1, 1]</span> press F4 ] - run [ - event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data - ] + event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data screen-should-contain [ <span class="Constant"> . .</span> <span class="Constant"> . ┊ .</span> diff --git a/html/edit/008-sandbox-test.mu.html b/html/edit/008-sandbox-test.mu.html index d5dbcfcb..28a098ae 100644 --- a/html/edit/008-sandbox-test.mu.html +++ b/html/edit/008-sandbox-test.mu.html @@ -16,6 +16,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } .muControl { color: #c0a020; } .muRecipe { color: #ff8700; } .muScenario { color: #00af00; } +.muData { color: #ffff00; } .Special { color: #ff6060; } .Comment { color: #9090ff; } .Constant { color: #00a0a0; } @@ -116,6 +117,27 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } ] ] +<span class="Comment"># this requires tracking a couple more things</span> +<span class="muData">container</span> sandbox-data [ + response-starting-row-on-screen:number + expected-response:address:shared:array:character +] + +<span class="Comment"># include expected response when saving or restoring a sandbox</span> +<span class="muRecipe">before</span> <span class="Constant"><end-save-sandbox></span> [ + <span class="Delimiter">{</span> + expected-response:address:shared: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>append filename, suffix + save filename, expected-response + <span class="Delimiter">}</span> +] + +<span class="muRecipe">before</span> <span class="Constant"><end-restore-sandbox></span> [ + expected-response:address:address:shared:array:character<span class="Special"> <- </span>get-address **curr, <span class="Constant">expected-response:offset</span> + *expected-response<span class="Special"> <- </span>copy contents +] + <span class="Comment"># clicks on sandbox responses save it as 'expected'</span> <span class="muRecipe">after</span> <span class="Constant"><global-touch></span> [ <span class="Comment"># check if it's inside the output of any sandbox</span> @@ -190,6 +212,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muRecipe">after</span> <span class="Constant"><render-sandbox-response></span> [ <span class="Delimiter">{</span> <span class="muControl">break-unless</span> sandbox-response + response-starting-row:address:number<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">response-starting-row-on-screen:offset</span> + *response-starting-row<span class="Special"> <- </span>copy row expected-response:address:shared: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>equal expected-response, sandbox-response @@ -204,6 +228,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="muControl">jump</span> <span class="Constant">+render-sandbox-end:label</span> <span class="Delimiter">}</span> ] + +<span class="muRecipe">before</span> <span class="Constant"><end-render-sandbox-reset-hidden></span> [ + tmp:address:number<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">response-starting-row-on-screen:offset</span> + *tmp<span class="Special"> <- </span>copy <span class="Constant">0</span> +] </pre> </body> </html> diff --git a/html/edit/010-warnings.mu.html b/html/edit/010-warnings.mu.html index a9b81c9e..eca63962 100644 --- a/html/edit/010-warnings.mu.html +++ b/html/edit/010-warnings.mu.html @@ -153,6 +153,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Delimiter">{</span> sandbox-warnings:address:shared: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:address:number<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">response-starting-row-on-screen:offset</span> *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 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> @@ -218,7 +219,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } run [ event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data ] - <span class="Comment"># status shows first sandbox with error</span> + <span class="Comment"># status line shows that error is in first sandbox</span> screen-should-contain [ <span class="Constant"> . errors found (0) run (F4) .</span> ] @@ -245,7 +246,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } run [ event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data ] - <span class="Comment"># status shows first sandbox with error</span> + <span class="Comment"># status line shows that error is in second sandbox</span> screen-should-contain [ <span class="Constant"> . errors found (1) run (F4) .</span> ] @@ -299,9 +300,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } assume-console [ press F4 ] - run [ - event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data - ] + event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data screen-should-contain [ <span class="Constant"> . errors found (0) run (F4) .</span> <span class="Constant"> .recipe foo x:_elem -> z:_elem [ ┊ .</span> @@ -453,6 +452,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span> <span class="Constant">1</span>:address:shared:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span> <span class="Constant">recipe foo [</span> +<span class="Constant"> local-scope</span> <span class="Constant"> x:address:shared:point <- new point:type</span> <span class="Constant"> get x:address:shared:point, 1:offset</span> <span class="Constant">]</span>] @@ -468,6 +468,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant"> . errors found run (F4) .</span> <span class="Constant"> . ┊foo .</span> <span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . local-scope ┊ .</span> <span class="Constant"> . x:address:shared:point <- new point:type ┊ .</span> <span class="Constant"> . get x:address:shared:point, 1:offset ┊ .</span> <span class="Constant"> .] ┊ .</span> @@ -483,6 +484,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span> <span class="Constant">1</span>:address:shared:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span> <span class="Constant">recipe foo [</span> +<span class="Constant"> local-scope</span> <span class="Constant"> x:number <- copy 0</span> <span class="Constant"> y:address:shared:point <- new point:type</span> <span class="Constant"> get *y:address:shared:point, x:number</span> @@ -499,6 +501,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant"> . errors found run (F4) .</span> <span class="Constant"> . ┊foo .</span> <span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . local-scope ┊ .</span> <span class="Constant"> . x:number <- copy 0 ┊ .</span> <span class="Constant"> . y:address:shared:point <- new point:type ┊ .</span> <span class="Constant"> . get *y:address:shared:point, x:number ┊ .</span> @@ -518,6 +521,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span> <span class="Constant">1</span>:address:shared:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span> <span class="Constant">recipe foo [</span> +<span class="Constant"> local-scope</span> <span class="Constant"> x:number <- copy y:number</span> <span class="Constant">]</span>] <span class="Constant">2</span>:address:shared:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span> @@ -525,13 +529,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } assume-console [ press F4 ] - run [ - event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data - ] + event-loop screen:address:shared:screen, console:address:shared:console, <span class="Constant">3</span>:address:shared:programming-environment-data screen-should-contain [ <span class="Constant"> . errors found run (F4) .</span> <span class="Constant"> . ┊foo .</span> <span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . local-scope ┊ .</span> <span class="Constant"> . x:number <- copy y:number ┊ .</span> <span class="Constant"> .] ┊ .</span> <span class="Constant"> .foo: use before set: y ┊ .</span> @@ -549,6 +552,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } <span class="Constant"> . errors found run (F4) .</span> <span class="Constant"> . ┊foo .</span> <span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span> + <span class="Constant"> . local-scope ┊ .</span> <span class="Constant"> . x:number <- copy y:number ┊ .</span> <span class="Constant"> .] ┊ .</span> <span class="Constant"> .foo: use before set: y ┊ .</span> |