<span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Globals")</span>
+<span class="Comment">// word boundaries</span>
+string Terminators<span class="Delimiter">(</span><span class="Constant">"(){}"</span><span class="Delimiter">);</span>
+string Ignore<span class="Delimiter">(</span><span class="Constant">","</span><span class="Delimiter">);</span> <span class="Comment">// meaningless except within [] strings</span>
+<span class="Delimiter">:(code)</span>
void slurp_word<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> ostream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span>
char c<span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">()</span> && in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">','</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">()</span> && Terminators<span class="Delimiter">.</span>find<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">())</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span>
in >> c<span class="Delimiter">;</span>
out << c<span class="Delimiter">;</span>
<span class="Identifier">return</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
while <span class="Delimiter">(</span>in >> c<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>isspace<span class="Delimiter">(</span>c<span class="Delimiter">)</span> || c == <span class="Constant">','</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>isspace<span class="Delimiter">(</span>c<span class="Delimiter">)</span> || Terminators<span class="Delimiter">.</span>find<span class="Delimiter">(</span>c<span class="Delimiter">)</span> != string::npos || Ignore<span class="Delimiter">.</span>find<span class="Delimiter">(</span>c<span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span>
in<span class="Delimiter">.</span>putback<span class="Delimiter">(</span>c<span class="Delimiter">);</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -219,8 +224,8 @@ void slurp_word<span class="Delimiter">(</span>istream& in<span class="Delim
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
-void skip_whitespace<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">()</span> && isspace<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">())</span> && in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+void skip_ignored_characters<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ while <span class="Delimiter">(</span>isspace<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">())</span> || Ignore<span class="Delimiter">.</span>find<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">())</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span>
in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
@@ -229,6 +234,7 @@ void skip_whitespace_and_comments<span class="Delimiter">(</span>istream& in
while <span class="Delimiter">(</span><span class="Constant">true</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
if <span class="Delimiter">(</span>isspace<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()))</span> in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
+ else if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">','</span><span class="Delimiter">)</span> in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
else if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'#'</span><span class="Delimiter">)</span> skip_comment<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
else <span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -241,12 +247,6 @@ void skip_comment<span class="Delimiter">(</span>istream& in<span class="Del
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
-void skip_comma<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">()</span> && in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">','</span><span class="Delimiter">)</span> in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
- skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
-<span class="Delimiter">}</span>
-
<span class="Comment">//: Warn if a recipe gets redefined, because large codebases can accidentally</span>
<span class="Comment">//: step on their own toes. But there'll be many occasions later where</span>
<span class="Comment">//: we'll want to disable the warnings.</span>
@@ -261,11 +261,8 @@ bool warn_on_redefine<span class="Delimiter">(</span>const string& recipe_na
<span class="Delimiter">}</span>
<span class="Comment">// for debugging</span>
-<span class="Delimiter">:(before "End Globals")</span>
-bool Show_rest_of_stream = <span class="Constant">false</span><span class="Delimiter">;</span>
<span class="Delimiter">:(code)</span>
void show_rest_of_stream<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!Show_rest_of_stream<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
cerr << <span class="Constant">'^'</span><span class="Delimiter">;</span>
char c<span class="Delimiter">;</span>
while <span class="Delimiter">(</span>in >> c<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -281,13 +278,15 @@ vector<recipe_ordinal> recently_added_recipes<span class="Delimiter">;</sp
long long int Reserved_for_tests = <span class="Constant">1000</span><span class="Delimiter">;</span>
<span class="Delimiter">:(before "End Setup")</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>recently_added_recipes<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>recently_added_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> >= Reserved_for_tests<span class="Delimiter">)</span> <span class="Comment">// don't renumber existing recipes, like 'interactive'</span>
- Recipe_ordinal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>Recipe[recently_added_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span>]<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>recently_added_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> >= Reserved_for_tests <span class="Comment">// don't renumber existing recipes, like 'interactive'</span>
+ && contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> recently_added_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Comment">// in case previous test had duplicate definitions</span>
+ Recipe_ordinal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> recently_added_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)).</span>name<span class="Delimiter">);</span>
Recipe<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>recently_added_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
<span class="Delimiter">}</span>
<span class="Comment">// Clear Other State For recently_added_recipes</span>
recently_added_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+<span class="Delimiter">:(code)</span>
<span class="Delimiter">:(scenario parse_comment_outside_recipe)</span>
<span class="Comment"># this comment will be dropped by the tangler, so we need a dummy recipe to stop that</span>
recipe f1 [ ]
@@ -296,8 +295,8 @@ recipe main [
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">23</span>
]
<span class="traceContains">+parse: instruction: copy</span>
-<span class="traceContains">+parse: ingredient: {name: "23", properties: ["23": "literal"]}</span>
-<span class="traceContains">+parse: product: {name: "1", properties: ["1": "number"]}</span>
+<span class="traceContains">+parse: ingredient: {"23": "literal"}</span>
+<span class="traceContains">+parse: product: {"1": "number"}</span>
<span class="Delimiter">:(scenario parse_comment_amongst_instruction)</span>
recipe main [
@@ -305,8 +304,8 @@ recipe main [
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">23</span>
]
<span class="traceContains">+parse: instruction: copy</span>
-<span class="traceContains">+parse: ingredient: {name: "23", properties: ["23": "literal"]}</span>
-<span class="traceContains">+parse: product: {name: "1", properties: ["1": "number"]}</span>
+<span class="traceContains">+parse: ingredient: {"23": "literal"}</span>
+<span class="traceContains">+parse: product: {"1": "number"}</span>
<span class="Delimiter">:(scenario parse_comment_amongst_instruction_2)</span>
recipe main [
@@ -315,8 +314,8 @@ recipe main [
<span class="Comment"># comment</span>
]
<span class="traceContains">+parse: instruction: copy</span>
-<span class="traceContains">+parse: ingredient: {name: "23", properties: ["23": "literal"]}</span>
-<span class="traceContains">+parse: product: {name: "1", properties: ["1": "number"]}</span>
+<span class="traceContains">+parse: ingredient: {"23": "literal"}</span>
+<span class="traceContains">+parse: product: {"1": "number"}</span>
<span class="Delimiter">:(scenario parse_comment_amongst_instruction_3)</span>
recipe main [
@@ -325,19 +324,19 @@ recipe main [
<span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">23</span>
]
<span class="traceContains">+parse: instruction: copy</span>
-<span class="traceContains">+parse: ingredient: {name: "23", properties: ["23": "literal"]}</span>
-<span class="traceContains">+parse: product: {name: "1", properties: ["1": "number"]}</span>
+<span class="traceContains">+parse: ingredient: {"23": "literal"}</span>
+<span class="traceContains">+parse: product: {"1": "number"}</span>
<span class="traceContains">+parse: instruction: copy</span>
-<span class="traceContains">+parse: ingredient: {name: "23", properties: ["23": "literal"]}</span>
-<span class="traceContains">+parse: product: {name: "2", properties: ["2": "number"]}</span>
+<span class="traceContains">+parse: ingredient: {"23": "literal"}</span>
+<span class="traceContains">+parse: product: {"2": "number"}</span>
<span class="Delimiter">:(scenario parse_comment_after_instruction)</span>
recipe main [
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">23</span> <span class="Comment"># comment</span>
]
<span class="traceContains">+parse: instruction: copy</span>
-<span class="traceContains">+parse: ingredient: {name: "23", properties: ["23": "literal"]}</span>
-<span class="traceContains">+parse: product: {name: "1", properties: ["1": "number"]}</span>
+<span class="traceContains">+parse: ingredient: {"23": "literal"}</span>
+<span class="traceContains">+parse: product: {"1": "number"}</span>
<span class="Delimiter">:(scenario parse_label)</span>
recipe main [
@@ -356,43 +355,43 @@ recipe main [
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">23</span>/foo:bar:baz
]
<span class="traceContains">+parse: instruction: copy</span>
-<span class="traceContains">+parse: ingredient: {name: "23", properties: ["23": "literal", "foo": "bar":"baz"]}</span>
-<span class="traceContains">+parse: product: {name: "1", properties: ["1": "number"]}</span>
+<span class="traceContains">+parse: ingredient: {"23": "literal", "foo": <"bar" : <"baz" : <>>>}</span>
+<span class="traceContains">+parse: product: {"1": "number"}</span>
<span class="Delimiter">:(scenario parse_multiple_products)</span>
recipe main [
<span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">23</span>
]
<span class="traceContains">+parse: instruction: copy</span>
-<span class="traceContains">+parse: ingredient: {name: "23", properties: ["23": "literal"]}</span>
-<span class="traceContains">+parse: product: {name: "1", properties: ["1": "number"]}</span>
-<span class="traceContains">+parse: product: {name: "2", properties: ["2": "number"]}</span>
+<span class="traceContains">+parse: ingredient: {"23": "literal"}</span>
+<span class="traceContains">+parse: product: {"1": "number"}</span>
+<span class="traceContains">+parse: product: {"2": "number"}</span>
<span class="Delimiter">:(scenario parse_multiple_ingredients)</span>
recipe main [
<span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">23</span><span class="Delimiter">,</span> <span class="Constant">4</span>:number
]
<span class="traceContains">+parse: instruction: copy</span>
-<span class="traceContains">+parse: ingredient: {name: "23", properties: ["23": "literal"]}</span>
-<span class="traceContains">+parse: ingredient: {name: "4", properties: ["4": "number"]}</span>
-<span class="traceContains">+parse: product: {name: "1", properties: ["1": "number"]}</span>
-<span class="traceContains">+parse: product: {name: "2", properties: ["2": "number"]}</span>
+<span class="traceContains">+parse: ingredient: {"23": "literal"}</span>
+<span class="traceContains">+parse: ingredient: {"4": "number"}</span>
+<span class="traceContains">+parse: product: {"1": "number"}</span>
+<span class="traceContains">+parse: product: {"2": "number"}</span>
<span class="Delimiter">:(scenario parse_multiple_types)</span>
recipe main [
<span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">23</span><span class="Delimiter">,</span> <span class="Constant">4</span>:number
]
<span class="traceContains">+parse: instruction: copy</span>
-<span class="traceContains">+parse: ingredient: {name: "23", properties: ["23": "literal"]}</span>
-<span class="traceContains">+parse: ingredient: {name: "4", properties: ["4": "number"]}</span>
-<span class="traceContains">+parse: product: {name: "1", properties: ["1": "number"]}</span>
-<span class="traceContains">+parse: product: {name: "2", properties: ["2": "address":"number"]}</span>
+<span class="traceContains">+parse: ingredient: {"23": "literal"}</span>
+<span class="traceContains">+parse: ingredient: {"4": "number"}</span>
+<span class="traceContains">+parse: product: {"1": "number"}</span>
+<span class="traceContains">+parse: product: {"2": <"address" : <"number" : <>>>}</span>
<span class="Delimiter">:(scenario parse_properties)</span>
recipe main [
<span class="Constant">1</span>:number:address/lookup<span class="Special"> <- </span>copy <span class="Constant">23</span>
]
-<span class="traceContains">+parse: product: {name: "1", properties: ["1": "number":"address", "lookup": ]}</span>
+<span class="traceContains">+parse: product: {"1": <"number" : <"address" : <>>>, "lookup": <>}</span>
<span class="Comment">//: this test we can't represent with a scenario</span>
<span class="Delimiter">:(code)</span>
diff --git a/html/012transform.cc.html b/html/012transform.cc.html
index 24c3b436..6770e137 100644
--- a/html/012transform.cc.html
+++ b/html/012transform.cc.html
@@ -13,10 +13,11 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.Identifier { color: #804000; }
.Constant { color: #00a0a0; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
-.Identifier { color: #804000; }
+.CommentedCode { color: #6c6c6c; }
-->
</style>
@@ -32,10 +33,21 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment">//:</span>
<span class="Comment">//: The hope is that this framework of transform tools will provide a</span>
<span class="Comment">//: deconstructed alternative to conventional compilers.</span>
+<span class="Comment">//:</span>
+<span class="Comment">//: We're going to have many transforms in mu, and getting their order right</span>
+<span class="Comment">//: (not the same as ordering of layers) is a well-known problem. Some tips:</span>
+<span class="Comment">//: a) Design each layer to rely on as few previous layers as possible.</span>
+<span class="Comment">//:</span>
+<span class="Comment">//: b) When positioning transforms, try to find the tightest constraint in</span>
+<span class="Comment">//: each transform relative to previous layers.</span>
+<span class="Comment">//:</span>
+<span class="Comment">//: c) Even so you'll periodically need to try adjusting each transform</span>
+<span class="Comment">//: relative to those in previous layers to find a better arrangement.</span>
<span class="Delimiter">:(before "End recipe Fields")</span>
long long int transformed_until<span class="Delimiter">;</span>
- recipe<span class="Delimiter">()</span> :transformed_until<span class="Delimiter">(</span>-<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{}</span>
+<span class="Delimiter">:(before "End recipe Constructor")</span>
+transformed_until = -<span class="Constant">1</span><span class="Delimiter">;</span>
<span class="Delimiter">:(before "End Types")</span>
typedef void <span class="Delimiter">(</span>*transform_fn<span class="Delimiter">)(</span>recipe_ordinal<span class="Delimiter">);</span>
@@ -43,22 +55,31 @@ typedef void <span class="Delimiter">(</span>*transform_fn<span class="Delimiter
<span class="Delimiter">:(before "End Globals")</span>
vector<transform_fn> Transform<span class="Delimiter">;</span>
+<span class="Delimiter">:(after "int main")</span>
+ <span class="Comment">// Begin Transforms</span>
+ <span class="Comment">// End Transforms</span>
+
<span class="Delimiter">:(code)</span>
void transform_all<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9990</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"=== transform_all()"</span> << end<span class="Delimiter">();</span>
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="CommentedCode">//? cerr << "transform " << t << '\n';</span>
for <span class="Delimiter">(</span>map<recipe_ordinal<span class="Delimiter">,</span> recipe>::iterator p = Recipe<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Recipe<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
recipe& r = p<span class="Delimiter">-></span>second<span class="Delimiter">;</span>
if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>transformed_until != t-<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ <span class="Comment">// End Transform Checks</span>
<span class="Delimiter">(</span>*Transform<span class="Delimiter">.</span>at<span class="Delimiter">(</span>t<span class="Delimiter">))(</span><span class="Comment">/*</span><span class="Comment">recipe_ordinal</span><span class="Comment">*/</span>p<span class="Delimiter">-></span>first<span class="Delimiter">);</span>
r<span class="Delimiter">.</span>transformed_until = t<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
parse_int_reagents<span class="Delimiter">();</span> <span class="Comment">// do this after all other transforms have run</span>
- <span class="Comment">// End Transform</span>
+ <span class="Comment">// End Transform All</span>
<span class="Delimiter">}</span>
void parse_int_reagents<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"--- parsing any uninitialized reagents as integers"</span> << end<span class="Delimiter">();</span>
+<span class="CommentedCode">//? cerr << "--- parsing any uninitialized reagents as integers" << '\n';</span>
for <span class="Delimiter">(</span>map<recipe_ordinal<span class="Delimiter">,</span> recipe>::iterator p = Recipe<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Recipe<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
recipe& r = p<span class="Delimiter">-></span>second<span class="Delimiter">;</span>
if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
diff --git a/html/013update_operation.cc.html b/html/013update_operation.cc.html
new file mode 100644
index 00000000..c2377b97
--- /dev/null
+++ b/html/013update_operation.cc.html
@@ -0,0 +1,67 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>Mu - 013update_operation.cc</title>
+<meta name="Generator" content="Vim/7.4">
+<meta name="plugin-version" content="vim7.4_v1">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
+<meta name="colorscheme" content="minimal">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
+body { font-family: monospace; color: #eeeeee; background-color: #080808; }
+* { font-size: 1.05em; }
+.Identifier { color: #804000; }
+.cSpecial { color: #008000; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
+.CommentedCode { color: #6c6c6c; }
+-->
+</style>
+
+<script type='text/javascript'>
+<!--
+
+-->
+</script>
+</head>
+<body>
+<pre id='vimCodeElement'>
+<span class="Comment">//: Once all code is loaded, save operation ids of instructions and check that</span>
+<span class="Comment">//: nothing's undefined.</span>
+
+<span class="Delimiter">:(before "End Transforms")</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>update_instruction_operations<span class="Delimiter">);</span> <span class="Comment">// idempotent</span>
+
+<span class="Delimiter">:(code)</span>
+void update_instruction_operations<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"--- compute instruction operations for recipe "</span> << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name << end<span class="Delimiter">();</span>
+<span class="CommentedCode">//? cerr << "--- compute instruction operations for recipe " << get(Recipe, r).name << '\n';</span>
+ for <span class="Delimiter">(</span>long long int index = <span class="Constant">0</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ instruction& inst = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>is_label<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"instruction "</span> << inst<span class="Delimiter">.</span>name << <span class="Constant">" has no recipe</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ inst<span class="Delimiter">.</span>operation = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+<span class="Comment">// hook to suppress inserting recipe name into errors and warnings (for later layers)</span>
+string maybe<span class="Delimiter">(</span>string s<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ <span class="Identifier">return</span> s + <span class="Constant">": "</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Comment">// temporarily suppress run</span>
+void transform<span class="Delimiter">(</span>string form<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ load<span class="Delimiter">(</span>form<span class="Delimiter">);</span>
+ transform_all<span class="Delimiter">();</span>
+<span class="Delimiter">}</span>
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/html/013literal_string.cc.html b/html/014literal_string.cc.html
index 56fff30c..b137323a 100644
--- a/html/013literal_string.cc.html
+++ b/html/014literal_string.cc.html
@@ -2,7 +2,7 @@
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
-<title>Mu - 013literal_string.cc</title>
+<title>Mu - 014literal_string.cc</title>
<meta name="Generator" content="Vim/7.4">
<meta name="plugin-version" content="vim7.4_v1">
<meta name="syntax" content="cpp">
@@ -13,13 +13,13 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.traceContains { color: #008000; }
.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
.Identifier { color: #804000; }
.Constant { color: #00a0a0; }
-.traceContains { color: #008000; }
-->
</style>
@@ -43,18 +43,18 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
recipe main [
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>copy [abc def] <span class="Comment"># copy can't really take a string</span>
]
-<span class="traceContains">+parse: ingredient: {name: "abc def", properties: [_: "literal-string"]}</span>
+<span class="traceContains">+parse: ingredient: {"abc def": "literal-string"}</span>
<span class="Delimiter">:(scenario string_literal_with_colons)</span>
recipe main [
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>copy [abc:def/ghi]
]
-<span class="traceContains">+parse: ingredient: {name: "abc:def/ghi", properties: [_: "literal-string"]}</span>
+<span class="traceContains">+parse: ingredient: {"abc:def/ghi": "literal-string"}</span>
<span class="Delimiter">:(before "End Mu Types Initialization")</span>
-Type_ordinal[<span class="Constant">"literal-string"</span>] = <span class="Constant">0</span><span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"literal-string"</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span>
-<span class="Delimiter">:(after "string next_word(istream& in)")</span>
+<span class="Delimiter">:(before "End next_word Special-cases")</span>
if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
string result = slurp_quoted<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
@@ -66,7 +66,7 @@ Type_ordinal[<span class="Constant">"literal-string"</span>] = <span c
string slurp_quoted<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
ostringstream out<span class="Delimiter">;</span>
assert<span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">());</span> assert<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'['</span><span class="Delimiter">);</span> out << static_cast<char><span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">());</span> <span class="Comment">// slurp the '['</span>
- if <span class="Delimiter">(</span>code_string<span class="Delimiter">(</span>in<span class="Delimiter">,</span> out<span class="Delimiter">))</span>
+ if <span class="Delimiter">(</span>is_code_string<span class="Delimiter">(</span>in<span class="Delimiter">,</span> out<span class="Delimiter">))</span>
slurp_quoted_comment_aware<span class="Delimiter">(</span>in<span class="Delimiter">,</span> out<span class="Delimiter">);</span>
else
slurp_quoted_comment_oblivious<span class="Delimiter">(</span>in<span class="Delimiter">,</span> out<span class="Delimiter">);</span>
@@ -75,7 +75,7 @@ string slurp_quoted<span class="Delimiter">(</span>istream& in<span class="D
<span class="Comment">// A string is a code string if it contains a newline before any non-whitespace</span>
<span class="Comment">// todo: support comments before the newline. But that gets messy.</span>
-bool code_string<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> ostringstream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+bool is_code_string<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> ostream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span>
while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
char c = in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
if <span class="Delimiter">(</span>!isspace<span class="Delimiter">(</span>c<span class="Delimiter">))</span> <span class="Delimiter">{</span>
@@ -92,7 +92,7 @@ bool code_string<span class="Delimiter">(</span>istream& in<span class="Deli
<span class="Comment">// Read a regular string. Regular strings can only contain other regular</span>
<span class="Comment">// strings.</span>
-void slurp_quoted_comment_oblivious<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> ostringstream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+void slurp_quoted_comment_oblivious<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> ostream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span>
int brace_depth = <span class="Constant">1</span><span class="Delimiter">;</span>
while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
char c = in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
@@ -106,13 +106,13 @@ void slurp_quoted_comment_oblivious<span class="Delimiter">(</span>istream&
if <span class="Delimiter">(</span>brace_depth == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">()</span> && brace_depth > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"unbalanced '['</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"unbalanced '['</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
out<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
<span class="Comment">// Read a code string. Code strings can contain either code or regular strings.</span>
-void slurp_quoted_comment_aware<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> ostringstream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+void slurp_quoted_comment_aware<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> ostream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span>
char c<span class="Delimiter">;</span>
while <span class="Delimiter">(</span>in >> c<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>c == <span class="cSpecial">'\\'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -133,7 +133,7 @@ void slurp_quoted_comment_aware<span class="Delimiter">(</span>istream& in<s
out << c<span class="Delimiter">;</span>
if <span class="Delimiter">(</span>c == <span class="Constant">']'</span><span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- raise << <span class="Constant">"unbalanced '['</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"unbalanced '['</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
out<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
@@ -142,18 +142,15 @@ if <span class="Delimiter">(</span>s<span class="Delimiter">.</span>at<span clas
assert<span class="Delimiter">(</span>*s<span class="Delimiter">.</span>rbegin<span class="Delimiter">()</span> == <span class="Constant">']'</span><span class="Delimiter">);</span>
<span class="Comment">// delete [] delimiters</span>
s<span class="Delimiter">.</span>erase<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span>
- s<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>s<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">);</span>
+ strip_last<span class="Delimiter">(</span>s<span class="Delimiter">);</span>
name = s<span class="Delimiter">;</span>
- types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> vector<string> ><span class="Delimiter">(</span>name<span class="Delimiter">,</span> vector<string><span class="Delimiter">()));</span>
- properties<span class="Delimiter">.</span>back<span class="Delimiter">().</span>second<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">"literal-string"</span><span class="Delimiter">);</span>
+ type = new type_tree<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> string_tree*><span class="Delimiter">(</span>name<span class="Delimiter">,</span> new string_tree<span class="Delimiter">(</span><span class="Constant">"literal-string"</span><span class="Delimiter">)));</span>
<span class="Identifier">return</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
-<span class="Comment">//: Two tweaks to printing literal strings compared to other reagents:</span>
-<span class="Comment">//: a) Don't print the string twice in the representation, just put '_' in</span>
-<span class="Comment">//: the property list.</span>
-<span class="Comment">//: b) Escape newlines in the string to make it more friendly to trace().</span>
+<span class="Comment">//: Unlike other reagents, escape newlines in literal strings to make them</span>
+<span class="Comment">//: more friendly to trace().</span>
<span class="Delimiter">:(after "string reagent::to_string()")</span>
if <span class="Delimiter">(</span>is_literal_string<span class="Delimiter">(</span>*this<span class="Delimiter">))</span>
@@ -161,14 +158,14 @@ if <span class="Delimiter">(</span>s<span class="Delimiter">.</span>at<span clas
<span class="Delimiter">:(code)</span>
bool is_literal_string<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- <span class="Identifier">return</span> !x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">"literal-string"</span><span class="Delimiter">;</span>
+ <span class="Identifier">return</span> x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second && x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">-></span>value == <span class="Constant">"literal-string"</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
string emit_literal_string<span class="Delimiter">(</span>string name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
size_t pos = <span class="Constant">0</span><span class="Delimiter">;</span>
while <span class="Delimiter">(</span>pos != string::npos<span class="Delimiter">)</span>
pos = replace<span class="Delimiter">(</span>name<span class="Delimiter">,</span> <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">,</span> <span class="Constant">"</span><span class="cSpecial">\\</span><span class="Constant">n"</span><span class="Delimiter">,</span> pos<span class="Delimiter">);</span>
- <span class="Identifier">return</span> <span class="Constant">"{name: </span><span class="cSpecial">\"</span><span class="Constant">"</span>+name+<span class="Constant">"</span><span class="cSpecial">\"</span><span class="Constant">, properties: [_: </span><span class="cSpecial">\"</span><span class="Constant">literal-string</span><span class="cSpecial">\"</span><span class="Constant">]}"</span><span class="Delimiter">;</span>
+ <span class="Identifier">return</span> <span class="Constant">"{</span><span class="cSpecial">\"</span><span class="Constant">"</span>+name+<span class="Constant">"</span><span class="cSpecial">\"</span><span class="Constant">: </span><span class="cSpecial">\"</span><span class="Constant">literal-string</span><span class="cSpecial">\"</span><span class="Constant">}"</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
size_t replace<span class="Delimiter">(</span>string& str<span class="Delimiter">,</span> const string& from<span class="Delimiter">,</span> const string& to<span class="Delimiter">,</span> size_t n<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -178,41 +175,45 @@ size_t replace<span class="Delimiter">(</span>string& str<span class="Delimi
<span class="Identifier">return</span> result<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+void strip_last<span class="Delimiter">(</span>string& s<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!s<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> s<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>s<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
<span class="Delimiter">:(scenario string_literal_nested)</span>
recipe main [
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>copy [abc [def]]
]
-<span class="traceContains">+parse: ingredient: {name: "abc [def]", properties: [_: "literal-string"]}</span>
+<span class="traceContains">+parse: ingredient: {"abc [def]": "literal-string"}</span>
<span class="Delimiter">:(scenario string_literal_escaped)</span>
recipe main [
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>copy [abc \[def]
]
-<span class="traceContains">+parse: ingredient: {name: "abc [def", properties: [_: "literal-string"]}</span>
+<span class="traceContains">+parse: ingredient: {"abc [def": "literal-string"}</span>
<span class="Delimiter">:(scenario string_literal_escaped_comment_aware)</span>
recipe main [
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>copy [
abc \\\[def]
]
-<span class="traceContains">+parse: ingredient: {name: "\nabc \[def", properties: [_: "literal-string"]}</span>
+<span class="traceContains">+parse: ingredient: {"\nabc \[def": "literal-string"}</span>
<span class="Delimiter">:(scenario string_literal_and_comment)</span>
recipe main [
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>copy [abc] <span class="Comment"># comment</span>
]
+<span class="traceContains">+parse: --- defining main</span>
<span class="traceContains">+parse: instruction: copy</span>
-<span class="traceContains">+parse: ingredient: {name: "abc", properties: [_: "literal-string"]}</span>
-<span class="traceContains">+parse: product: {name: "1", properties: ["1": "address":"array":"character"]}</span>
-<span class="Comment"># no other ingredients</span>
-$parse: <span class="Constant">3</span>
+<span class="traceContains">+parse: number of ingredients: 1</span>
+<span class="traceContains">+parse: ingredient: {"abc": "literal-string"}</span>
+<span class="traceContains">+parse: product: {"1": <"address" : <"array" : <"character" : <>>>>}</span>
<span class="Delimiter">:(scenario string_literal_escapes_newlines_in_trace)</span>
recipe main [
copy [abc
def]
]
-<span class="traceContains">+parse: ingredient: {name: "abc\ndef", properties: [_: "literal-string"]}</span>
+<span class="traceContains">+parse: ingredient: {"abc\ndef": "literal-string"}</span>
<span class="Delimiter">:(scenario string_literal_can_skip_past_comments)</span>
recipe main [
@@ -221,13 +222,13 @@ recipe main [
bar
]
]
-<span class="traceContains">+parse: ingredient: {name: "\n # ']' inside comment\n bar\n ", properties: [_: "literal-string"]}</span>
+<span class="traceContains">+parse: ingredient: {"\n # ']' inside comment\n bar\n ": "literal-string"}</span>
<span class="Delimiter">:(scenario string_literal_empty)</span>
recipe main [
copy []
]
-<span class="traceContains">+parse: ingredient: {name: "", properties: [_: "literal-string"]}</span>
+<span class="traceContains">+parse: ingredient: {"": "literal-string"}</span>
</pre>
</body>
</html>
diff --git a/html/014literal_noninteger.cc.html b/html/015literal_noninteger.cc.html
index eb054c75..4c0f8852 100644
--- a/html/014literal_noninteger.cc.html
+++ b/html/015literal_noninteger.cc.html
@@ -2,7 +2,7 @@
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
-<title>Mu - 014literal_noninteger.cc</title>
+<title>Mu - 015literal_noninteger.cc</title>
<meta name="Generator" content="Vim/7.4">
<meta name="plugin-version" content="vim7.4_v1">
<meta name="syntax" content="cpp">
@@ -13,13 +13,13 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.traceContains { color: #008000; }
.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
.Identifier { color: #804000; }
.Constant { color: #00a0a0; }
-.traceContains { color: #008000; }
-->
</style>
@@ -38,14 +38,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
recipe main [
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">3.14159</span>
]
-<span class="traceContains">+parse: ingredient: {name: "3.14159", properties: ["3.14159": "literal-number"]}</span>
+<span class="traceContains">+parse: ingredient: {"3.14159": "literal-number"}</span>
<span class="Delimiter">:(after "Parsing reagent(string s)")</span>
if <span class="Delimiter">(</span>is_noninteger<span class="Delimiter">(</span>s<span class="Delimiter">))</span> <span class="Delimiter">{</span>
name = s<span class="Delimiter">;</span>
- types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> vector<string> ><span class="Delimiter">(</span>name<span class="Delimiter">,</span> vector<string><span class="Delimiter">()));</span>
- properties<span class="Delimiter">.</span>back<span class="Delimiter">().</span>second<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">"literal-number"</span><span class="Delimiter">);</span>
+ type = new type_tree<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> string_tree*><span class="Delimiter">(</span>name<span class="Delimiter">,</span> new string_tree<span class="Delimiter">(</span><span class="Constant">"literal-number"</span><span class="Delimiter">)));</span>
set_value<span class="Delimiter">(</span>to_double<span class="Delimiter">(</span>s<span class="Delimiter">));</span>
<span class="Identifier">return</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -53,7 +52,8 @@ if <span class="Delimiter">(</span>is_noninteger<span class="Delimiter">(</span>
<span class="Delimiter">:(code)</span>
bool is_noninteger<span class="Delimiter">(</span>const string& s<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Identifier">return</span> s<span class="Delimiter">.</span>find_first_not_of<span class="Delimiter">(</span><span class="Constant">"0123456789-."</span><span class="Delimiter">)</span> == string::npos
- && s<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">'.'</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">;</span>
+ && s<span class="Delimiter">.</span>find_first_of <span class="Delimiter">(</span><span class="Constant">"0123456789-"</span><span class="Delimiter">)</span> != string::npos
+ && std::count<span class="Delimiter">(</span>s<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> s<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> <span class="Constant">'.'</span><span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
double to_double<span class="Delimiter">(</span>string n<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -63,6 +63,16 @@ double to_double<span class="Delimiter">(</span>string n<span class="Delimiter">
assert<span class="Delimiter">(</span>*end == <span class="cSpecial">'\0'</span><span class="Delimiter">);</span>
<span class="Identifier">return</span> result<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+
+void test_is_noninteger<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+ CHECK<span class="Delimiter">(</span>!is_noninteger<span class="Delimiter">(</span><span class="Constant">"1234"</span><span class="Delimiter">));</span>
+ CHECK<span class="Delimiter">(</span>!is_noninteger<span class="Delimiter">(</span><span class="Constant">"1a2"</span><span class="Delimiter">));</span>
+ CHECK<span class="Delimiter">(</span>is_noninteger<span class="Delimiter">(</span><span class="Constant">"234.0"</span><span class="Delimiter">));</span>
+ CHECK<span class="Delimiter">(</span>!is_noninteger<span class="Delimiter">(</span><span class="Constant">"..."</span><span class="Delimiter">));</span>
+ CHECK<span class="Delimiter">(</span>!is_noninteger<span class="Delimiter">(</span><span class="Constant">"."</span><span class="Delimiter">));</span>
+ CHECK<span class="Delimiter">(</span>is_noninteger<span class="Delimiter">(</span><span class="Constant">"2."</span><span class="Delimiter">));</span>
+ CHECK<span class="Delimiter">(</span>is_noninteger<span class="Delimiter">(</span><span class="Constant">".2"</span><span class="Delimiter">));</span>
+<span class="Delimiter">}</span>
</pre>
</body>
</html>
diff --git a/html/020run.cc.html b/html/020run.cc.html
index 92ad8931..38ffeb73 100644
--- a/html/020run.cc.html
+++ b/html/020run.cc.html
@@ -16,9 +16,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
.SalientComment { color: #00ffff; }
.CommentedCode { color: #6c6c6c; }
.PreProc { color: #c000c0; }
-.traceAbsent { color: #c00000; }
.Delimiter { color: #a04060; }
.traceContains { color: #008000; }
+.traceAbsent { color: #c00000; }
.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
@@ -99,10 +99,10 @@ void run_current_routine<span class="Delimiter">()</span>
<span class="Comment">// Running One Instruction</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+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>
- if <span class="Delimiter">(</span>Memory[<span class="Constant">0</span>] != <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"something wrote to location 0; this should never happen</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
- Memory[<span class="Constant">0</span>] = <span class="Constant">0</span><span class="Delimiter">;</span>
+ 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>
+ if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">)</span> != <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << <span class="Constant">"something wrote to location 0; this should never happen</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span>
<span class="Delimiter">}</span>
<span class="Comment">// Read all ingredients from memory.</span>
<span class="Comment">// Each ingredient loads a vector of values rather than a single value; mu</span>
@@ -120,20 +120,6 @@ void run_current_routine<span class="Delimiter">()</span>
switch <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>operation<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Comment">// Primitive Recipe Implementations</span>
case COPY: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">)</span> != SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">))</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"ingredients and products should match in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!is_mu_array<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> && is_mu_array<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"can't copy "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="Constant">" to array "</span> << current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>is_mu_array<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> && !is_mu_array<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"can't copy array "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="Constant">" to "</span> << current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- <span class="Delimiter">}</span>
copy<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> ingredients<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> inserter<span class="Delimiter">(</span>products<span class="Delimiter">,</span> products<span class="Delimiter">.</span>begin<span class="Delimiter">()));</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -142,9 +128,8 @@ void run_current_routine<span class="Delimiter">()</span>
cout << <span class="Constant">"not a primitive op: "</span> << current_instruction<span class="Delimiter">().</span>operation << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
- finish_instruction:
if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>products<span class="Delimiter">)</span> < SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">))</span> <span class="Delimiter">{</span>
- raise << SIZE<span class="Delimiter">(</span>products<span class="Delimiter">)</span> << <span class="Constant">" vs "</span> << SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">)</span> << <span class="Constant">": failed to write to all products! "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << end<span class="Delimiter">();</span>
+ raise_error << SIZE<span class="Delimiter">(</span>products<span class="Delimiter">)</span> << <span class="Constant">" vs "</span> << SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">)</span> << <span class="Constant">": failed to write to all products! "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
else <span class="Delimiter">{</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -171,21 +156,23 @@ inline long long int& current_step_index<span class="Delimiter">()</span> <s
<span class="Delimiter">}</span>
inline const string& current_recipe_name<span class="Delimiter">()</span> <span class="Delimiter">{</span>
- <span class="Identifier">return</span> Recipe[Current_routine<span class="Delimiter">-></span>running_recipe]<span class="Delimiter">.</span>name<span class="Delimiter">;</span>
+ <span class="Identifier">return</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> Current_routine<span class="Delimiter">-></span>running_recipe<span class="Delimiter">).</span>name<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
inline const instruction& current_instruction<span class="Delimiter">()</span> <span class="Delimiter">{</span>
- <span class="Identifier">return</span> Recipe[Current_routine<span class="Delimiter">-></span>running_recipe]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>running_step_index<span class="Delimiter">);</span>
+ <span class="Identifier">return</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> Current_routine<span class="Delimiter">-></span>running_recipe<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>running_step_index<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
inline bool routine::completed<span class="Delimiter">()</span> const <span class="Delimiter">{</span>
- <span class="Identifier">return</span> running_step_index >= SIZE<span class="Delimiter">(</span>Recipe[running_recipe]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span>
+ <span class="Identifier">return</span> running_step_index >= SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> running_recipe<span class="Delimiter">).</span>steps<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
<span class="SalientComment">//:: Startup flow</span>
<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="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>
transform_all<span class="Delimiter">();</span>
@@ -203,24 +190,26 @@ if <span class="Delimiter">(</span>argc > <span class="Constant">1</span><spa
argc--<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
transform_all<span class="Delimiter">();</span>
- if <span class="Delimiter">(</span>Run_tests<span class="Delimiter">)</span> Recipe<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>Recipe_ordinal[string<span class="Delimiter">(</span><span class="Constant">"main"</span><span class="Delimiter">)</span>]<span class="Delimiter">);</span>
+<span class="CommentedCode">//? dump_recipe("handle-keyboard-event"), exit(0);</span>
+ if <span class="Delimiter">(</span>Run_tests<span class="Delimiter">)</span> Recipe<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> string<span class="Delimiter">(</span><span class="Constant">"main"</span><span class="Delimiter">)));</span>
+ <span class="Comment">// End Loading .mu Files</span>
<span class="Delimiter">}</span>
<span class="Comment">//: Step 3: if we aren't running tests, locate a recipe called 'main' and</span>
<span class="Comment">//: start running it.</span>
<span class="Delimiter">:(before "End Main")</span>
-if <span class="Delimiter">(</span>!Run_tests<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+if <span class="Delimiter">(</span>!Run_tests && contains_key<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> string<span class="Delimiter">(</span><span class="Constant">"main"</span><span class="Delimiter">))</span> && contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> string<span class="Delimiter">(</span><span class="Constant">"main"</span><span class="Delimiter">))))</span> <span class="Delimiter">{</span>
setup<span class="Delimiter">();</span>
<span class="CommentedCode">//? Trace_file = "interactive";</span>
<span class="CommentedCode">//? START_TRACING_UNTIL_END_OF_SCOPE;</span>
-<span class="CommentedCode">//? Trace_stream->collect_layers.insert("app");</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9990</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"=== Starting to run"</span> << end<span class="Delimiter">();</span>
run_main<span class="Delimiter">(</span>argc<span class="Delimiter">,</span> argv<span class="Delimiter">);</span>
teardown<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(code)</span>
void run_main<span class="Delimiter">(</span>int argc<span class="Delimiter">,</span> char* argv[]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- recipe_ordinal r = Recipe_ordinal[string<span class="Delimiter">(</span><span class="Constant">"main"</span><span class="Delimiter">)</span>]<span class="Delimiter">;</span>
+ recipe_ordinal r = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> string<span class="Delimiter">(</span><span class="Constant">"main"</span><span class="Delimiter">));</span>
if <span class="Delimiter">(</span>r<span class="Delimiter">)</span> run<span class="Delimiter">(</span>r<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
@@ -261,10 +250,11 @@ void load_permanently<span class="Delimiter">(</span>string filename<span class=
ifstream fin<span class="Delimiter">(</span>filename<span class="Delimiter">.</span>c_str<span class="Delimiter">());</span>
fin<span class="Delimiter">.</span>peek<span class="Delimiter">();</span>
if <span class="Delimiter">(</span>!fin<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"no such file "</span> << filename << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"no such file "</span> << filename << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">return</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
fin >> std::noskipws<span class="Delimiter">;</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9990</span><span class="Delimiter">,</span> <span class="Constant">"load"</span><span class="Delimiter">)</span> << <span class="Constant">"=== "</span> << filename << end<span class="Delimiter">();</span>
load<span class="Delimiter">(</span>fin<span class="Delimiter">);</span>
fin<span class="Delimiter">.</span>close<span class="Delimiter">();</span>
<span class="Comment">// freeze everything so it doesn't get cleared by tests</span>
@@ -292,6 +282,7 @@ void load_all_permanently<span class="Delimiter">(</span>string dir<span class="
<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Includes")</span>
<span class="PreProc">#include</span><span class="Constant"><dirent.h></span>
+<span class="PreProc">#include</span><span class="Constant"><sys/stat.h></span>
<span class="SalientComment">//:: Reading from memory, writing to memory.</span>
@@ -305,59 +296,69 @@ vector<double> read_memory<span class="Delimiter">(</span>reagent x<span c
long long int base = x<span class="Delimiter">.</span>value<span class="Delimiter">;</span>
long long int size = size_of<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
for <span class="Delimiter">(</span>long long int offset = <span class="Constant">0</span><span class="Delimiter">;</span> offset < size<span class="Delimiter">;</span> ++offset<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- double val = Memory[base+offset]<span class="Delimiter">;</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"mem"</span><span class="Delimiter">)</span> << <span class="Constant">"location "</span> << base+offset << <span class="Constant">" is "</span> << val << end<span class="Delimiter">();</span>
+ double val = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> base+offset<span class="Delimiter">);</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">"location "</span> << base+offset << <span class="Constant">" is "</span> << no_scientific<span class="Delimiter">(</span>val<span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>val<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
<span class="Identifier">return</span> result<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
void write_memory<span class="Delimiter">(</span>reagent x<span class="Delimiter">,</span> vector<double> data<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << <span class="Constant">"can't write to "</span> << x<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"; no type</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
if <span class="Delimiter">(</span>is_dummy<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
long long int base = x<span class="Delimiter">.</span>value<span class="Delimiter">;</span>
if <span class="Delimiter">(</span>size_mismatch<span class="Delimiter">(</span>x<span class="Delimiter">,</span> data<span class="Delimiter">))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": size mismatch in storing to "</span> << x<span class="Delimiter">.</span>original_string << <span class="Constant">" ("</span> << size_of<span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">)</span> << <span class="Constant">" vs "</span> << SIZE<span class="Delimiter">(</span>data<span class="Delimiter">)</span> << <span class="Constant">") at '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"size mismatch in storing to "</span> << x<span class="Delimiter">.</span>original_string << <span class="Constant">" ("</span> << size_of<span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="Constant">" vs "</span> << SIZE<span class="Delimiter">(</span>data<span class="Delimiter">)</span> << <span class="Constant">") at '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">return</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
for <span class="Delimiter">(</span>long long int offset = <span class="Constant">0</span><span class="Delimiter">;</span> offset < SIZE<span class="Delimiter">(</span>data<span class="Delimiter">);</span> ++offset<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"mem"</span><span class="Delimiter">)</span> << <span class="Constant">"storing "</span> << data<span class="Delimiter">.</span>at<span class="Delimiter">(</span>offset<span class="Delimiter">)</span> << <span class="Constant">" in location "</span> << base+offset << end<span class="Delimiter">();</span>
- Memory[base+offset] = data<span class="Delimiter">.</span>at<span class="Delimiter">(</span>offset<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>base+offset == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</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>offset<span class="Delimiter">))</span> << <span class="Constant">" in location "</span> << base+offset << end<span class="Delimiter">();</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> base+offset<span class="Delimiter">,</span> data<span class="Delimiter">.</span>at<span class="Delimiter">(</span>offset<span class="Delimiter">));</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(code)</span>
long long int size_of<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>type == <span class="Constant">NULL</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
<span class="Comment">// End size_of(reagent) Cases</span>
- <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">);</span>
+ <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
-long long int size_of<span class="Delimiter">(</span>const vector<type_ordinal>& types<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
- <span class="Comment">// End size_of(types) Cases</span>
+long long int size_of<span class="Delimiter">(</span>const type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>type == <span class="Constant">NULL</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
+ <span class="Comment">// End size_of(type) Cases</span>
<span class="Identifier">return</span> <span class="Constant">1</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
bool size_mismatch<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">,</span> const vector<double>& data<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>type == <span class="Constant">NULL</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
<span class="Comment">// End size_mismatch(x) Cases</span>
<span class="CommentedCode">//? if (size_of(x) != SIZE(data)) cerr << size_of(x) << " vs " << SIZE(data) << '\n';</span>
<span class="Identifier">return</span> size_of<span class="Delimiter">(</span>x<span class="Delimiter">)</span> != SIZE<span class="Delimiter">(</span>data<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
-bool is_dummy<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+inline bool is_dummy<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Identifier">return</span> x<span class="Delimiter">.</span>name == <span class="Constant">"_"</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
-bool is_literal<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- <span class="Identifier">return</span> SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">)</span> == <span class="Constant">1</span> && r<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">;</span>
+inline bool is_literal<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!r<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value == <span class="Constant">0</span><span class="Delimiter">)</span>
+ assert<span class="Delimiter">(</span>!r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left && !r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">);</span>
+ <span class="Identifier">return</span> r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value == <span class="Constant">0</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
-bool is_mu_array<span class="Delimiter">(</span>reagent r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- <span class="Identifier">return</span> !r<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && r<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == Type_ordinal[<span class="Constant">"array"</span>]<span class="Delimiter">;</span>
+inline bool scalar<span class="Delimiter">(</span>const vector<long long int>& x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ <span class="Identifier">return</span> SIZE<span class="Delimiter">(</span>x<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+inline bool scalar<span class="Delimiter">(</span>const vector<double>& x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ <span class="Identifier">return</span> SIZE<span class="Delimiter">(</span>x<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
-<span class="Delimiter">:(code)</span>
<span class="Comment">// helper for tests</span>
void run<span class="Delimiter">(</span>string form<span class="Delimiter">)</span> <span class="Delimiter">{</span>
vector<recipe_ordinal> tmp = load<span class="Delimiter">(</span>form<span class="Delimiter">);</span>
@@ -383,32 +384,12 @@ recipe main [
<span class="traceContains">+run: _ <- copy 0</span>
<span class="Delimiter">:(scenario write_to_0_disallowed)</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
- <span class="Constant">0</span><span class="Special"> <- </span>copy <span class="Constant">34</span>
+ <span class="Constant">0</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
]
<span class="traceAbsent">-mem: storing 34 in location 0</span>
-<span class="Delimiter">:(scenario copy_checks_reagent_count)</span>
-<span class="Special">% Hide_warnings = true;</span>
-recipe main [
- <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">35</span>
-]
-<span class="traceContains">+warn: ingredients and products should match in '1:number <- copy 34, 35'</span>
-
-<span class="Delimiter">:(scenario write_scalar_to_array_disallowed)</span>
-<span class="Special">% Hide_warnings = true;</span>
-recipe main [
- <span class="Constant">1</span>:array:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
-]
-<span class="traceContains">+warn: can't copy 34 to array 1:array:number</span>
-
-<span class="Delimiter">:(scenario write_scalar_to_array_disallowed_2)</span>
-<span class="Special">% Hide_warnings = true;</span>
-recipe main [
- <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:array:number<span class="Special"> <- </span>copy <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">35</span>
-]
-<span class="traceContains">+warn: can't copy 35 to array 2:array:number</span>
-
<span class="Comment">//: mu is robust to various combinations of commas and spaces. You just have</span>
<span class="Comment">//: to put spaces around the '<-'.</span>
diff --git a/html/021arithmetic.cc.html b/html/021arithmetic.cc.html
deleted file mode 100644
index 7575dd28..00000000
--- a/html/021arithmetic.cc.html
+++ /dev/null
@@ -1,266 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-<meta http-equiv="content-type" content="text/html; charset=UTF-8">
-<title>Mu - 021arithmetic.cc</title>
-<meta name="Generator" content="Vim/7.4">
-<meta name="plugin-version" content="vim7.4_v1">
-<meta name="syntax" content="cpp">
-<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
-<meta name="colorscheme" content="minimal">
-<style type="text/css">
-<!--
-pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
-body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1.05em; }
-.cSpecial { color: #008000; }
-.traceContains { color: #008000; }
-.Comment { color: #9090ff; }
-.Delimiter { color: #a04060; }
-.Special { color: #ff6060; }
-.Identifier { color: #804000; }
-.Constant { color: #00a0a0; }
--->
-</style>
-
-<script type='text/javascript'>
-<!--
-
--->
-</script>
-</head>
-<body>
-<pre id='vimCodeElement'>
-<span class="Comment">//: Arithmetic primitives</span>
-
-<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
-ADD<span class="Delimiter">,</span>
-<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"add"</span>] = ADD<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
-case ADD: <span class="Delimiter">{</span>
- double result = <span class="Constant">0</span><span class="Delimiter">;</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'add' requires number ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- result += ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- <span class="Delimiter">}</span>
- products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
- products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
-<span class="Delimiter">}</span>
-
-<span class="Delimiter">:(scenario add_literal)</span>
-recipe main [
- <span class="Constant">1</span>:number<span class="Special"> <- </span>add <span class="Constant">23</span><span class="Delimiter">,</span> <span class="Constant">34</span>
-]
-<span class="traceContains">+mem: storing 57 in location 1</span>
-
-<span class="Delimiter">:(scenario add)</span>
-recipe main [
- <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">23</span>
- <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
- <span class="Constant">3</span>:number<span class="Special"> <- </span>add <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number
-]
-<span class="traceContains">+mem: storing 57 in location 3</span>
-
-<span class="Delimiter">:(scenario add_multiple)</span>
-recipe main [
- <span class="Constant">1</span>:number<span class="Special"> <- </span>add <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">4</span><span class="Delimiter">,</span> <span class="Constant">5</span>
-]
-<span class="traceContains">+mem: storing 12 in location 1</span>
-
-<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
-SUBTRACT<span class="Delimiter">,</span>
-<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"subtract"</span>] = SUBTRACT<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
-case SUBTRACT: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'subtract' has no ingredients</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'subtract' requires number ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- double result = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'subtract' requires number ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- result -= ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- <span class="Delimiter">}</span>
- products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
- products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
-<span class="Delimiter">}</span>
-
-<span class="Delimiter">:(scenario subtract_literal)</span>
-recipe main [
- <span class="Constant">1</span>:number<span class="Special"> <- </span>subtract <span class="Constant">5</span><span class="Delimiter">,</span> <span class="Constant">2</span>
-]
-<span class="traceContains">+mem: storing 3 in location 1</span>
-
-<span class="Delimiter">:(scenario subtract)</span>
-recipe main [
- <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">23</span>
- <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
- <span class="Constant">3</span>:number<span class="Special"> <- </span>subtract <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number
-]
-<span class="traceContains">+mem: storing -11 in location 3</span>
-
-<span class="Delimiter">:(scenario subtract_multiple)</span>
-recipe main [
- <span class="Constant">1</span>:number<span class="Special"> <- </span>subtract <span class="Constant">6</span><span class="Delimiter">,</span> <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">2</span>
-]
-<span class="traceContains">+mem: storing 1 in location 1</span>
-
-<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
-MULTIPLY<span class="Delimiter">,</span>
-<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"multiply"</span>] = MULTIPLY<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
-case MULTIPLY: <span class="Delimiter">{</span>
- double result = <span class="Constant">1</span><span class="Delimiter">;</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'multiply' requires number ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- result *= ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- <span class="Delimiter">}</span>
- products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
- products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
-<span class="Delimiter">}</span>
-
-<span class="Delimiter">:(scenario multiply_literal)</span>
-recipe main [
- <span class="Constant">1</span>:number<span class="Special"> <- </span>multiply <span class="Constant">2</span><span class="Delimiter">,</span> <span class="Constant">3</span>
-]
-<span class="traceContains">+mem: storing 6 in location 1</span>
-
-<span class="Delimiter">:(scenario multiply)</span>
-recipe main [
- <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">4</span>
- <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">6</span>
- <span class="Constant">3</span>:number<span class="Special"> <- </span>multiply <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number
-]
-<span class="traceContains">+mem: storing 24 in location 3</span>
-
-<span class="Delimiter">:(scenario multiply_multiple)</span>
-recipe main [
- <span class="Constant">1</span>:number<span class="Special"> <- </span>multiply <span class="Constant">2</span><span class="Delimiter">,</span> <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">4</span>
-]
-<span class="traceContains">+mem: storing 24 in location 1</span>
-
-<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
-DIVIDE<span class="Delimiter">,</span>
-<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"divide"</span>] = DIVIDE<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
-case DIVIDE: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'divide' has no ingredients</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'divide' requires number ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- double result = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'divide' requires number ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- result /= ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- <span class="Delimiter">}</span>
- products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
- products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
-<span class="Delimiter">}</span>
-
-<span class="Delimiter">:(scenario divide_literal)</span>
-recipe main [
- <span class="Constant">1</span>:number<span class="Special"> <- </span>divide <span class="Constant">8</span><span class="Delimiter">,</span> <span class="Constant">2</span>
-]
-<span class="traceContains">+mem: storing 4 in location 1</span>
-
-<span class="Delimiter">:(scenario divide)</span>
-recipe main [
- <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">27</span>
- <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">3</span>
- <span class="Constant">3</span>:number<span class="Special"> <- </span>divide <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number
-]
-<span class="traceContains">+mem: storing 9 in location 3</span>
-
-<span class="Delimiter">:(scenario divide_multiple)</span>
-recipe main [
- <span class="Constant">1</span>:number<span class="Special"> <- </span>divide <span class="Constant">12</span><span class="Delimiter">,</span> <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">2</span>
-]
-<span class="traceContains">+mem: storing 2 in location 1</span>
-
-<span class="Comment">//: Integer division</span>
-
-<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
-DIVIDE_WITH_REMAINDER<span class="Delimiter">,</span>
-<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"divide-with-remainder"</span>] = DIVIDE_WITH_REMAINDER<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
-case DIVIDE_WITH_REMAINDER: <span class="Delimiter">{</span>
- products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'divide-with-remainder' requires exactly two ingredients, but got '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> || !scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'divide-with-remainder' requires number ingredients, but got '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- long long int quotient = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> / ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- long long int remainder = static_cast<long long int><span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> % static_cast<long long int><span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
- <span class="Comment">// very large integers will lose precision</span>
- products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>quotient<span class="Delimiter">);</span>
- products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>remainder<span class="Delimiter">);</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
-<span class="Delimiter">}</span>
-
-<span class="Delimiter">:(scenario divide_with_remainder_literal)</span>
-recipe main [
- <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>divide-with-remainder <span class="Constant">9</span><span class="Delimiter">,</span> <span class="Constant">2</span>
-]
-<span class="traceContains">+mem: storing 4 in location 1</span>
-<span class="traceContains">+mem: storing 1 in location 2</span>
-
-<span class="Delimiter">:(scenario divide_with_remainder)</span>
-recipe main [
- <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">27</span>
- <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">11</span>
- <span class="Constant">3</span>:number<span class="Delimiter">,</span> <span class="Constant">4</span>:number<span class="Special"> <- </span>divide-with-remainder <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number
-]
-<span class="traceContains">+mem: storing 2 in location 3</span>
-<span class="traceContains">+mem: storing 5 in location 4</span>
-
-<span class="Delimiter">:(scenario divide_with_decimal_point)</span>
-recipe main [
- <span class="Comment"># todo: literal floats?</span>
- <span class="Constant">1</span>:number<span class="Special"> <- </span>divide <span class="Constant">5</span><span class="Delimiter">,</span> <span class="Constant">2</span>
-]
-<span class="traceContains">+mem: storing 2.5 in location 1</span>
-
-<span class="Delimiter">:(code)</span>
-inline bool scalar<span class="Delimiter">(</span>const vector<long long int>& x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- <span class="Identifier">return</span> SIZE<span class="Delimiter">(</span>x<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">;</span>
-<span class="Delimiter">}</span>
-inline bool scalar<span class="Delimiter">(</span>const vector<double>& x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- <span class="Identifier">return</span> SIZE<span class="Delimiter">(</span>x<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">;</span>
-<span class="Delimiter">}</span>
-</pre>
-</body>
-</html>
-<!-- vim: set foldmethod=manual : -->
diff --git a/html/021check_instruction.cc.html b/html/021check_instruction.cc.html
new file mode 100644
index 00000000..f0238926
--- /dev/null
+++ b/html/021check_instruction.cc.html
@@ -0,0 +1,183 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>Mu - 021check_instruction.cc</title>
+<meta name="Generator" content="Vim/7.4">
+<meta name="plugin-version" content="vim7.4_v1">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
+<meta name="colorscheme" content="minimal">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
+body { font-family: monospace; color: #eeeeee; background-color: #080808; }
+* { font-size: 1.05em; }
+.traceContains { color: #008000; }
+.Identifier { color: #804000; }
+.cSpecial { color: #008000; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
+.Special { color: #ff6060; }
+.CommentedCode { color: #6c6c6c; }
+-->
+</style>
+
+<script type='text/javascript'>
+<!--
+
+-->
+</script>
+</head>
+<body>
+<pre id='vimCodeElement'>
+<span class="Comment">//: Introduce a new transform to perform various checks in instructions before</span>
+<span class="Comment">//: we start running them. It'll be extensible, so that we can add checks for</span>
+<span class="Comment">//: new recipes as we extend 'run' to support them.</span>
+<span class="Comment">//:</span>
+<span class="Comment">//: Doing checking in a separate part complicates things, because the values</span>
+<span class="Comment">//: of variables in memory and the processor (current_recipe_name,</span>
+<span class="Comment">//: current_instruction) aren't available at checking time. If I had a more</span>
+<span class="Comment">//: sophisticated layer system I'd introduce the simpler version first and</span>
+<span class="Comment">//: transform it in a separate layer or set of layers.</span>
+
+<span class="Delimiter">:(after "Transform.push_back(update_instruction_operations)")</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_instruction<span class="Delimiter">);</span> <span class="Comment">// idempotent</span>
+
+<span class="Delimiter">:(code)</span>
+void check_instruction<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"--- perform checks for recipe "</span> << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name << end<span class="Delimiter">();</span>
+<span class="CommentedCode">//? cerr << "--- perform checks for recipe " << get(Recipe, r).name << '\n';</span>
+ map<string<span class="Delimiter">,</span> vector<type_ordinal> > metadata<span class="Delimiter">;</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ instruction& inst = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ 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>
+ switch <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ <span class="Comment">// Primitive Recipe Checks</span>
+ case COPY: <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">)</span> != SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << <span class="Constant">"ingredients and products should match in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"can't copy "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="Constant">" to "</span> << inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="Constant">"; types don't match</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">goto</span> finish_checking_instruction<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Comment">// End Primitive Recipe Checks</span>
+ default: <span class="Delimiter">{</span>
+ <span class="Comment">// Defined Recipe Checks</span>
+ <span class="Comment">// End Defined Recipe Checks</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ finish_checking_instruction:<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario copy_checks_reagent_count)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">35</span>
+]
+<span class="traceContains">+error: ingredients and products should match in '1:number <- copy 34, 35'</span>
+
+<span class="Delimiter">:(scenario write_scalar_to_array_disallowed)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+ <span class="Constant">1</span>:array:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
+]
+<span class="traceContains">+error: main: can't copy 34 to 1:array:number; types don't match</span>
+
+<span class="Delimiter">:(scenario write_scalar_to_array_disallowed_2)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:array:number<span class="Special"> <- </span>copy <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">35</span>
+]
+<span class="traceContains">+error: main: can't copy 35 to 2:array:number; types don't match</span>
+
+<span class="Delimiter">:(scenario write_scalar_to_address_disallowed)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+ <span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
+]
+<span class="traceContains">+error: main: can't copy 34 to 1:address:number; types don't match</span>
+
+<span class="Delimiter">:(code)</span>
+bool types_match<span class="Delimiter">(</span>reagent lhs<span class="Delimiter">,</span> reagent rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ <span class="Comment">// '_' never raises type error</span>
+ if <span class="Delimiter">(</span>is_dummy<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+ <span class="Comment">// to sidestep type-checking, use /raw in the source.</span>
+ <span class="Comment">// this is unsafe, and will be highlighted in red inside vim. just for some tests.</span>
+ if <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>rhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+ <span class="Comment">// allow writing 0 to any address</span>
+ if <span class="Delimiter">(</span>rhs<span class="Delimiter">.</span>name == <span class="Constant">"0"</span> && is_mu_address<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>is_literal<span class="Delimiter">(</span>rhs<span class="Delimiter">))</span> <span class="Identifier">return</span> !is_mu_array<span class="Delimiter">(</span>lhs<span class="Delimiter">)</span> && !is_mu_address<span class="Delimiter">(</span>lhs<span class="Delimiter">)</span> && size_of<span class="Delimiter">(</span>rhs<span class="Delimiter">)</span> == size_of<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!lhs<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span> !rhs<span class="Delimiter">.</span>type<span class="Delimiter">;</span>
+ <span class="Identifier">return</span> types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">,</span> rhs<span class="Delimiter">.</span>type<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+<span class="Comment">// two types match if the second begins like the first</span>
+<span class="Comment">// (trees perform the same check recursively on each subtree)</span>
+bool types_match<span class="Delimiter">(</span>type_tree* lhs<span class="Delimiter">,</span> type_tree* rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!lhs<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>!rhs || rhs<span class="Delimiter">-></span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>lhs<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>lhs<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+ <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>rhs<span class="Delimiter">)</span> == size_of<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>lhs<span class="Delimiter">-></span>value != rhs<span class="Delimiter">-></span>value<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+ <span class="Identifier">return</span> types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">-></span>left<span class="Delimiter">,</span> rhs<span class="Delimiter">-></span>left<span class="Delimiter">)</span> && types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">-></span>right<span class="Delimiter">,</span> rhs<span class="Delimiter">-></span>right<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+<span class="Comment">// hacky version that allows 0 addresses</span>
+bool types_match<span class="Delimiter">(</span>const reagent lhs<span class="Delimiter">,</span> const type_tree* rhs<span class="Delimiter">,</span> const vector<double>& data<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>is_dummy<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>rhs<span class="Delimiter">-></span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> scalar<span class="Delimiter">(</span>data<span class="Delimiter">)</span> && data<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">;</span>
+ <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>rhs<span class="Delimiter">)</span> == size_of<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value != rhs<span class="Delimiter">-></span>value<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+ <span class="Identifier">return</span> types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">,</span> rhs<span class="Delimiter">-></span>left<span class="Delimiter">)</span> && types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">,</span> rhs<span class="Delimiter">-></span>right<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+bool is_raw<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ <span class="Identifier">return</span> has_property<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">"raw"</span><span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+bool is_mu_array<span class="Delimiter">(</span>reagent r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!r<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>r<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+ <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">"array"</span><span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+bool is_mu_address<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">"address"</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="Identifier">return</span> r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">-></span>value == <span class="Constant">"literal-number"</span>
+ || r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">-></span>value == <span class="Constant">"literal"</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</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">"character"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Comment">// permit arithmetic on unicode code points</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">"number"</span><span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+bool is_mu_scalar<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> !r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second || r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">-></span>value != <span class="Constant">"literal-string"</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>is_mu_array<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> size_of<span class="Delimiter">(</span>r<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/html/022arithmetic.cc.html b/html/022arithmetic.cc.html
new file mode 100644
index 00000000..0a353d6d
--- /dev/null
+++ b/html/022arithmetic.cc.html
@@ -0,0 +1,353 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>Mu - 022arithmetic.cc</title>
+<meta name="Generator" content="Vim/7.4">
+<meta name="plugin-version" content="vim7.4_v1">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
+<meta name="colorscheme" content="minimal">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
+body { font-family: monospace; color: #eeeeee; background-color: #080808; }
+* { font-size: 1.05em; }
+.traceContains { color: #008000; }
+.cSpecial { color: #008000; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
+.Special { color: #ff6060; }
+.Identifier { color: #804000; }
+.Constant { color: #00a0a0; }
+-->
+</style>
+
+<script type='text/javascript'>
+<!--
+
+-->
+</script>
+</head>
+<body>
+<pre id='vimCodeElement'>
+<span class="Comment">//: Arithmetic primitives</span>
+
+<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
+ADD<span class="Delimiter">,</span>
+<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"add"</span><span class="Delimiter">,</span> ADD<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case ADD: <span class="Delimiter">{</span>
+ <span class="Comment">// primary goal of these checks is to forbid address arithmetic</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'add' requires number ingredients, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">goto</span> finish_checking_instruction<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'add' yields exactly one product in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<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><span class="Constant">0</span><span class="Delimiter">))</span> && !is_mu_number<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> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'add' should yield a number, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case ADD: <span class="Delimiter">{</span>
+ double result = <span class="Constant">0</span><span class="Delimiter">;</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ result += ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+ products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
+ products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario add_literal)</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>add <span class="Constant">23</span><span class="Delimiter">,</span> <span class="Constant">34</span>
+]
+<span class="traceContains">+mem: storing 57 in location 1</span>
+
+<span class="Delimiter">:(scenario add)</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">23</span>
+ <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
+ <span class="Constant">3</span>:number<span class="Special"> <- </span>add <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number
+]
+<span class="traceContains">+mem: storing 57 in location 3</span>
+
+<span class="Delimiter">:(scenario add_multiple)</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>add <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">4</span><span class="Delimiter">,</span> <span class="Constant">5</span>
+]
+<span class="traceContains">+mem: storing 12 in location 1</span>
+
+<span class="Delimiter">:(scenario add_checks_type)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>add <span class="Constant">2</span>:boolean<span class="Delimiter">,</span> <span class="Constant">1</span>
+]
+<span class="traceContains">+error: main: 'add' requires number ingredients, but got 2:boolean</span>
+
+<span class="Delimiter">:(scenario add_checks_return_type)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+ <span class="Constant">1</span>:address:number<span class="Special"> <- </span>add <span class="Constant">2</span><span class="Delimiter">,</span> <span class="Constant">2</span>
+]
+<span class="traceContains">+error: main: 'add' should yield a number, but got 1:address:number</span>
+
+<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
+SUBTRACT<span class="Delimiter">,</span>
+<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"subtract"</span><span class="Delimiter">,</span> SUBTRACT<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case SUBTRACT: <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'subtract' has no ingredients</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Comment">// permit address offset computations in tests</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'subtract' requires number ingredients, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">goto</span> finish_checking_instruction<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'subtract' yields exactly one product in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<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><span class="Constant">0</span><span class="Delimiter">))</span> && !is_mu_number<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> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'subtract' should yield a number, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case SUBTRACT: <span class="Delimiter">{</span>
+ double result = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
+ result -= ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
+ products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario subtract_literal)</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>subtract <span class="Constant">5</span><span class="Delimiter">,</span> <span class="Constant">2</span>
+]
+<span class="traceContains">+mem: storing 3 in location 1</span>
+
+<span class="Delimiter">:(scenario subtract)</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">23</span>
+ <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
+ <span class="Constant">3</span>:number<span class="Special"> <- </span>subtract <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number
+]
+<span class="traceContains">+mem: storing -11 in location 3</span>
+
+<span class="Delimiter">:(scenario subtract_multiple)</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>subtract <span class="Constant">6</span><span class="Delimiter">,</span> <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">2</span>
+]
+<span class="traceContains">+mem: storing 1 in location 1</span>
+
+<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
+MULTIPLY<span class="Delimiter">,</span>
+<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"multiply"</span><span class="Delimiter">,</span> MULTIPLY<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case MULTIPLY: <span class="Delimiter">{</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'multiply' requires number ingredients, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">goto</span> finish_checking_instruction<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'multiply' yields exactly one product in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<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><span class="Constant">0</span><span class="Delimiter">))</span> && !is_mu_number<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> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'multiply' should yield a number, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case MULTIPLY: <span class="Delimiter">{</span>
+ double result = <span class="Constant">1</span><span class="Delimiter">;</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ result *= ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+ products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
+ products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario multiply_literal)</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>multiply <span class="Constant">2</span><span class="Delimiter">,</span> <span class="Constant">3</span>
+]
+<span class="traceContains">+mem: storing 6 in location 1</span>
+
+<span class="Delimiter">:(scenario multiply)</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">4</span>
+ <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">6</span>
+ <span class="Constant">3</span>:number<span class="Special"> <- </span>multiply <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number
+]
+<span class="traceContains">+mem: storing 24 in location 3</span>
+
+<span class="Delimiter">:(scenario multiply_multiple)</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>multiply <span class="Constant">2</span><span class="Delimiter">,</span> <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">4</span>
+]
+<span class="traceContains">+mem: storing 24 in location 1</span>
+
+<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
+DIVIDE<span class="Delimiter">,</span>
+<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"divide"</span><span class="Delimiter">,</span> DIVIDE<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case DIVIDE: <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'divide' has no ingredients</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'divide' requires number ingredients, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">goto</span> finish_checking_instruction<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'divide' yields exactly one product in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<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><span class="Constant">0</span><span class="Delimiter">))</span> && !is_mu_number<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> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'divide' should yield a number, but got "</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>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case DIVIDE: <span class="Delimiter">{</span>
+ double result = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
+ result /= ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
+ products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario divide_literal)</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>divide <span class="Constant">8</span><span class="Delimiter">,</span> <span class="Constant">2</span>
+]
+<span class="traceContains">+mem: storing 4 in location 1</span>
+
+<span class="Delimiter">:(scenario divide)</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">27</span>
+ <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">3</span>
+ <span class="Constant">3</span>:number<span class="Special"> <- </span>divide <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number
+]
+<span class="traceContains">+mem: storing 9 in location 3</span>
+
+<span class="Delimiter">:(scenario divide_multiple)</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>divide <span class="Constant">12</span><span class="Delimiter">,</span> <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">2</span>
+]
+<span class="traceContains">+mem: storing 2 in location 1</span>
+
+<span class="Comment">//: Integer division</span>
+
+<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
+DIVIDE_WITH_REMAINDER<span class="Delimiter">,</span>
+<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"divide-with-remainder"</span><span class="Delimiter">,</span> DIVIDE_WITH_REMAINDER<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case DIVIDE_WITH_REMAINDER: <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'divide-with-remainder' requires exactly two ingredients, but got '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> || !is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'divide-with-remainder' requires number ingredients, but got '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">)</span> > <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'divide-with-remainder' yields two products in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>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> && !is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'divide-with-remainder' should yield a number, but got "</span> << inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">goto</span> finish_checking_instruction<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case DIVIDE_WITH_REMAINDER: <span class="Delimiter">{</span>
+ products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">);</span>
+ long long int a = static_cast<long long int><span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
+ long long int b = static_cast<long long int><span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
+ if <span class="Delimiter">(</span>b == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"divide by zero in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ long long int quotient = a / b<span class="Delimiter">;</span>
+ long long int remainder = a % b<span class="Delimiter">;</span>
+ <span class="Comment">// very large integers will lose precision</span>
+ products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>quotient<span class="Delimiter">);</span>
+ products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>remainder<span class="Delimiter">);</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario divide_with_remainder_literal)</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number<span class="Special"> <- </span>divide-with-remainder <span class="Constant">9</span><span class="Delimiter">,</span> <span class="Constant">2</span>
+]
+<span class="traceContains">+mem: storing 4 in location 1</span>
+<span class="traceContains">+mem: storing 1 in location 2</span>
+
+<span class="Delimiter">:(scenario divide_with_remainder)</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">27</span>
+ <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">11</span>
+ <span class="Constant">3</span>:number<span class="Delimiter">,</span> <span class="Constant">4</span>:number<span class="Special"> <- </span>divide-with-remainder <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number
+]
+<span class="traceContains">+mem: storing 2 in location 3</span>
+<span class="traceContains">+mem: storing 5 in location 4</span>
+
+<span class="Delimiter">:(scenario divide_with_decimal_point)</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>divide <span class="Constant">5</span><span class="Delimiter">,</span> <span class="Constant">2</span>
+]
+<span class="traceContains">+mem: storing 2.5 in location 1</span>
+
+<span class="Delimiter">:(scenario divide_by_zero)</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>divide <span class="Constant">4</span><span class="Delimiter">,</span> <span class="Constant">0</span>
+]
+<span class="traceContains">+mem: storing inf in location 1</span>
+
+<span class="Delimiter">:(scenario divide_by_zero_2)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>divide-with-remainder <span class="Constant">4</span><span class="Delimiter">,</span> <span class="Constant">0</span>
+]
+<span class="Comment"># integer division can't return floating-point infinity</span>
+<span class="traceContains">+error: main: divide by zero in '1:number <- divide-with-remainder 4, 0'</span>
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/html/022boolean.cc.html b/html/023boolean.cc.html
index f1c0b5b2..1daa8686 100644
--- a/html/022boolean.cc.html
+++ b/html/023boolean.cc.html
@@ -2,7 +2,7 @@
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
-<title>Mu - 022boolean.cc</title>
+<title>Mu - 023boolean.cc</title>
<meta name="Generator" content="Vim/7.4">
<meta name="plugin-version" content="vim7.4_v1">
<meta name="syntax" content="cpp">
@@ -13,8 +13,8 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
-.cSpecial { color: #008000; }
.traceContains { color: #008000; }
+.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
@@ -36,17 +36,22 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
AND<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"and"</span>] = AND<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"and"</span><span class="Delimiter">,</span> AND<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case AND: <span class="Delimiter">{</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!is_mu_scalar<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'and' requires boolean ingredients, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">goto</span> finish_checking_instruction<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case AND: <span class="Delimiter">{</span>
bool result = <span class="Constant">true</span><span class="Delimiter">;</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'and' requires boolean ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
result = result && ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- <span class="Delimiter">}</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
@@ -81,17 +86,22 @@ recipe main [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
OR<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"or"</span>] = OR<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"or"</span><span class="Delimiter">,</span> OR<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case OR: <span class="Delimiter">{</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!is_mu_scalar<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'and' requires boolean ingredients, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">goto</span> finish_checking_instruction<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case OR: <span class="Delimiter">{</span>
bool result = <span class="Constant">false</span><span class="Delimiter">;</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'or' requires boolean ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
result = result || ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- <span class="Delimiter">}</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
@@ -126,15 +136,25 @@ recipe main [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
NOT<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"not"</span>] = NOT<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"not"</span><span class="Delimiter">,</span> NOT<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case NOT: <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">)</span> > SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'not' cannot have fewer ingredients than products in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!is_mu_scalar<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'not' requires boolean ingredients, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">goto</span> finish_checking_instruction<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case NOT: <span class="Delimiter">{</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">));</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'not' requires boolean ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">goto</span> finish_instruction<span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>!ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
<span class="Delimiter">}</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
diff --git a/html/023jump.cc.html b/html/024jump.cc.html
index 9e239685..8f392805 100644
--- a/html/023jump.cc.html
+++ b/html/024jump.cc.html
@@ -2,7 +2,7 @@
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
-<title>Mu - 023jump.cc</title>
+<title>Mu - 024jump.cc</title>
<meta name="Generator" content="Vim/7.4">
<meta name="plugin-version" content="vim7.4_v1">
<meta name="syntax" content="cpp">
@@ -13,6 +13,7 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.traceContains { color: #008000; }
.traceAbsent { color: #c00000; }
.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
@@ -20,7 +21,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
.Special { color: #ff6060; }
.Identifier { color: #804000; }
.Constant { color: #00a0a0; }
-.traceContains { color: #008000; }
-->
</style>
@@ -46,26 +46,30 @@ recipe main [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
JUMP<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"jump"</span>] = JUMP<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"jump"</span><span class="Delimiter">,</span> JUMP<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case JUMP: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'jump' requires exactly one ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ 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>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'jump' requires exactly one ingredient, but got "</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>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'jump' should be a label or offset, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_scalar<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'jump' should be a label or offset, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="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">:(before "End Primitive Recipe Implementations")</span>
+case JUMP: <span class="Delimiter">{</span>
assert<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>initialized<span class="Delimiter">);</span>
current_step_index<span class="Delimiter">()</span> += ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>+<span class="Constant">1</span><span class="Delimiter">;</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"jumping to instruction "</span> << current_step_index<span class="Delimiter">()</span> << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"jumping to instruction "</span> << current_step_index<span class="Delimiter">()</span> << end<span class="Delimiter">();</span>
<span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Comment">// skip rest of this instruction</span>
<span class="Delimiter">}</span>
<span class="Comment">//: special type to designate jump targets</span>
<span class="Delimiter">:(before "End Mu Types Initialization")</span>
-Type_ordinal[<span class="Constant">"offset"</span>] = <span class="Constant">0</span><span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"offset"</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span>
<span class="Delimiter">:(scenario jump_backward)</span>
recipe main [
@@ -81,28 +85,32 @@ recipe main [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
JUMP_IF<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"jump-if"</span>] = JUMP_IF<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"jump-if"</span><span class="Delimiter">,</span> JUMP_IF<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case JUMP_IF: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'jump-if' requires exactly two ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'jump-if' requires exactly two ingredients, but got "</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>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'jump-if' requires a boolean for its first ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_scalar<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'jump-if' requires a boolean for its first ingredient, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'jump-if' requires a label or offset for its second ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_scalar<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'jump-if' requires a label or offset for its second ingredient, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="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">:(before "End Primitive Recipe Implementations")</span>
+case JUMP_IF: <span class="Delimiter">{</span>
assert<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>initialized<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>!ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"jump-if fell through"</span> << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"jump-if fell through"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
current_step_index<span class="Delimiter">()</span> += ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>+<span class="Constant">1</span><span class="Delimiter">;</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"jumping to instruction "</span> << current_step_index<span class="Delimiter">()</span> << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"jumping to instruction "</span> << current_step_index<span class="Delimiter">()</span> << end<span class="Delimiter">();</span>
<span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Comment">// skip rest of this instruction</span>
<span class="Delimiter">}</span>
@@ -129,28 +137,32 @@ recipe main [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
JUMP_UNLESS<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"jump-unless"</span>] = JUMP_UNLESS<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"jump-unless"</span><span class="Delimiter">,</span> JUMP_UNLESS<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case JUMP_UNLESS: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'jump-unless' requires exactly two ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'jump-unless' requires exactly two ingredients, but got "</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>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'jump-unless' requires a boolean for its first ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_scalar<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'jump-unless' requires a boolean for its first ingredient, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'jump-unless' requires a label or offset for its second ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_scalar<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'jump-unless' requires a label or offset for its second ingredient, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="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">:(before "End Primitive Recipe Implementations")</span>
+case JUMP_UNLESS: <span class="Delimiter">{</span>
assert<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>initialized<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"jump-unless fell through"</span> << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"jump-unless fell through"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
current_step_index<span class="Delimiter">()</span> += ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>+<span class="Constant">1</span><span class="Delimiter">;</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"jumping to instruction "</span> << current_step_index<span class="Delimiter">()</span> << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"jumping to instruction "</span> << current_step_index<span class="Delimiter">()</span> << end<span class="Delimiter">();</span>
<span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Comment">// skip rest of this instruction</span>
<span class="Delimiter">}</span>
diff --git a/html/024compare.cc.html b/html/025compare.cc.html
index 1fb7c4a5..9d4fc286 100644
--- a/html/024compare.cc.html
+++ b/html/025compare.cc.html
@@ -2,7 +2,7 @@
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
-<title>Mu - 024compare.cc</title>
+<title>Mu - 025compare.cc</title>
<meta name="Generator" content="Vim/7.4">
<meta name="plugin-version" content="vim7.4_v1">
<meta name="syntax" content="cpp">
@@ -13,8 +13,8 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
-.cSpecial { color: #008000; }
.traceContains { color: #008000; }
+.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
@@ -36,13 +36,17 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
EQUAL<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"equal"</span>] = EQUAL<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"equal"</span><span class="Delimiter">,</span> EQUAL<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case EQUAL: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> <= <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'equal' needs at least two ingredients to compare in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ 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>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'equal' needs at least two ingredients to compare in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case EQUAL: <span class="Delimiter">{</span>
vector<double>& exemplar = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
bool result = <span class="Constant">true</span><span class="Delimiter">;</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -91,26 +95,29 @@ recipe main [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
GREATER_THAN<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"greater-than"</span>] = GREATER_THAN<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"greater-than"</span><span class="Delimiter">,</span> GREATER_THAN<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case GREATER_THAN: <span class="Delimiter">{</span>
- bool result = <span class="Constant">true</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> <= <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'greater-than' needs at least two ingredients to compare in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ 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>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'greater-than' needs at least two ingredients to compare in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'greater-than' can only compare numbers; got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">goto</span> finish_greater_than<span class="Delimiter">;</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'greater-than' can only compare numbers; got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">goto</span> finish_checking_instruction<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case GREATER_THAN: <span class="Delimiter">{</span>
+ bool result = <span class="Constant">true</span><span class="Delimiter">;</span>
for <span class="Delimiter">(</span>long long int i = <span class="Comment">/**/</span><span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i-<span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> <= ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
result = <span class="Constant">false</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
- finish_greater_than:
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
@@ -147,26 +154,29 @@ recipe main [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
LESSER_THAN<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"lesser-than"</span>] = LESSER_THAN<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"lesser-than"</span><span class="Delimiter">,</span> LESSER_THAN<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case LESSER_THAN: <span class="Delimiter">{</span>
- bool result = <span class="Constant">true</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> <= <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'lesser-than' needs at least two ingredients to compare in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ 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>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'lesser-than' needs at least two ingredients to compare in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'lesser-than' can only compare numbers; got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">goto</span> finish_lesser_than<span class="Delimiter">;</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'lesser-than' can only compare numbers; got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">goto</span> finish_checking_instruction<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case LESSER_THAN: <span class="Delimiter">{</span>
+ bool result = <span class="Constant">true</span><span class="Delimiter">;</span>
for <span class="Delimiter">(</span>long long int i = <span class="Comment">/**/</span><span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i-<span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> >= ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
result = <span class="Constant">false</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
- finish_lesser_than:
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
@@ -203,26 +213,29 @@ recipe main [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
GREATER_OR_EQUAL<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"greater-or-equal"</span>] = GREATER_OR_EQUAL<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"greater-or-equal"</span><span class="Delimiter">,</span> GREATER_OR_EQUAL<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case GREATER_OR_EQUAL: <span class="Delimiter">{</span>
- bool result = <span class="Constant">true</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> <= <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'greater-or-equal' needs at least two ingredients to compare in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ 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>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'greater-or-equal' needs at least two ingredients to compare in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'greater-or-equal' can only compare numbers; got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">goto</span> finish_greater_or_equal<span class="Delimiter">;</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'greater-or-equal' can only compare numbers; got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">goto</span> finish_checking_instruction<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case GREATER_OR_EQUAL: <span class="Delimiter">{</span>
+ bool result = <span class="Constant">true</span><span class="Delimiter">;</span>
for <span class="Delimiter">(</span>long long int i = <span class="Comment">/**/</span><span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i-<span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> < ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
result = <span class="Constant">false</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
- finish_greater_or_equal:
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
@@ -267,26 +280,29 @@ recipe main [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
LESSER_OR_EQUAL<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"lesser-or-equal"</span>] = LESSER_OR_EQUAL<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"lesser-or-equal"</span><span class="Delimiter">,</span> LESSER_OR_EQUAL<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case LESSER_OR_EQUAL: <span class="Delimiter">{</span>
- bool result = <span class="Constant">true</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> <= <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'lesser-or-equal' needs at least two ingredients to compare in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ 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>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'lesser-or-equal' needs at least two ingredients to compare in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'lesser-or-equal' can only compare numbers; got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">goto</span> finish_lesser_or_equal<span class="Delimiter">;</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'lesser-or-equal' can only compare numbers; got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">goto</span> finish_checking_instruction<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case LESSER_OR_EQUAL: <span class="Delimiter">{</span>
+ bool result = <span class="Constant">true</span><span class="Delimiter">;</span>
for <span class="Delimiter">(</span>long long int i = <span class="Comment">/**/</span><span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i-<span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> > ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
result = <span class="Constant">false</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
- finish_lesser_or_equal:
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
diff --git a/html/029tools.cc.html b/html/029tools.cc.html
index 77e709c2..018e0f01 100644
--- a/html/029tools.cc.html
+++ b/html/029tools.cc.html
@@ -13,12 +13,12 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
-.cSpecial { color: #008000; }
+.traceContains { color: #008000; }
.SalientComment { color: #00ffff; }
-.Special { color: #ff6060; }
+.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
-.traceContains { color: #008000; }
+.Special { color: #ff6060; }
.Identifier { color: #804000; }
.Constant { color: #00a0a0; }
-->
@@ -43,22 +43,26 @@ recipe main [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
TRACE<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"trace"</span>] = TRACE<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"trace"</span><span class="Delimiter">,</span> TRACE<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case TRACE: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">)</span> < <span class="Constant">3</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'trace' takes three or more ingredients rather than '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> < <span class="Constant">3</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'trace' takes three or more ingredients rather than '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'trace' should be a number (depth), but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'trace' should be a number (depth), but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- long long int depth = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>!is_literal_string<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": second ingredient of 'trace' should be a literal string (label), but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_literal_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"second ingredient of 'trace' should be a literal string (label), but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="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">:(before "End Primitive Recipe Implementations")</span>
+case TRACE: <span class="Delimiter">{</span>
+ long long int depth = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
string label = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">;</span>
ostringstream out<span class="Delimiter">;</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">2</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -73,14 +77,18 @@ case TRACE: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
STASH<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"stash"</span>] = STASH<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"stash"</span><span class="Delimiter">,</span> STASH<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case STASH: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case STASH: <span class="Delimiter">{</span>
ostringstream out<span class="Delimiter">;</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
out << print_mu<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
<span class="Delimiter">}</span>
- trace<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">,</span> <span class="Constant">"app"</span><span class="Delimiter">)</span> << out<span class="Delimiter">.</span>str<span class="Delimiter">()</span> << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">,</span> <span class="Constant">"app"</span><span class="Delimiter">)</span> << out<span class="Delimiter">.</span>str<span class="Delimiter">()</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -110,63 +118,53 @@ string print_mu<span class="Delimiter">(</span>const reagent& r<span class="
<span class="Comment">// End print Special-cases(reagent r, data)</span>
ostringstream out<span class="Delimiter">;</span>
for <span class="Delimiter">(</span>long long i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>data<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- out << data<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> << <span class="Constant">' '</span><span class="Delimiter">;</span>
+ out << no_scientific<span class="Delimiter">(</span>data<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> << <span class="Constant">' '</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
-HIDE_WARNINGS<span class="Delimiter">,</span>
+HIDE_ERRORS<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"hide-warnings"</span>] = HIDE_WARNINGS<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"hide-errors"</span><span class="Delimiter">,</span> HIDE_ERRORS<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case HIDE_ERRORS: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
-case HIDE_WARNINGS: <span class="Delimiter">{</span>
+case HIDE_ERRORS: <span class="Delimiter">{</span>
+ Hide_errors = <span class="Constant">true</span><span class="Delimiter">;</span>
Hide_warnings = <span class="Constant">true</span><span class="Delimiter">;</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
-SHOW_WARNINGS<span class="Delimiter">,</span>
+SHOW_ERRORS<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"show-warnings"</span>] = SHOW_WARNINGS<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
-case SHOW_WARNINGS: <span class="Delimiter">{</span>
- Hide_warnings = <span class="Constant">false</span><span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"show-errors"</span><span class="Delimiter">,</span> SHOW_ERRORS<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case SHOW_ERRORS: <span class="Delimiter">{</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
-
-<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
-_START_TRACING<span class="Delimiter">,</span>
-<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"$start-tracing"</span>] = _START_TRACING<span class="Delimiter">;</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
-case _START_TRACING: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span>
- Trace_stream<span class="Delimiter">-></span>dump_layer = <span class="Constant">"all"</span><span class="Delimiter">;</span>
- else
- Trace_stream<span class="Delimiter">-></span>dump_layer = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">;</span>
+case SHOW_ERRORS: <span class="Delimiter">{</span>
+ Hide_errors = <span class="Constant">false</span><span class="Delimiter">;</span>
+ Hide_warnings = <span class="Constant">false</span><span class="Delimiter">;</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
-_STOP_TRACING<span class="Delimiter">,</span>
+TRACE_UNTIL<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"$stop-tracing"</span>] = _STOP_TRACING<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
-case _STOP_TRACING: <span class="Delimiter">{</span>
- Trace_stream<span class="Delimiter">-></span>dump_layer = <span class="Constant">""</span><span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"trace-until"</span><span class="Delimiter">,</span> TRACE_UNTIL<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case TRACE_UNTIL: <span class="Delimiter">{</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
-
-<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
-_CLOSE_TRACE<span class="Delimiter">,</span>
-<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"$close-trace"</span>] = _CLOSE_TRACE<span class="Delimiter">;</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
-case _CLOSE_TRACE: <span class="Delimiter">{</span>
+case TRACE_UNTIL: <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- delete Trace_stream<span class="Delimiter">;</span>
- Trace_stream = <span class="Constant">NULL</span><span class="Delimiter">;</span>
+ Trace_stream<span class="Delimiter">-></span>collect_depth = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
<span class="Delimiter">}</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -174,7 +172,11 @@ case _CLOSE_TRACE: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
_DUMP_TRACE<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"$dump-trace"</span>] = _DUMP_TRACE<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"$dump-trace"</span><span class="Delimiter">,</span> _DUMP_TRACE<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case _DUMP_TRACE: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case _DUMP_TRACE: <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
@@ -189,42 +191,68 @@ case _DUMP_TRACE: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
_CLEAR_TRACE<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"$clear-trace"</span>] = _CLEAR_TRACE<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"$clear-trace"</span><span class="Delimiter">,</span> _CLEAR_TRACE<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case _CLEAR_TRACE: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case _CLEAR_TRACE: <span class="Delimiter">{</span>
- CLEAR_TRACE<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">)</span> Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
+_SAVE_TRACE<span class="Delimiter">,</span>
+<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"$save-trace"</span><span class="Delimiter">,</span> _SAVE_TRACE<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case _SAVE_TRACE: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case _SAVE_TRACE: <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!Trace_file<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+ ofstream fout<span class="Delimiter">((</span>Trace_dir+Trace_file<span class="Delimiter">).</span>c_str<span class="Delimiter">());</span>
+ fout << Trace_stream<span class="Delimiter">-></span>readable_contents<span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">);</span>
+ fout<span class="Delimiter">.</span>close<span class="Delimiter">();</span>
+ <span class="Delimiter">}</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Comment">//: assert: perform sanity checks at runtime</span>
<span class="Delimiter">:(scenario assert)</span>
-<span class="Special">% Hide_warnings = true; // '%' lines insert arbitrary C code into tests before calling 'run' with the lines below. Must be immediately after :(scenario) line.</span>
+<span class="Special">% Hide_errors = true; // '%' lines insert arbitrary C code into tests before calling 'run' with the lines below. Must be immediately after :(scenario) line.</span>
recipe main [
assert <span class="Constant">0</span><span class="Delimiter">,</span> [this is an assert in mu]
]
-<span class="traceContains">+warn: this is an assert in mu</span>
+<span class="traceContains">+error: this is an assert in mu</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
ASSERT<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"assert"</span>] = ASSERT<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"assert"</span><span class="Delimiter">,</span> ASSERT<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case ASSERT: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'assert' takes exactly two ingredients rather than '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'assert' takes exactly two ingredients rather than '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'assert' requires a boolean for its first ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_scalar<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'assert' requires a boolean for its first ingredient, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'assert' requires a literal string for its second ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_literal_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'assert' requires a literal string for its second ingredient, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="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">:(before "End Primitive Recipe Implementations")</span>
+case ASSERT: <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>!ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
- raise << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -234,12 +262,16 @@ case ASSERT: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
_PRINT<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"$print"</span>] = _PRINT<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"$print"</span><span class="Delimiter">,</span> _PRINT<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case _PRINT: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case _PRINT: <span class="Delimiter">{</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"$print: "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"$print: "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name << end<span class="Delimiter">();</span>
if <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> <span class="Constant">"newline"</span><span class="Delimiter">))</span>
cout << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
else
@@ -247,9 +279,9 @@ case _PRINT: <span class="Delimiter">{</span>
<span class="Delimiter">}</span>
else <span class="Delimiter">{</span>
for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"$print: "</span> << ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"$print: "</span> << ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
if <span class="Delimiter">(</span>j > <span class="Constant">0</span><span class="Delimiter">)</span> cout << <span class="Constant">" "</span><span class="Delimiter">;</span>
- cout << ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span>j<span class="Delimiter">);</span>
+ cout << no_scientific<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span>j<span class="Delimiter">));</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
@@ -259,7 +291,11 @@ case _PRINT: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
_EXIT<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"$exit"</span>] = _EXIT<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"$exit"</span><span class="Delimiter">,</span> _EXIT<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case _EXIT: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case _EXIT: <span class="Delimiter">{</span>
exit<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
@@ -269,25 +305,31 @@ case _EXIT: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
_SYSTEM<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"$system"</span>] = _SYSTEM<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"$system"</span><span class="Delimiter">,</span> _SYSTEM<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case _SYSTEM: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": '$system' requires exactly one ingredient, but got none</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ 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>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'$system' requires exactly one ingredient, but got none</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case _SYSTEM: <span class="Delimiter">{</span>
int status = system<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">.</span>c_str<span class="Delimiter">());</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>status<span class="Delimiter">);</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
-<span class="SalientComment">//:: helpers for debugging</span>
-
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
_DUMP_MEMORY<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"$dump-memory"</span>] = _DUMP_MEMORY<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"$dump-memory"</span><span class="Delimiter">,</span> _DUMP_MEMORY<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case _DUMP_MEMORY: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case _DUMP_MEMORY: <span class="Delimiter">{</span>
dump_memory<span class="Delimiter">();</span>
diff --git a/html/030container.cc.html b/html/030container.cc.html
index 7d0d4a26..403c6a60 100644
--- a/html/030container.cc.html
+++ b/html/030container.cc.html
@@ -13,15 +13,15 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.traceContains { color: #008000; }
.SalientComment { color: #00ffff; }
-.traceAbsent { color: #c00000; }
.cSpecial { color: #008000; }
+.traceAbsent { color: #c00000; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
.Identifier { color: #804000; }
.Constant { color: #00a0a0; }
-.traceContains { color: #008000; }
-->
</style>
@@ -37,21 +37,21 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">:(before "End Mu Types Initialization")</span>
<span class="Comment">//: We'll use this container as a running example, with two number elements.</span>
-type_ordinal point = Type_ordinal[<span class="Constant">"point"</span>] = Next_type_ordinal++<span class="Delimiter">;</span>
-Type[point]<span class="Delimiter">.</span>size = <span class="Constant">2</span><span class="Delimiter">;</span>
-Type[point]<span class="Delimiter">.</span>kind = container<span class="Delimiter">;</span>
-Type[point]<span class="Delimiter">.</span>name = <span class="Constant">"point"</span><span class="Delimiter">;</span>
-vector<type_ordinal> i<span class="Delimiter">;</span>
-i<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>number<span class="Delimiter">);</span>
-Type[point]<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
-Type[point]<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+type_ordinal point = put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"point"</span><span class="Delimiter">,</span> Next_type_ordinal++<span class="Delimiter">);</span>
+get_or_insert<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> point<span class="Delimiter">).</span>size = <span class="Constant">2</span><span class="Delimiter">;</span>
+get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> point<span class="Delimiter">).</span>kind = CONTAINER<span class="Delimiter">;</span>
+get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> point<span class="Delimiter">).</span>name = <span class="Constant">"point"</span><span class="Delimiter">;</span>
+get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> point<span class="Delimiter">).</span>elements<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new type_tree<span class="Delimiter">(</span>number<span class="Delimiter">));</span>
+get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> point<span class="Delimiter">).</span>element_names<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">"x"</span><span class="Delimiter">);</span>
+get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> point<span class="Delimiter">).</span>elements<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new type_tree<span class="Delimiter">(</span>number<span class="Delimiter">));</span>
+get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> point<span class="Delimiter">).</span>element_names<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">"y"</span><span class="Delimiter">);</span>
<span class="Comment">//: Containers can be copied around with a single instruction just like</span>
<span class="Comment">//: numbers, no matter how large they are.</span>
<span class="Comment">//: Tests in this layer often explicitly setup memory before reading it as a</span>
<span class="Comment">//: container. Don't do this in general. I'm tagging exceptions with /raw to</span>
-<span class="Comment">//: avoid warnings.</span>
+<span class="Comment">//: avoid errors.</span>
<span class="Delimiter">:(scenario copy_multiple_locations)</span>
recipe main [
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
@@ -61,27 +61,25 @@ recipe main [
<span class="traceContains">+mem: storing 34 in location 3</span>
<span class="traceContains">+mem: storing 35 in location 4</span>
-<span class="Comment">//: trying to copy to a differently-sized destination will fail</span>
+<span class="Comment">//: trying to copy to a differently-typed destination will fail</span>
<span class="Delimiter">:(scenario copy_checks_size)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
<span class="Constant">2</span>:point<span class="Special"> <- </span>copy <span class="Constant">1</span>:number
]
-<span class="traceContains">+warn: main: size mismatch in storing to 2:point (2 vs 1) at '2:point <- copy 1:number'</span>
+<span class="traceContains">+error: main: can't copy 1:number to 2:point; types don't match</span>
<span class="Delimiter">:(before "End Mu Types Initialization")</span>
<span class="Comment">// A more complex container, containing another container as one of its</span>
<span class="Comment">// elements.</span>
-type_ordinal point_number = Type_ordinal[<span class="Constant">"point-number"</span>] = Next_type_ordinal++<span class="Delimiter">;</span>
-Type[point_number]<span class="Delimiter">.</span>size = <span class="Constant">2</span><span class="Delimiter">;</span>
-Type[point_number]<span class="Delimiter">.</span>kind = container<span class="Delimiter">;</span>
-Type[point_number]<span class="Delimiter">.</span>name = <span class="Constant">"point-number"</span><span class="Delimiter">;</span>
-vector<type_ordinal> p2<span class="Delimiter">;</span>
-p2<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>point<span class="Delimiter">);</span>
-Type[point_number]<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>p2<span class="Delimiter">);</span>
-vector<type_ordinal> i2<span class="Delimiter">;</span>
-i2<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>number<span class="Delimiter">);</span>
-Type[point_number]<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>i2<span class="Delimiter">);</span>
+type_ordinal point_number = put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"point-number"</span><span class="Delimiter">,</span> Next_type_ordinal++<span class="Delimiter">);</span>
+get_or_insert<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> point_number<span class="Delimiter">).</span>size = <span class="Constant">2</span><span class="Delimiter">;</span>
+get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> point_number<span class="Delimiter">).</span>kind = CONTAINER<span class="Delimiter">;</span>
+get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> point_number<span class="Delimiter">).</span>name = <span class="Constant">"point-number"</span><span class="Delimiter">;</span>
+get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> point_number<span class="Delimiter">).</span>elements<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new type_tree<span class="Delimiter">(</span>point<span class="Delimiter">));</span>
+get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> point_number<span class="Delimiter">).</span>element_names<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">"xy"</span><span class="Delimiter">);</span>
+get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> point_number<span class="Delimiter">).</span>elements<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new type_tree<span class="Delimiter">(</span>number<span class="Delimiter">));</span>
+get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> point_number<span class="Delimiter">).</span>element_names<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">"z"</span><span class="Delimiter">);</span>
<span class="Delimiter">:(scenario copy_handles_nested_container_elements)</span>
recipe main [
@@ -119,17 +117,26 @@ recipe main [
]
<span class="traceContains">+mem: storing 0 in location 7</span>
-<span class="Delimiter">:(before "End size_of(types) Cases")</span>
-type_info t = Type[types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>]<span class="Delimiter">;</span>
-if <span class="Delimiter">(</span>t<span class="Delimiter">.</span>kind == container<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+<span class="Delimiter">:(before "End size_of(type) Cases")</span>
+if <span class="Delimiter">(</span>type<span class="Delimiter">-></span>value == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ <span class="Comment">// error value, but we'll raise it elsewhere</span>
+ <span class="Identifier">return</span> <span class="Constant">1</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+if <span class="Delimiter">(</span>type<span class="Delimiter">-></span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ assert<span class="Delimiter">(</span>!type<span class="Delimiter">-></span>left && !type<span class="Delimiter">-></span>right<span class="Delimiter">);</span>
+ <span class="Identifier">return</span> <span class="Constant">1</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+type_info t = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">);</span>
+if <span class="Delimiter">(</span>t<span class="Delimiter">.</span>kind == CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Comment">// size of a container is the sum of the sizes of its elements</span>
long long int result = <span class="Constant">0</span><span class="Delimiter">;</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>t<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Comment">// todo: strengthen assertion to disallow mutual type recursion</span>
- if <span class="Delimiter">(</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == t<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"container "</span> << t<span class="Delimiter">.</span>name << <span class="Constant">" can't include itself as a member</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>t<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>value == type<span class="Delimiter">-></span>value<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << <span class="Constant">"container "</span> << t<span class="Delimiter">.</span>name << <span class="Constant">" can't include itself as a member</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+ <span class="Comment">// End size_of(type) Container Cases</span>
result += size_of<span class="Delimiter">(</span>t<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
<span class="Delimiter">}</span>
<span class="Identifier">return</span> result<span class="Delimiter">;</span>
@@ -156,48 +163,81 @@ recipe main [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
GET<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"get"</span>] = GET<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"get"</span><span class="Delimiter">,</span> GET<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case GET: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'get' expects exactly 2 ingredients in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'get' expects exactly 2 ingredients in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- reagent base = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- long long int base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>base_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": tried to access location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ reagent base = inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> <span class="Comment">// new copy for every invocation</span>
+ <span class="Comment">// Update GET base in Check</span>
+ if <span class="Delimiter">(</span>!base<span class="Delimiter">.</span>type || !base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value || get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>kind != CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'get' should be a container, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ type_ordinal base_type = base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">;</span>
+ reagent offset = inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>offset<span class="Delimiter">)</span> || !is_mu_scalar<span class="Delimiter">(</span>offset<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"second ingredient of 'get' should have type 'offset', but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ long long int offset_value = <span class="Constant">0</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>offset<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Comment">// later layers permit non-integer offsets</span>
+ offset_value = to_integer<span class="Delimiter">(</span>offset<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
+ else
+ offset_value = offset<span class="Delimiter">.</span>value<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>offset_value < <span class="Constant">0</span> || offset_value >= SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>elements<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"invalid offset "</span> << offset_value << <span class="Constant">" for "</span> << get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> || Type[base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>]<span class="Delimiter">.</span>kind != container<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'get' should be a container, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ reagent product = inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ <span class="Comment">// Update GET product in Check</span>
+ const reagent element = element_type<span class="Delimiter">(</span>base<span class="Delimiter">,</span> offset_value<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'get' "</span> << offset<span class="Delimiter">.</span>original_string << <span class="Constant">" ("</span> << offset_value << <span class="Constant">") on "</span> << get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name << <span class="Constant">" can't be saved in "</span> << product<span class="Delimiter">.</span>original_string << <span class="Constant">"; type should be "</span> << debug_string<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="Constant">" but is "</span> << debug_string<span class="Delimiter">(</span>product<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- type_ordinal base_type = base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": second ingredient of 'get' should have type 'offset', but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case GET: <span class="Delimiter">{</span>
+ reagent base = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ <span class="Comment">// Update GET base in Run</span>
+ long long int base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>base_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"tried to access location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span>
+ type_ordinal base_type = base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">;</span>
long long int offset = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>offset < <span class="Constant">0</span> || offset >= SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>elements<span class="Delimiter">))</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Comment">// copied from Check above</span>
long long int src = base_address<span class="Delimiter">;</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < offset<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- src += size_of<span class="Delimiter">(</span>Type[base_type]<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
+ <span class="Comment">// End GET field Cases</span>
+ src += size_of<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
<span class="Delimiter">}</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"address to copy is "</span> << src << end<span class="Delimiter">();</span>
- if <span class="Delimiter">(</span>offset < <span class="Constant">0</span> || offset >= SIZE<span class="Delimiter">(</span>Type[base_type]<span class="Delimiter">.</span>elements<span class="Delimiter">))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": invalid offset "</span> << offset << <span class="Constant">" for "</span> << Type[base_type]<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- type_ordinal src_type = Type[base_type]<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>offset<span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"its type is "</span> << Type[src_type]<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span>
- reagent tmp<span class="Delimiter">;</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"address to copy is "</span> << src << end<span class="Delimiter">();</span>
+ reagent tmp = element_type<span class="Delimiter">(</span>base<span class="Delimiter">,</span> offset<span class="Delimiter">);</span>
tmp<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>src<span class="Delimiter">);</span>
- tmp<span class="Delimiter">.</span>types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>src_type<span class="Delimiter">);</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"its type is "</span> << debug_string<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>read_memory<span class="Delimiter">(</span>tmp<span class="Delimiter">));</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+<span class="Delimiter">:(code)</span>
+const reagent element_type<span class="Delimiter">(</span>const reagent& canonized_base<span class="Delimiter">,</span> long long int offset_value<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ assert<span class="Delimiter">(</span>offset_value >= <span class="Constant">0</span><span class="Delimiter">);</span>
+ assert<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> canonized_base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">));</span>
+ assert<span class="Delimiter">(</span>!get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> canonized_base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>name<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
+ const type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> canonized_base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">);</span>
+ assert<span class="Delimiter">(</span>info<span class="Delimiter">.</span>kind == CONTAINER<span class="Delimiter">);</span>
+ reagent element<span class="Delimiter">;</span>
+ element<span class="Delimiter">.</span>type = new type_tree<span class="Delimiter">(</span>*info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>offset_value<span class="Delimiter">));</span>
+ <span class="Comment">// End element_type Special-cases</span>
+ <span class="Identifier">return</span> element<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
<span class="Delimiter">:(scenario get_handles_nested_container_elements)</span>
recipe main [
<span class="Constant">12</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
@@ -207,92 +247,143 @@ recipe main [
]
<span class="traceContains">+mem: storing 36 in location 15</span>
-<span class="SalientComment">//:: To write to elements of containers, you need their address.</span>
-
-<span class="Delimiter">:(scenario get_address)</span>
+<span class="Delimiter">:(scenario get_out_of_bounds)</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
<span class="Constant">12</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
<span class="Constant">13</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span>
- <span class="Constant">15</span>:address:number<span class="Special"> <- </span>get-address <span class="Constant">12</span>:point/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">1</span>:offset <span class="Comment"># unsafe</span>
+ <span class="Constant">14</span>:number<span class="Special"> <- </span>copy <span class="Constant">36</span>
+ get <span class="Constant">12</span>:point-number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">2</span>:offset <span class="Comment"># point-number occupies 3 locations but has only 2 fields; out of bounds</span>
]
-<span class="traceContains">+mem: storing 13 in location 15</span>
+<span class="traceContains">+error: main: invalid offset 2 for point-number</span>
-<span class="Delimiter">:(scenario get_out_of_bounds)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Delimiter">:(scenario get_out_of_bounds_2)</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
<span class="Constant">12</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
<span class="Constant">13</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span>
<span class="Constant">14</span>:number<span class="Special"> <- </span>copy <span class="Constant">36</span>
- get <span class="Constant">12</span>:point-number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">2</span>:offset <span class="Comment"># point-number occupies 3 locations but has only 2 fields; out of bounds</span>
+ get <span class="Constant">12</span>:point-number/<span class="Special">raw</span><span class="Delimiter">,</span> -<span class="Constant">1</span>:offset
]
-<span class="traceContains">+warn: main: invalid offset 2 for point-number</span>
+<span class="traceContains">+error: main: invalid offset -1 for point-number</span>
-<span class="Delimiter">:(scenario get_out_of_bounds_2)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Delimiter">:(scenario get_product_type_mismatch)</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
<span class="Constant">12</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
<span class="Constant">13</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span>
<span class="Constant">14</span>:number<span class="Special"> <- </span>copy <span class="Constant">36</span>
- get <span class="Constant">12</span>:point-number/<span class="Special">raw</span><span class="Delimiter">,</span> -<span class="Constant">1</span>:offset
+ <span class="Constant">15</span>:address:number<span class="Special"> <- </span>get <span class="Constant">12</span>:point-number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">1</span>:offset
+]
+<span class="traceContains">+error: main: 'get' 1:offset (1) on point-number can't be saved in 15:address:number; type should be number but is <address : <number : <>>></span>
+
+<span class="SalientComment">//:: To write to elements of containers, you need their address.</span>
+
+<span class="Delimiter">:(scenario get_address)</span>
+recipe main [
+ <span class="Constant">12</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
+ <span class="Constant">13</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span>
+ <span class="Constant">15</span>:address:number<span class="Special"> <- </span>get-address <span class="Constant">12</span>:point/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">1</span>:offset <span class="Comment"># unsafe</span>
]
-<span class="traceContains">+warn: main: invalid offset -1 for point-number</span>
+<span class="traceContains">+mem: storing 13 in location 15</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
GET_ADDRESS<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"get-address"</span>] = GET_ADDRESS<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"get-address"</span><span class="Delimiter">,</span> GET_ADDRESS<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case GET_ADDRESS: <span class="Delimiter">{</span>
- reagent base = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- long long int base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>base_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": tried to access location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'get-address' expects exactly 2 ingredients in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> || Type[base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>]<span class="Delimiter">.</span>kind != container<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'get-address' should be a container, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ reagent base = inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ <span class="Comment">// Update GET_ADDRESS base in Check</span>
+ if <span class="Delimiter">(</span>!base<span class="Delimiter">.</span>type || get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>kind != CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'get-address' should be a container, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- type_ordinal base_type = base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": second ingredient of 'get-address' should have type 'offset', but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ type_ordinal base_type = base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">;</span>
+ reagent offset = inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>offset<span class="Delimiter">)</span> || !is_mu_scalar<span class="Delimiter">(</span>offset<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"second ingredient of 'get' should have type 'offset', but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span>
- long long int offset = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>offset < <span class="Constant">0</span> || offset >= SIZE<span class="Delimiter">(</span>Type[base_type]<span class="Delimiter">.</span>elements<span class="Delimiter">))</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"invalid offset "</span> << offset << <span class="Constant">" for "</span> << Type[base_type]<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ long long int offset_value = <span class="Constant">0</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>offset<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Comment">// later layers permit non-integer offsets</span>
+ offset_value = to_integer<span class="Delimiter">(</span>offset<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>offset_value < <span class="Constant">0</span> || offset_value >= SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>elements<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"invalid offset "</span> << offset_value << <span class="Constant">" for "</span> << get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ else <span class="Delimiter">{</span>
+ offset_value = offset<span class="Delimiter">.</span>value<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>
+ <span class="Comment">// Update GET_ADDRESS product in Check</span>
+ <span class="Comment">// same type as for GET..</span>
+ reagent element = element_type<span class="Delimiter">(</span>base<span class="Delimiter">,</span> offset_value<span class="Delimiter">);</span>
+ <span class="Comment">// ..except for an address at the start</span>
+ element<span class="Delimiter">.</span>type = new type_tree<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">),</span> element<span class="Delimiter">.</span>type<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'get-address' "</span> << offset<span class="Delimiter">.</span>original_string << <span class="Constant">" ("</span> << offset_value << <span class="Constant">") on "</span> << get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name << <span class="Constant">" can't be saved in "</span> << product<span class="Delimiter">.</span>original_string << <span class="Constant">"; type should be "</span> << debug_string<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <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">:(before "End Primitive Recipe Implementations")</span>
+case GET_ADDRESS: <span class="Delimiter">{</span>
+ reagent base = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ <span class="Comment">// Update GET_ADDRESS base in Run</span>
+ long long int base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>base_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"tried to access location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+ type_ordinal base_type = base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">;</span>
+ long long int offset = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>offset < <span class="Constant">0</span> || offset >= SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>elements<span class="Delimiter">))</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Comment">// copied from Check above</span>
long long int result = base_address<span class="Delimiter">;</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < offset<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- result += size_of<span class="Delimiter">(</span>Type[base_type]<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
+ <span class="Comment">// End GET_ADDRESS field Cases</span>
+ result += size_of<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
<span class="Delimiter">}</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"address to copy is "</span> << result << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"address to copy is "</span> << result << end<span class="Delimiter">();</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(scenario get_address_out_of_bounds)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
<span class="Constant">12</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
<span class="Constant">13</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span>
<span class="Constant">14</span>:number<span class="Special"> <- </span>copy <span class="Constant">36</span>
get-address <span class="Constant">12</span>:point-number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">2</span>:offset <span class="Comment"># point-number occupies 3 locations but has only 2 fields; out of bounds</span>
]
-<span class="traceContains">+warn: invalid offset 2 for point-number</span>
+<span class="traceContains">+error: main: invalid offset 2 for point-number</span>
<span class="Delimiter">:(scenario get_address_out_of_bounds_2)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
<span class="Constant">12</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
<span class="Constant">13</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span>
<span class="Constant">14</span>:number<span class="Special"> <- </span>copy <span class="Constant">36</span>
get-address <span class="Constant">12</span>:point-number/<span class="Special">raw</span><span class="Delimiter">,</span> -<span class="Constant">1</span>:offset
]
-<span class="traceContains">+warn: invalid offset -1 for point-number</span>
+<span class="traceContains">+error: main: invalid offset -1 for point-number</span>
+
+<span class="Delimiter">:(scenario get_address_product_type_mismatch)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+ <span class="Constant">12</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
+ <span class="Constant">13</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span>
+ <span class="Constant">14</span>:number<span class="Special"> <- </span>copy <span class="Constant">36</span>
+ <span class="Constant">15</span>:number<span class="Special"> <- </span>get-address <span class="Constant">12</span>:point-number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">1</span>:offset
+]
+<span class="traceContains">+error: main: 'get-address' 1:offset (1) on point-number can't be saved in 15:number; type should be <address : <number : <>>></span>
<span class="SalientComment">//:: Allow containers to be defined in mu code.</span>
@@ -302,11 +393,11 @@ container foo [
x:number
y:number
]
-<span class="traceContains">+parse: reading container foo</span>
-<span class="traceContains">+parse: element name: x</span>
-<span class="traceContains">+parse: type: 1</span>
-<span class="traceContains">+parse: element name: y</span>
-<span class="traceContains">+parse: type: 1</span>
+<span class="traceContains">+parse: --- defining container foo</span>
+<span class="traceContains">+parse: element name: x</span>
+<span class="traceContains">+parse: type: 1</span>
+<span class="traceContains">+parse: element name: y</span>
+<span class="traceContains">+parse: type: 1</span>
<span class="Delimiter">:(scenario container_use_before_definition)</span>
container foo [
@@ -318,57 +409,66 @@ container bar [
x:number
y:number
]
-<span class="traceContains">+parse: reading container foo</span>
+<span class="traceContains">+parse: --- defining container foo</span>
<span class="traceContains">+parse: type number: 1000</span>
<span class="traceContains">+parse: element name: x</span>
<span class="traceContains">+parse: type: 1</span>
<span class="traceContains">+parse: element name: y</span>
<span class="traceContains">+parse: type: 1001</span>
-<span class="traceContains">+parse: reading container bar</span>
+<span class="traceContains">+parse: --- defining container bar</span>
<span class="traceContains">+parse: type number: 1001</span>
<span class="Delimiter">:(before "End Command Handlers")</span>
else if <span class="Delimiter">(</span>command == <span class="Constant">"container"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- insert_container<span class="Delimiter">(</span>command<span class="Delimiter">,</span> container<span class="Delimiter">,</span> in<span class="Delimiter">);</span>
+ insert_container<span class="Delimiter">(</span>command<span class="Delimiter">,</span> CONTAINER<span class="Delimiter">,</span> in<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(code)</span>
void insert_container<span class="Delimiter">(</span>const string& command<span class="Delimiter">,</span> kind_of_type kind<span class="Delimiter">,</span> istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
string name = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
- trace<span class="Delimiter">(</span><span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">"reading "</span> << command << <span class="Constant">' '</span> << name << end<span class="Delimiter">();</span>
- if <span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">.</span>find<span class="Delimiter">(</span>name<span class="Delimiter">)</span> == Type_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">()</span>
- || Type_ordinal[name] == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- Type_ordinal[name] = Next_type_ordinal++<span class="Delimiter">;</span>
+ <span class="Comment">// End container Name Refinements</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">"--- defining "</span> << command << <span class="Constant">' '</span> << name << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">)</span>
+ || get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">,</span> Next_type_ordinal++<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
- trace<span class="Delimiter">(</span><span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">"type number: "</span> << Type_ordinal[name] << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">"type number: "</span> << get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
skip_bracket<span class="Delimiter">(</span>in<span class="Delimiter">,</span> <span class="Constant">"'container' must begin with '['"</span><span class="Delimiter">);</span>
- type_info& t = Type[Type_ordinal[name]]<span class="Delimiter">;</span>
- recently_added_types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>Type_ordinal[name]<span class="Delimiter">);</span>
- t<span class="Delimiter">.</span>name = name<span class="Delimiter">;</span>
- t<span class="Delimiter">.</span>kind = kind<span class="Delimiter">;</span>
+ type_info& info = get_or_insert<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">));</span>
+ recently_added_types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">));</span>
+ info<span class="Delimiter">.</span>name = name<span class="Delimiter">;</span>
+ info<span class="Delimiter">.</span>kind = kind<span class="Delimiter">;</span>
while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
string element = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>element == <span class="Constant">"]"</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Comment">// End insert_container Special Definitions(element)</span>
istringstream inner<span class="Delimiter">(</span>element<span class="Delimiter">);</span>
- t<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>slurp_until<span class="Delimiter">(</span>inner<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">));</span>
- trace<span class="Delimiter">(</span><span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">" element name: "</span> << t<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>back<span class="Delimiter">()</span> << end<span class="Delimiter">();</span>
- vector<type_ordinal> types<span class="Delimiter">;</span>
- while <span class="Delimiter">(</span>!inner<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+ info<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>slurp_until<span class="Delimiter">(</span>inner<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">));</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">" element name: "</span> << info<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>back<span class="Delimiter">()</span> << end<span class="Delimiter">();</span>
+ type_tree* new_type = <span class="Constant">NULL</span><span class="Delimiter">;</span>
+ for <span class="Delimiter">(</span>type_tree** curr_type = &new_type<span class="Delimiter">;</span> !inner<span class="Delimiter">.</span>eof<span class="Delimiter">();</span> curr_type = &<span class="Delimiter">(</span>*curr_type<span class="Delimiter">)-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span>
string type_name = slurp_until<span class="Delimiter">(</span>inner<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">.</span>find<span class="Delimiter">(</span>type_name<span class="Delimiter">)</span> == Type_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">()</span>
+ <span class="Comment">// End insert_container Special Uses(type_name)</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type_name<span class="Delimiter">)</span>
<span class="Comment">// types can contain integers, like for array sizes</span>
&& !is_integer<span class="Delimiter">(</span>type_name<span class="Delimiter">))</span> <span class="Delimiter">{</span>
- Type_ordinal[type_name] = Next_type_ordinal++<span class="Delimiter">;</span>
+ put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type_name<span class="Delimiter">,</span> Next_type_ordinal++<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
- types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>Type_ordinal[type_name]<span class="Delimiter">);</span>
- trace<span class="Delimiter">(</span><span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">" type: "</span> << types<span class="Delimiter">.</span>back<span class="Delimiter">()</span> << end<span class="Delimiter">();</span>
+ *curr_type = new type_tree<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type_name<span class="Delimiter">));</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">" type: "</span> << get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type_name<span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
- t<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>types<span class="Delimiter">);</span>
+ info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_type<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
- assert<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>t<span class="Delimiter">.</span>elements<span class="Delimiter">)</span> == SIZE<span class="Delimiter">(</span>t<span class="Delimiter">.</span>element_names<span class="Delimiter">));</span>
- t<span class="Delimiter">.</span>size = SIZE<span class="Delimiter">(</span>t<span class="Delimiter">.</span>elements<span class="Delimiter">);</span>
+ assert<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">)</span> == SIZE<span class="Delimiter">(</span>info<span class="Delimiter">.</span>element_names<span class="Delimiter">));</span>
+ info<span class="Delimiter">.</span>size = SIZE<span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+void skip_bracket<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> string message<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">()</span> != <span class="Constant">'['</span><span class="Delimiter">)</span>
+ raise_error << message << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(scenarios run)</span>
@@ -397,7 +497,12 @@ vector<type_ordinal> recently_added_types<span class="Delimiter">;</span>
recently_added_types<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
<span class="Delimiter">:(before "End Setup")</span> <span class="Comment">//: for tests</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>recently_added_types<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- Type_ordinal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>Type[recently_added_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span>]<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> recently_added_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ Type_ordinal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> recently_added_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)).</span>name<span class="Delimiter">);</span>
+ <span class="Comment">// todo: why do I explicitly need to provide this?</span>
+ for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>Type<span class="Delimiter">.</span>at<span class="Delimiter">(</span>recently_added_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)).</span>elements<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ delete Type<span class="Delimiter">.</span>at<span class="Delimiter">(</span>recently_added_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)).</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
Type<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>recently_added_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
<span class="Delimiter">}</span>
recently_added_types<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
@@ -411,9 +516,7 @@ while<span class="Delimiter">(</span>p != Type_ordinal<span class="Delimiter">.<
<span class="Comment">// increment iterator</span>
++p<span class="Delimiter">;</span>
<span class="Comment">// now delete current item if necessary</span>
- if <span class="Delimiter">(</span>t >= <span class="Constant">1000</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- Type_ordinal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>name<span class="Delimiter">);</span>
- <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>t >= <span class="Constant">1000</span><span class="Delimiter">)</span> Type_ordinal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>name<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
<span class="Comment">//: lastly, ensure scenarios are consistent by always starting them at the</span>
<span class="Comment">//: same type number.</span>
@@ -423,60 +526,72 @@ assert<span class="Delimiter">(</span>Next_type_ordinal < <span class="Consta
<span class="Delimiter">:(before "End Setup")</span>
Next_type_ordinal = <span class="Constant">1000</span><span class="Delimiter">;</span>
-<span class="SalientComment">//:: Allow container definitions anywhere in the codebase, but warn if you</span>
-<span class="SalientComment">//:: can't find a definition.</span>
+<span class="SalientComment">//:: Allow container definitions anywhere in the codebase, but complain if you</span>
+<span class="SalientComment">//:: can't find a definition at the end.</span>
-<span class="Delimiter">:(scenario run_warns_on_unknown_types)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Delimiter">:(scenario run_complains_on_unknown_types)</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
<span class="Comment"># integer is not a type</span>
<span class="Constant">1</span>:integer<span class="Special"> <- </span>copy <span class="Constant">0</span>
]
-<span class="traceContains">+warn: unknown type: integer</span>
+<span class="traceContains">+error: main: unknown type in '1:integer <- copy 0'</span>
<span class="Delimiter">:(scenario run_allows_type_definition_after_use)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
- <span class="Constant">1</span>:bar<span class="Special"> <- </span>copy <span class="Constant">0</span>
+ <span class="Constant">1</span>:bar<span class="Special"> <- </span>copy <span class="Constant">0</span>/<span class="Special">raw</span>
]
container bar [
x:number
]
-<span class="traceAbsent">-warn: unknown type: bar</span>
-$warn: <span class="Constant">0</span>
+<span class="traceAbsent">-error: unknown type: bar</span>
+$error: <span class="Constant">0</span>
-<span class="Delimiter">:(after "int main")</span>
- Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_invalid_types<span class="Delimiter">);</span>
+<span class="Delimiter">:(after "Begin Transforms")</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_or_set_invalid_types<span class="Delimiter">);</span> <span class="Comment">// idempotent</span>
<span class="Delimiter">:(code)</span>
-void check_invalid_types<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- for <span class="Delimiter">(</span>long long int index = <span class="Constant">0</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- const instruction& inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span>
+void check_or_set_invalid_types<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ for <span class="Delimiter">(</span>long long int index = <span class="Constant">0</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ const instruction& inst = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- check_invalid_types<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
+ check_or_set_invalid_types<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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>
+ maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">),</span> <span class="Constant">"'"</span>+inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span>+<span class="Constant">"'"</span><span class="Delimiter">);</span>
<span class="Delimiter">}</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- check_invalid_types<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
+ check_or_set_invalid_types<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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>
+ maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">),</span> <span class="Constant">"'"</span>+inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span>+<span class="Constant">"'"</span><span class="Delimiter">);</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
-void check_invalid_types<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>Type<span class="Delimiter">.</span>find<span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> == Type<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
- raise << <span class="Constant">"unknown type: "</span> << r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+void check_or_set_invalid_types<span class="Delimiter">(</span>type_tree* type<span class="Delimiter">,</span> const string_tree* type_name<span class="Delimiter">,</span> const string& block<span class="Delimiter">,</span> const string& name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ <span class="Comment">// can't assert that type_name is non-null, even at the top of a recursive call tree</span>
+ if <span class="Delimiter">(</span>!type<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// will throw a more precise error elsewhere</span>
+ <span class="Comment">// End Container Type Checks</span>
+ if <span class="Delimiter">(</span>type<span class="Delimiter">-></span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ assert<span class="Delimiter">(</span>!type<span class="Delimiter">-></span>left && !type<span class="Delimiter">-></span>right<span class="Delimiter">);</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>type_name && contains_key<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type_name<span class="Delimiter">-></span>value<span class="Delimiter">))</span>
+ type<span class="Delimiter">-></span>value = get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type_name<span class="Delimiter">-></span>value<span class="Delimiter">);</span>
+ else
+ raise_error << block << <span class="Constant">"unknown type in "</span> << name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Delimiter">}</span>
+ check_or_set_invalid_types<span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">,</span> type_name ? type_name<span class="Delimiter">-></span>left : <span class="Constant">NULL</span><span class="Delimiter">,</span> block<span class="Delimiter">,</span> name<span class="Delimiter">);</span>
+ check_or_set_invalid_types<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">,</span> type_name ? type_name<span class="Delimiter">-></span>right : <span class="Constant">NULL</span><span class="Delimiter">,</span> block<span class="Delimiter">,</span> name<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(scenario container_unknown_field)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
container foo [
x:number
y:bar
]
-<span class="traceContains">+warn: unknown type for field y in foo</span>
+<span class="traceContains">+error: foo: unknown type in y</span>
<span class="Delimiter">:(scenario read_container_with_bracket_in_comment)</span>
container foo [
@@ -484,35 +599,62 @@ container foo [
<span class="Comment"># ']' in comment</span>
y:number
]
-<span class="traceContains">+parse: reading container foo</span>
-<span class="traceContains">+parse: element name: x</span>
-<span class="traceContains">+parse: type: 1</span>
-<span class="traceContains">+parse: element name: y</span>
-<span class="traceContains">+parse: type: 1</span>
+<span class="traceContains">+parse: --- defining container foo</span>
+<span class="traceContains">+parse: element name: x</span>
+<span class="traceContains">+parse: type: 1</span>
+<span class="traceContains">+parse: element name: y</span>
+<span class="traceContains">+parse: type: 1</span>
-<span class="Delimiter">:(before "End Transform")</span>
+<span class="Delimiter">:(before "End Transform All")</span>
check_container_field_types<span class="Delimiter">();</span>
<span class="Delimiter">:(code)</span>
void check_container_field_types<span class="Delimiter">()</span> <span class="Delimiter">{</span>
for <span class="Delimiter">(</span>map<type_ordinal<span class="Delimiter">,</span> type_info>::iterator p = Type<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Type<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
const type_info& info = p<span class="Delimiter">-></span>second<span class="Delimiter">;</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>Type<span class="Delimiter">.</span>find<span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span>j<span class="Delimiter">))</span> == Type<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
- raise << <span class="Constant">"unknown type for field "</span> << info<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> << <span class="Constant">" in "</span> << info<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Delimiter">}</span>
+ <span class="Comment">// Check Container Field Types(info)</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
+ check_invalid_types<span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> maybe<span class="Delimiter">(</span>info<span class="Delimiter">.</span>name<span class="Delimiter">),</span> info<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+void check_invalid_types<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ for <span class="Delimiter">(</span>long long int index = <span class="Constant">0</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ const instruction& inst = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ check_invalid_types<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">,</span>
+ maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">),</span> <span class="Constant">"'"</span>+inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span>+<span class="Constant">"'"</span><span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ check_invalid_types<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">,</span>
+ maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">),</span> <span class="Constant">"'"</span>+inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span>+<span class="Constant">"'"</span><span class="Delimiter">);</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
+void check_invalid_types<span class="Delimiter">(</span>type_tree* type<span class="Delimiter">,</span> const string& block<span class="Delimiter">,</span> const string& name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!type<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// will throw a more precise error elsewhere</span>
+ <span class="Comment">// End Container Type Checks</span>
+ if <span class="Delimiter">(</span>type<span class="Delimiter">-></span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ assert<span class="Delimiter">(</span>!type<span class="Delimiter">-></span>left && !type<span class="Delimiter">-></span>right<span class="Delimiter">);</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">))</span>
+ raise_error << block << <span class="Constant">"unknown type in "</span> << name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ check_invalid_types<span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">,</span> block<span class="Delimiter">,</span> name<span class="Delimiter">);</span>
+ check_invalid_types<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">,</span> block<span class="Delimiter">,</span> name<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
<span class="SalientComment">//:: Construct types out of their constituent fields. Doesn't currently do</span>
<span class="SalientComment">//:: type-checking but *does* match sizes.</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
MERGE<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"merge"</span>] = MERGE<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"merge"</span><span class="Delimiter">,</span> MERGE<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case MERGE: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case MERGE: <span class="Delimiter">{</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
@@ -533,15 +675,6 @@ recipe main [
]
<span class="traceContains">+mem: storing 3 in location 1</span>
<span class="traceContains">+mem: storing 4 in location 2</span>
-
-<span class="SalientComment">//:: helpers</span>
-
-<span class="Delimiter">:(code)</span>
-void skip_bracket<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> string message<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">()</span> != <span class="Constant">'['</span><span class="Delimiter">)</span>
- raise << message << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
-<span class="Delimiter">}</span>
</pre>
</body>
</html>
diff --git a/html/031address.cc.html b/html/031address.cc.html
index caad95d7..f2b0e28f 100644
--- a/html/031address.cc.html
+++ b/html/031address.cc.html
@@ -13,15 +13,15 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
-.SalientComment { color: #00ffff; }
+.traceContains { color: #008000; }
.traceAbsent { color: #c00000; }
.cSpecial { color: #008000; }
+.SalientComment { color: #00ffff; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
.Identifier { color: #804000; }
.Constant { color: #00a0a0; }
-.traceContains { color: #008000; }
-->
</style>
@@ -38,7 +38,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">:(scenario copy_indirect)</span>
recipe main [
- <span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">2</span>
+ <span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">2</span>/<span class="Special">raw</span>
<span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
<span class="Comment"># This loads location 1 as an address and looks up *that* location.</span>
<span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:address:number/lookup
@@ -46,76 +46,104 @@ recipe main [
<span class="traceContains">+mem: storing 34 in location 3</span>
<span class="Delimiter">:(before "long long int base = x.value" following "vector<double> read_memory(reagent x)")</span>
-x = canonize<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
+canonize<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
<span class="Comment">//: similarly, write to addresses pointing at other locations using the</span>
<span class="Comment">//: 'lookup' property</span>
<span class="Delimiter">:(scenario store_indirect)</span>
recipe main [
- <span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">2</span>
+ <span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">2</span>/<span class="Special">raw</span>
<span class="Constant">1</span>:address:number/lookup<span class="Special"> <- </span>copy <span class="Constant">34</span>
]
<span class="traceContains">+mem: storing 34 in location 2</span>
<span class="Delimiter">:(before "long long int base = x.value" following "void write_memory(reagent x, vector<double> data)")</span>
-x = canonize<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
+canonize<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"can't write to location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"can't write to location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">return</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
-<span class="Delimiter">:(after "bool is_mu_array(reagent r)")</span>
-r = canonize<span class="Delimiter">(</span>r<span class="Delimiter">);</span>
-
<span class="Comment">//: writes to address 0 always loudly fail</span>
-<span class="Delimiter">:(scenario store_to_0_warns)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Delimiter">:(scenario store_to_0_fails)</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
<span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
<span class="Constant">1</span>:address:number/lookup<span class="Special"> <- </span>copy <span class="Constant">34</span>
]
<span class="traceAbsent">-mem: storing 34 in location 0</span>
-<span class="traceContains">+warn: can't write to location 0 in '1:address:number/lookup <- copy 34'</span>
+<span class="traceContains">+error: can't write to location 0 in '1:address:number/lookup <- copy 34'</span>
<span class="Delimiter">:(code)</span>
-reagent canonize<span class="Delimiter">(</span>reagent x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> x<span class="Delimiter">;</span>
- reagent r = x<span class="Delimiter">;</span>
- while <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">"lookup"</span><span class="Delimiter">))</span>
- r = lookup_memory<span class="Delimiter">(</span>r<span class="Delimiter">);</span>
- <span class="Identifier">return</span> r<span class="Delimiter">;</span>
+void canonize<span class="Delimiter">(</span>reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
+ <span class="Comment">// End canonize(x) Special-cases</span>
+ while <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>x<span class="Delimiter">,</span> <span class="Constant">"lookup"</span><span class="Delimiter">))</span>
+ lookup_memory<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
-reagent lookup_memory<span class="Delimiter">(</span>reagent x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- static const type_ordinal ADDRESS = Type_ordinal[<span class="Constant">"address"</span>]<span class="Delimiter">;</span>
- reagent result<span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> || x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> != ADDRESS<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": tried to /lookup "</span> << x<span class="Delimiter">.</span>original_string << <span class="Constant">" but it isn't an address</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+void lookup_memory<span class="Delimiter">(</span>reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>type || x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"tried to /lookup "</span> << x<span class="Delimiter">.</span>original_string << <span class="Constant">" but it isn't an address</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
<span class="Comment">// compute value</span>
if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": tried to /lookup 0</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"tried to /lookup 0</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
- result<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>Memory[x<span class="Delimiter">.</span>value]<span class="Delimiter">);</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"mem"</span><span class="Delimiter">)</span> << <span class="Constant">"location "</span> << x<span class="Delimiter">.</span>value << <span class="Constant">" is "</span> << result<span class="Delimiter">.</span>value << end<span class="Delimiter">();</span>
-
- <span class="Comment">// populate types</span>
- copy<span class="Delimiter">(</span>++x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> inserter<span class="Delimiter">(</span>result<span class="Delimiter">.</span>types<span class="Delimiter">,</span> result<span class="Delimiter">.</span>types<span class="Delimiter">.</span>begin<span class="Delimiter">()));</span>
-
- <span class="Comment">// drop-one 'lookup'</span>
- long long int i = <span class="Constant">0</span><span class="Delimiter">;</span>
- long long int len = SIZE<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">);</span>
- for <span class="Delimiter">(</span>i = <span class="Constant">0</span><span class="Delimiter">;</span> i < len<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>first == <span class="Constant">"lookup"</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
- result<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
+ 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">"location "</span> << x<span class="Delimiter">.</span>value << <span class="Constant">" is "</span> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> x<span class="Delimiter">.</span>value<span class="Delimiter">))</span> << end<span class="Delimiter">();</span>
+ x<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> x<span class="Delimiter">.</span>value<span class="Delimiter">));</span>
+ drop_address_from_type<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
+ drop_one_lookup<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(after "bool types_match(reagent lhs, reagent rhs)")</span>
+ 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 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>
+
+<span class="Delimiter">:(after "bool is_mu_address(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>
+
+<span class="Delimiter">:(after "bool is_mu_number(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>
+
+<span class="Delimiter">:(code)</span>
+bool canonize_type<span class="Delimiter">(</span>reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ while <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">"lookup"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!r<span class="Delimiter">.</span>type || 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>
+ raise_error << <span class="Constant">"can't lookup non-address: "</span> << r<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">": "</span> << debug_string<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ drop_address_from_type<span class="Delimiter">(</span>r<span class="Delimiter">);</span>
+ drop_one_lookup<span class="Delimiter">(</span>r<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+ <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+void drop_address_from_type<span class="Delimiter">(</span>reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ type_tree* tmp = r<span class="Delimiter">.</span>type<span class="Delimiter">;</span>
+ r<span class="Delimiter">.</span>type = tmp<span class="Delimiter">-></span>right<span class="Delimiter">;</span>
+ tmp<span class="Delimiter">-></span>right = <span class="Constant">NULL</span><span class="Delimiter">;</span>
+ delete tmp<span class="Delimiter">;</span>
+ <span class="Comment">// property</span>
+ if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ string_tree* tmp2 = r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">;</span>
+ r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second = tmp2<span class="Delimiter">-></span>right<span class="Delimiter">;</span>
+ tmp2<span class="Delimiter">-></span>right = <span class="Constant">NULL</span><span class="Delimiter">;</span>
+ delete tmp2<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- ++i<span class="Delimiter">;</span> <span class="Comment">// skip first lookup</span>
- for <span class="Delimiter">(;</span> i < len<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- result<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
+<span class="Delimiter">}</span>
+
+void drop_one_lookup<span class="Delimiter">(</span>reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ for <span class="Delimiter">(</span>vector<pair<string<span class="Delimiter">,</span> string_tree*> >::iterator p = r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != r<span class="Delimiter">.</span>properties<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="Constant">"lookup"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>p<span class="Delimiter">);</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
<span class="Delimiter">}</span>
- <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+ assert<span class="Delimiter">(</span><span class="Constant">false</span><span class="Delimiter">);</span>
<span class="Delimiter">}</span>
<span class="SalientComment">//:: 'get' can read from container address</span>
@@ -128,6 +156,16 @@ recipe main [
]
<span class="traceContains">+mem: storing 34 in location 4</span>
+<span class="Delimiter">:(scenario get_indirect2)</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">2</span>
+ <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
+ <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span>
+ <span class="Constant">4</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">5</span>/<span class="Special">raw</span>
+ *<span class="Constant">4</span>:address:number<span class="Special"> <- </span>get <span class="Constant">1</span>:address:point/lookup<span class="Delimiter">,</span> <span class="Constant">0</span>:offset
+]
+<span class="traceContains">+mem: storing 34 in location 5</span>
+
<span class="Delimiter">:(scenario include_nonlookup_properties)</span>
recipe main [
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">2</span>
@@ -137,8 +175,12 @@ recipe main [
]
<span class="traceContains">+mem: storing 34 in location 4</span>
-<span class="Delimiter">:(after "reagent base = " following "case GET:")</span>
-base = canonize<span class="Delimiter">(</span>base<span class="Delimiter">);</span>
+<span class="Delimiter">:(after "Update GET base in Check")</span>
+if <span class="Delimiter">(</span>!canonize_type<span class="Delimiter">(</span>base<span class="Delimiter">))</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">:(after "Update GET product in Check")</span>
+if <span class="Delimiter">(</span>!canonize_type<span class="Delimiter">(</span>product<span class="Delimiter">))</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">:(after "Update GET base in Run")</span>
+canonize<span class="Delimiter">(</span>base<span class="Delimiter">);</span>
<span class="Delimiter">:(scenario get_address_indirect)</span>
<span class="Comment"># 'get' can read from container address</span>
@@ -146,31 +188,37 @@ recipe main [
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">2</span>
<span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
<span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span>
- <span class="Constant">4</span>:number<span class="Special"> <- </span>get-address <span class="Constant">1</span>:address:point/lookup<span class="Delimiter">,</span> <span class="Constant">0</span>:offset
+ <span class="Constant">4</span>:address:number<span class="Special"> <- </span>get-address <span class="Constant">1</span>:address:point/lookup<span class="Delimiter">,</span> <span class="Constant">0</span>:offset
]
<span class="traceContains">+mem: storing 2 in location 4</span>
-<span class="Delimiter">:(after "reagent base = " following "case GET_ADDRESS:")</span>
-base = canonize<span class="Delimiter">(</span>base<span class="Delimiter">);</span>
+<span class="Delimiter">:(after "Update GET_ADDRESS base in Check")</span>
+if <span class="Delimiter">(</span>!canonize_type<span class="Delimiter">(</span>base<span class="Delimiter">))</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">:(after "Update GET_ADDRESS product in Check")</span>
+if <span class="Delimiter">(</span>!canonize_type<span class="Delimiter">(</span>base<span class="Delimiter">))</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">:(after "Update GET_ADDRESS base in Run")</span>
+canonize<span class="Delimiter">(</span>base<span class="Delimiter">);</span>
<span class="SalientComment">//:: abbreviation for '/lookup': a prefix '*'</span>
<span class="Delimiter">:(scenario lookup_abbreviation)</span>
recipe main [
- <span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">2</span>
+ <span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">2</span>/<span class="Special">raw</span>
<span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
<span class="Constant">3</span>:number<span class="Special"> <- </span>copy *<span class="Constant">1</span>:address:number
]
+<span class="traceContains">+parse: ingredient: {"1": <"address" : <"number" : <>>>, "lookup": <>}</span>
<span class="traceContains">+mem: storing 34 in location 3</span>
<span class="Delimiter">:(before "End Parsing reagent")</span>
<span class="Delimiter">{</span>
while <span class="Delimiter">(</span>!name<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && name<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">'*'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
name<span class="Delimiter">.</span>erase<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span>
- properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> vector<string> ><span class="Delimiter">(</span><span class="Constant">"lookup"</span><span class="Delimiter">,</span> vector<string><span class="Delimiter">()));</span>
+ properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> string_tree*><span class="Delimiter">(</span><span class="Constant">"lookup"</span><span class="Delimiter">,</span> <span class="Constant">NULL</span><span class="Delimiter">));</span>
<span class="Delimiter">}</span>
if <span class="Delimiter">(</span>name<span class="Delimiter">.</span>empty<span class="Delimiter">())</span>
- raise << <span class="Constant">"illegal name "</span> << original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"illegal name "</span> << original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>first = name<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="SalientComment">//:: helpers for debugging</span>
@@ -178,11 +226,12 @@ recipe main [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
_DUMP<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"$dump"</span>] = _DUMP<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"$dump"</span><span class="Delimiter">,</span> _DUMP<span class="Delimiter">);</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case _DUMP: <span class="Delimiter">{</span>
- reagent after_canonize = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
- cerr << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name << <span class="Constant">' '</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>value << <span class="Constant">" => "</span> << after_canonize<span class="Delimiter">.</span>value << <span class="Constant">" => "</span> << Memory[after_canonize<span class="Delimiter">.</span>value] << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
+ reagent after_canonize = 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>
+ canonize<span class="Delimiter">(</span>after_canonize<span class="Delimiter">);</span>
+ cerr << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name << <span class="Constant">' '</span> << no_scientific<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>value<span class="Delimiter">)</span> << <span class="Constant">" => "</span> << no_scientific<span class="Delimiter">(</span>after_canonize<span class="Delimiter">.</span>value<span class="Delimiter">)</span> << <span class="Constant">" => "</span> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> after_canonize<span class="Delimiter">.</span>value<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>
@@ -193,15 +242,17 @@ long long int foo = -<span class="Constant">1</span><span class="Delimiter">;</s
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
_FOO<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"$foo"</span>] = _FOO<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"$foo"</span><span class="Delimiter">,</span> _FOO<span class="Delimiter">);</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case _FOO: <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>foo != -<span class="Constant">1</span><span class="Delimiter">)</span> cerr << foo << <span class="Constant">": "</span> << Memory[foo] << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>foo != -<span class="Constant">1</span><span class="Delimiter">)</span> cerr << foo << <span class="Constant">": "</span> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> foo<span class="Delimiter">))</span> << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
else cerr << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
else <span class="Delimiter">{</span>
- foo = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)).</span>value<span class="Delimiter">;</span>
+ reagent tmp = 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>
+ canonize<span class="Delimiter">(</span>tmp<span class="Delimiter">);</span>
+ foo = tmp<span class="Delimiter">.</span>value<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
diff --git a/html/032array.cc.html b/html/032array.cc.html
index c73052a4..8c0ce105 100644
--- a/html/032array.cc.html
+++ b/html/032array.cc.html
@@ -13,6 +13,7 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.traceContains { color: #008000; }
.SalientComment { color: #00ffff; }
.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
@@ -20,7 +21,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
.Special { color: #ff6060; }
.Identifier { color: #804000; }
.Constant { color: #00a0a0; }
-.traceContains { color: #008000; }
-->
</style>
@@ -50,40 +50,47 @@ recipe main [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
CREATE_ARRAY<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"create-array"</span>] = CREATE_ARRAY<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"create-array"</span><span class="Delimiter">,</span> CREATE_ARRAY<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case CREATE_ARRAY: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": 'create-array' needs one product and no ingredients but got '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'create-array' needs one product and no ingredients but got '"</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>
- reagent product = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
+ 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>!is_mu_array<span class="Delimiter">(</span>product<span class="Delimiter">))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": 'create-array' cannot create non-array "</span> << product<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'create-array' cannot create non-array "</span> << product<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- long long int base_address = product<span class="Delimiter">.</span>value<span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>product<span class="Delimiter">.</span>types<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": create array of what? "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"create array of what? "</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="Comment">// 'create-array' will need to check properties rather than types</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>product<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">)</span> <= <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": create array of what size? "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!product<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second || !product<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">-></span>right || !product<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"create array of what size? "</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>
- if <span class="Delimiter">(</span>!is_integer<span class="Delimiter">(</span>product<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": 'create-array' product should specify size of array after its element type, but got "</span> << product<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_integer<span class="Delimiter">(</span>product<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>value<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'create-array' product should specify size of array after its element type, but got "</span> << product<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>value << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- long long int array_size= to_integer<span class="Delimiter">(</span>product<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">));</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case CREATE_ARRAY: <span class="Delimiter">{</span>
+ reagent product = current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ canonize<span class="Delimiter">(</span>product<span class="Delimiter">);</span>
+ long long int base_address = product<span class="Delimiter">.</span>value<span class="Delimiter">;</span>
+ long long int array_size = to_integer<span class="Delimiter">(</span>product<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>value<span class="Delimiter">);</span>
<span class="Comment">// initialize array size, so that size_of will work</span>
- Memory[base_address] = array_size<span class="Delimiter">;</span> <span class="Comment">// in array elements</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> base_address<span class="Delimiter">,</span> array_size<span class="Delimiter">);</span> <span class="Comment">// in array elements</span>
long long int size = size_of<span class="Delimiter">(</span>product<span class="Delimiter">);</span> <span class="Comment">// in locations</span>
- trace<span class="Delimiter">(</span><span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"creating array of size "</span> << size << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"creating array of size "</span> << size << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Comment">// initialize array</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">1</span><span class="Delimiter">;</span> i <= size_of<span class="Delimiter">(</span>product<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- Memory[base_address+i] = <span class="Constant">0</span><span class="Delimiter">;</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> base_address+i<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span>
<span class="Delimiter">}</span>
<span class="Comment">// dummy product; doesn't actually do anything</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
@@ -112,7 +119,7 @@ recipe main [
<span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>
<span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span>
- <span class="Constant">5</span>:address:array:number<span class="Special"> <- </span>copy <span class="Constant">1</span> <span class="Comment"># unsafe</span>
+ <span class="Constant">5</span>:address:array:number<span class="Special"> <- </span>copy <span class="Constant">1</span>/<span class="Special">raw</span>
<span class="Constant">6</span>:array:number<span class="Special"> <- </span>copy *<span class="Constant">5</span>:address:array:number
]
<span class="traceContains">+mem: storing 3 in location 6</span>
@@ -132,15 +139,15 @@ recipe main [
<span class="Comment">//: disable the size mismatch check since the destination array need not be initialized</span>
<span class="Delimiter">:(before "End size_mismatch(x) Cases")</span>
-if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == Type_ordinal[<span class="Constant">"array"</span>]<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>type && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
<span class="Delimiter">:(before "End size_of(reagent) Cases")</span>
-if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == Type_ordinal[<span class="Constant">"array"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": '"</span> << r<span class="Delimiter">.</span>original_string << <span class="Constant">"' is an array of what?</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>type && 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">"array"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"'"</span> << r<span class="Delimiter">.</span>original_string << <span class="Constant">"' is an array of what?</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">return</span> <span class="Constant">1</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Comment">// skip the 'array' type to get at the element type</span>
- <span class="Identifier">return</span> <span class="Constant">1</span> + Memory[r<span class="Delimiter">.</span>value]*size_of<span class="Delimiter">(</span>array_element<span class="Delimiter">(</span>r<span class="Delimiter">.</span>types<span class="Delimiter">));</span>
+ <span class="Identifier">return</span> <span class="Constant">1</span> + get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> r<span class="Delimiter">.</span>value<span class="Delimiter">)</span>*size_of<span class="Delimiter">(</span>array_element<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">));</span>
<span class="Delimiter">}</span>
<span class="SalientComment">//:: To access elements of an array, use 'index'</span>
@@ -169,43 +176,60 @@ recipe main [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
INDEX<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"index"</span>] = INDEX<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"index"</span><span class="Delimiter">,</span> INDEX<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case INDEX: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'index' expects exactly 2 ingredients in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'index' expects exactly 2 ingredients in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- reagent base = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
+ reagent base = inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ canonize_type<span class="Delimiter">(</span>base<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>!is_mu_array<span class="Delimiter">(</span>base<span class="Delimiter">))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": 'index' on a non-array "</span> << base<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'index' on a non-array "</span> << base<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
+ reagent product = inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ canonize_type<span class="Delimiter">(</span>product<span class="Delimiter">);</span>
+ reagent element<span class="Delimiter">;</span>
+ element<span class="Delimiter">.</span>type = new type_tree<span class="Delimiter">(</span>*array_element<span class="Delimiter">(</span>base<span class="Delimiter">.</span>type<span class="Delimiter">));</span>
+ if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'index' on "</span> << base<span class="Delimiter">.</span>original_string << <span class="Constant">" can't be saved in "</span> << product<span class="Delimiter">.</span>original_string << <span class="Constant">"; type should be "</span> << debug_string<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case INDEX: <span class="Delimiter">{</span>
+ reagent base = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ canonize<span class="Delimiter">(</span>base<span class="Delimiter">);</span>
long long int base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span>
if <span class="Delimiter">(</span>base_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": tried to access location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"tried to access location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- reagent offset = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">));</span>
+ reagent offset = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
+ canonize<span class="Delimiter">(</span>offset<span class="Delimiter">);</span>
vector<double> offset_val<span class="Delimiter">(</span>read_memory<span class="Delimiter">(</span>offset<span class="Delimiter">));</span>
- vector<type_ordinal> element_type = array_element<span class="Delimiter">(</span>base<span class="Delimiter">.</span>types<span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> < <span class="Constant">0</span> || offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> >= Memory[base_address]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": invalid index "</span> << offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ type_tree* element_type = array_element<span class="Delimiter">(</span>base<span class="Delimiter">.</span>type<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> < <span class="Constant">0</span> || offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> >= get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> base_address<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"invalid index "</span> << no_scientific<span class="Delimiter">(</span>offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
long long int src = base_address + <span class="Constant">1</span> + offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>*size_of<span class="Delimiter">(</span>element_type<span class="Delimiter">);</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"address to copy is "</span> << src << end<span class="Delimiter">();</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"its type is "</span> << Type[element_type<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>]<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"address to copy is "</span> << src << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"its type is "</span> << get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> element_type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>name << end<span class="Delimiter">();</span>
reagent tmp<span class="Delimiter">;</span>
tmp<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>src<span class="Delimiter">);</span>
- copy<span class="Delimiter">(</span>element_type<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> element_type<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> inserter<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>types<span class="Delimiter">,</span> tmp<span class="Delimiter">.</span>types<span class="Delimiter">.</span>begin<span class="Delimiter">()));</span>
+ tmp<span class="Delimiter">.</span>type = new type_tree<span class="Delimiter">(</span>*element_type<span class="Delimiter">);</span>
products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>read_memory<span class="Delimiter">(</span>tmp<span class="Delimiter">));</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(code)</span>
-vector<type_ordinal> array_element<span class="Delimiter">(</span>const vector<type_ordinal>& types<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- <span class="Identifier">return</span> vector<type_ordinal><span class="Delimiter">(</span>++types<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> types<span class="Delimiter">.</span>end<span class="Delimiter">());</span>
+type_tree* array_element<span class="Delimiter">(</span>const type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ <span class="Identifier">return</span> type<span class="Delimiter">-></span>right<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(scenario index_indirect)</span>
@@ -214,13 +238,13 @@ recipe main [
<span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>
<span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span>
- <span class="Constant">5</span>:address:array:number<span class="Special"> <- </span>copy <span class="Constant">1</span>
+ <span class="Constant">5</span>:address:array:number<span class="Special"> <- </span>copy <span class="Constant">1</span>/<span class="Special">raw</span>
<span class="Constant">6</span>:number<span class="Special"> <- </span>index *<span class="Constant">5</span>:address:array:number<span class="Delimiter">,</span> <span class="Constant">1</span>
]
<span class="traceContains">+mem: storing 15 in location 6</span>
<span class="Delimiter">:(scenario index_out_of_bounds)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
<span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> <- </span>create-array
<span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>
@@ -232,10 +256,10 @@ recipe main [
<span class="Constant">8</span>:address:array:point<span class="Special"> <- </span>copy <span class="Constant">1</span>
index *<span class="Constant">8</span>:address:array:point<span class="Delimiter">,</span> <span class="Constant">4</span> <span class="Comment"># less than size of array in locations, but larger than its length in elements</span>
]
-<span class="traceContains">+warn: main: invalid index 4</span>
+<span class="traceContains">+error: main: invalid index 4</span>
<span class="Delimiter">:(scenario index_out_of_bounds_2)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
<span class="Constant">1</span>:array:point:<span class="Constant">3</span><span class="Special"> <- </span>create-array
<span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>
@@ -244,10 +268,25 @@ recipe main [
<span class="Constant">5</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>
<span class="Constant">6</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span>
<span class="Constant">7</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span>
- <span class="Constant">8</span>:address:array:point<span class="Special"> <- </span>copy <span class="Constant">1</span>
+ <span class="Constant">8</span>:address:array:point<span class="Special"> <- </span>copy <span class="Constant">1</span>/<span class="Special">raw</span>
index *<span class="Constant">8</span>:address:array:point<span class="Delimiter">,</span> -<span class="Constant">1</span>
]
-<span class="traceContains">+warn: main: invalid index -1</span>
+<span class="traceContains">+error: main: invalid index -1</span>
+
+<span class="Delimiter">:(scenario index_product_type_mismatch)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+ <span class="Constant">1</span>:array:point:<span class="Constant">3</span><span class="Special"> <- </span>create-array
+ <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>
+ <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span>
+ <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span>
+ <span class="Constant">5</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>
+ <span class="Constant">6</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span>
+ <span class="Constant">7</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span>
+ <span class="Constant">8</span>:address:array:point<span class="Special"> <- </span>copy <span class="Constant">1</span>/<span class="Special">raw</span>
+ <span class="Constant">9</span>:number<span class="Special"> <- </span>index *<span class="Constant">8</span>:address:array:point<span class="Delimiter">,</span> <span class="Constant">0</span>
+]
+<span class="traceContains">+error: main: 'index' on *8:address:array:point can't be saved in 9:number; type should be point</span>
<span class="SalientComment">//:: To write to elements of containers, you need their address.</span>
@@ -257,35 +296,53 @@ recipe main [
<span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>
<span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span>
- <span class="Constant">5</span>:number<span class="Special"> <- </span>index-address <span class="Constant">1</span>:array:number<span class="Delimiter">,</span> <span class="Constant">0</span>
+ <span class="Constant">5</span>:address:number<span class="Special"> <- </span>index-address <span class="Constant">1</span>:array:number<span class="Delimiter">,</span> <span class="Constant">0</span>
]
<span class="traceContains">+mem: storing 2 in location 5</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
INDEX_ADDRESS<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"index-address"</span>] = INDEX_ADDRESS<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"index-address"</span><span class="Delimiter">,</span> INDEX_ADDRESS<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case INDEX_ADDRESS: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'index-address' expects exactly 2 ingredients in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'index-address' expects exactly 2 ingredients in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- reagent base = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
+ reagent base = inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ canonize_type<span class="Delimiter">(</span>base<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>!is_mu_array<span class="Delimiter">(</span>base<span class="Delimiter">))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": 'index-address' on a non-array "</span> << base<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'index-address' on a non-array "</span> << base<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
+ reagent product = inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ canonize_type<span class="Delimiter">(</span>product<span class="Delimiter">);</span>
+ reagent element<span class="Delimiter">;</span>
+ element<span class="Delimiter">.</span>type = new type_tree<span class="Delimiter">(</span>*array_element<span class="Delimiter">(</span>base<span class="Delimiter">.</span>type<span class="Delimiter">));</span>
+ element<span class="Delimiter">.</span>type = new type_tree<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">),</span> element<span class="Delimiter">.</span>type<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'index' on "</span> << base<span class="Delimiter">.</span>original_string << <span class="Constant">" can't be saved in "</span> << product<span class="Delimiter">.</span>original_string << <span class="Constant">"; type should be "</span> << debug_string<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case INDEX_ADDRESS: <span class="Delimiter">{</span>
+ reagent base = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ canonize<span class="Delimiter">(</span>base<span class="Delimiter">);</span>
long long int base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span>
if <span class="Delimiter">(</span>base_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": tried to access location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"tried to access location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- reagent offset = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">));</span>
+ reagent offset = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
+ canonize<span class="Delimiter">(</span>offset<span class="Delimiter">);</span>
vector<double> offset_val<span class="Delimiter">(</span>read_memory<span class="Delimiter">(</span>offset<span class="Delimiter">));</span>
- vector<type_ordinal> element_type = array_element<span class="Delimiter">(</span>base<span class="Delimiter">.</span>types<span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> < <span class="Constant">0</span> || offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> >= Memory[base_address]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": invalid index "</span> << offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ type_tree* element_type = array_element<span class="Delimiter">(</span>base<span class="Delimiter">.</span>type<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> < <span class="Constant">0</span> || offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> >= get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> base_address<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"invalid index "</span> << no_scientific<span class="Delimiter">(</span>offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
long long int result = base_address + <span class="Constant">1</span> + offset_val<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>*size_of<span class="Delimiter">(</span>element_type<span class="Delimiter">);</span>
@@ -295,7 +352,7 @@ case INDEX_ADDRESS: <span class="Delimiter">{</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(scenario index_address_out_of_bounds)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
<span class="Constant">1</span>:array:point:<span class="Constant">3</span><span class="Special"> <- </span>create-array
<span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>
@@ -307,10 +364,10 @@ recipe main [
<span class="Constant">8</span>:address:array:point<span class="Special"> <- </span>copy <span class="Constant">1</span> <span class="Comment"># unsafe</span>
index-address *<span class="Constant">8</span>:address:array:point<span class="Delimiter">,</span> <span class="Constant">4</span> <span class="Comment"># less than size of array in locations, but larger than its length in elements</span>
]
-<span class="traceContains">+warn: main: invalid index 4</span>
+<span class="traceContains">+error: main: invalid index 4</span>
<span class="Delimiter">:(scenario index_address_out_of_bounds_2)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
<span class="Constant">1</span>:array:point:<span class="Constant">3</span><span class="Special"> <- </span>create-array
<span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>
@@ -319,10 +376,25 @@ recipe main [
<span class="Constant">5</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>
<span class="Constant">6</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span>
<span class="Constant">7</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span>
- <span class="Constant">8</span>:address:array:point<span class="Special"> <- </span>copy <span class="Constant">1</span> <span class="Comment"># unsafe</span>
+ <span class="Constant">8</span>:address:array:point<span class="Special"> <- </span>copy <span class="Constant">1</span>/<span class="Special">raw</span>
index-address *<span class="Constant">8</span>:address:array:point<span class="Delimiter">,</span> -<span class="Constant">1</span>
]
-<span class="traceContains">+warn: main: invalid index -1</span>
+<span class="traceContains">+error: main: invalid index -1</span>
+
+<span class="Delimiter">:(scenario index_address_product_type_mismatch)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+ <span class="Constant">1</span>:array:point:<span class="Constant">3</span><span class="Special"> <- </span>create-array
+ <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>
+ <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span>
+ <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span>
+ <span class="Constant">5</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span>
+ <span class="Constant">6</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span>
+ <span class="Constant">7</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span>
+ <span class="Constant">8</span>:address:array:point<span class="Special"> <- </span>copy <span class="Constant">1</span>/<span class="Special">raw</span>
+ <span class="Constant">9</span>:address:number<span class="Special"> <- </span>index-address *<span class="Constant">8</span>:address:array:point<span class="Delimiter">,</span> <span class="Constant">0</span>
+]
+<span class="traceContains">+error: main: 'index' on *8:address:array:point can't be saved in 9:address:number; type should be <address : <point : <>>></span>
<span class="SalientComment">//:: compute the length of an array</span>
@@ -339,24 +411,31 @@ recipe main [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
LENGTH<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"length"</span>] = LENGTH<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"length"</span><span class="Delimiter">,</span> LENGTH<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case LENGTH: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'length' expects exactly 2 ingredients in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ 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>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'length' expects exactly 2 ingredients in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- reagent x = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
+ reagent x = inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ canonize_type<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>!is_mu_array<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"tried to calculate length of non-array "</span> << x<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"tried to calculate length of non-array "</span> << x<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case LENGTH: <span class="Delimiter">{</span>
+ reagent x = 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>
+ canonize<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": tried to access location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"tried to access location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
- products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>Memory[x<span class="Delimiter">.</span>value]<span class="Delimiter">);</span>
+ products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> x<span class="Delimiter">.</span>value<span class="Delimiter">));</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
diff --git a/html/033exclusive_container.cc.html b/html/033exclusive_container.cc.html
index beea9b0e..a4fc191a 100644
--- a/html/033exclusive_container.cc.html
+++ b/html/033exclusive_container.cc.html
@@ -13,9 +13,9 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
-.cSpecial { color: #008000; }
-.SalientComment { color: #00ffff; }
.traceContains { color: #008000; }
+.SalientComment { color: #00ffff; }
+.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
@@ -41,23 +41,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">:(before "End Mu Types Initialization")</span>
<span class="Comment">//: We'll use this container as a running example, with two number elements.</span>
<span class="Delimiter">{</span>
-type_ordinal tmp = Type_ordinal[<span class="Constant">"number-or-point"</span>] = Next_type_ordinal++<span class="Delimiter">;</span>
-Type[tmp]<span class="Delimiter">.</span>size = <span class="Constant">2</span><span class="Delimiter">;</span>
-Type[tmp]<span class="Delimiter">.</span>kind = exclusive_container<span class="Delimiter">;</span>
-Type[tmp]<span class="Delimiter">.</span>name = <span class="Constant">"number-or-point"</span><span class="Delimiter">;</span>
-vector<type_ordinal> t1<span class="Delimiter">;</span>
-t1<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>number<span class="Delimiter">);</span>
-Type[tmp]<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>t1<span class="Delimiter">);</span>
-vector<type_ordinal> t2<span class="Delimiter">;</span>
-t2<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>point<span class="Delimiter">);</span>
-Type[tmp]<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>t2<span class="Delimiter">);</span>
-Type[tmp]<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">"i"</span><span class="Delimiter">);</span>
-Type[tmp]<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">"p"</span><span class="Delimiter">);</span>
+type_ordinal tmp = put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"number-or-point"</span><span class="Delimiter">,</span> Next_type_ordinal++<span class="Delimiter">);</span>
+get_or_insert<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> tmp<span class="Delimiter">).</span>size = <span class="Constant">2</span><span class="Delimiter">;</span>
+get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> tmp<span class="Delimiter">).</span>kind = EXCLUSIVE_CONTAINER<span class="Delimiter">;</span>
+get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> tmp<span class="Delimiter">).</span>name = <span class="Constant">"number-or-point"</span><span class="Delimiter">;</span>
+get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> tmp<span class="Delimiter">).</span>elements<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new type_tree<span class="Delimiter">(</span>number<span class="Delimiter">));</span>
+get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> tmp<span class="Delimiter">).</span>element_names<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">"i"</span><span class="Delimiter">);</span>
+get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> tmp<span class="Delimiter">).</span>elements<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new type_tree<span class="Delimiter">(</span>point<span class="Delimiter">));</span>
+get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> tmp<span class="Delimiter">).</span>element_names<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">"p"</span><span class="Delimiter">);</span>
<span class="Delimiter">}</span>
<span class="Comment">//: Tests in this layer often explicitly setup memory before reading it as an</span>
<span class="Comment">//: array. Don't do this in general. I'm tagging exceptions with /raw to</span>
-<span class="Comment">//: avoid warnings.</span>
+<span class="Comment">//: avoid errors.</span>
<span class="Delimiter">:(scenario copy_exclusive_container)</span>
<span class="Comment"># Copying exclusive containers copies all their contents and an extra location for the tag.</span>
recipe main [
@@ -70,8 +66,8 @@ recipe main [
<span class="traceContains">+mem: storing 34 in location 5</span>
<span class="traceContains">+mem: storing 35 in location 6</span>
-<span class="Delimiter">:(before "End size_of(types) Cases")</span>
-if <span class="Delimiter">(</span>t<span class="Delimiter">.</span>kind == exclusive_container<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+<span class="Delimiter">:(before "End size_of(type) Cases")</span>
+if <span class="Delimiter">(</span>t<span class="Delimiter">.</span>kind == EXCLUSIVE_CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Comment">// size of an exclusive container is the size of its largest variant</span>
<span class="Comment">// (So like containers, it can't contain arrays.)</span>
long long int result = <span class="Constant">0</span><span class="Delimiter">;</span>
@@ -91,7 +87,7 @@ if <span class="Delimiter">(</span>t<span class="Delimiter">.</span>kind == excl
<span class="Comment">//: 'maybe-convert' requires a literal in ingredient 1. We'll use a synonym</span>
<span class="Comment">//: called 'variant'.</span>
<span class="Delimiter">:(before "End Mu Types Initialization")</span>
-Type_ordinal[<span class="Constant">"variant"</span>] = <span class="Constant">0</span><span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"variant"</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span>
<span class="Delimiter">:(scenario maybe_convert)</span>
recipe main [
@@ -114,30 +110,37 @@ recipe main [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
MAYBE_CONVERT<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"maybe-convert"</span>] = MAYBE_CONVERT<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"maybe-convert"</span><span class="Delimiter">,</span> MAYBE_CONVERT<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case MAYBE_CONVERT: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'maybe-convert' expects exactly 2 ingredients in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'maybe-convert' expects exactly 2 ingredients in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- reagent base = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
- long long int base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>base_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": tried to access location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ reagent base = inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ canonize_type<span class="Delimiter">(</span>base<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!base<span class="Delimiter">.</span>type || !base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value || get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>kind != EXCLUSIVE_CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'maybe-convert' should be an exclusive-container, but got "</span> << base<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> || Type[base<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>]<span class="Delimiter">.</span>kind != exclusive_container<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name <span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'maybe-convert' should be an exclusive-container, but got "</span> << base<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"second ingredient of 'maybe-convert' should have type 'variant', but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": second ingredient of 'maybe-convert' should have type 'variant', but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case MAYBE_CONVERT: <span class="Delimiter">{</span>
+ reagent base = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ canonize<span class="Delimiter">(</span>base<span class="Delimiter">);</span>
+ long long int base_address = base<span class="Delimiter">.</span>value<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>base_address == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"tried to access location 0 in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
long long int tag = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>value<span class="Delimiter">;</span>
long long int result<span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>tag == static_cast<long long int><span class="Delimiter">(</span>Memory[base_address]<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>tag == static_cast<long long int><span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> base_address<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
result = base_address+<span class="Constant">1</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
else <span class="Delimiter">{</span>
@@ -155,7 +158,7 @@ exclusive-container foo [
x:number
y:number
]
-<span class="traceContains">+parse: reading exclusive-container foo</span>
+<span class="traceContains">+parse: --- defining exclusive-container foo</span>
<span class="traceContains">+parse: element name: x</span>
<span class="traceContains">+parse: type: 1</span>
<span class="traceContains">+parse: element name: y</span>
@@ -163,7 +166,7 @@ exclusive-container foo [
<span class="Delimiter">:(before "End Command Handlers")</span>
else if <span class="Delimiter">(</span>command == <span class="Constant">"exclusive-container"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- insert_container<span class="Delimiter">(</span>command<span class="Delimiter">,</span> exclusive_container<span class="Delimiter">,</span> in<span class="Delimiter">);</span>
+ insert_container<span class="Delimiter">(</span>command<span class="Delimiter">,</span> EXCLUSIVE_CONTAINER<span class="Delimiter">,</span> in<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
<span class="SalientComment">//:: To construct exclusive containers out of variant types, use 'merge'.</span>
@@ -188,9 +191,10 @@ recipe main [
<span class="Delimiter">:(before "End size_mismatch(x) Cases")</span>
if <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>operation == MERGE
&& !current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">()</span>
- && !current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- reagent x = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
- if <span class="Delimiter">(</span>Type[x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>]<span class="Delimiter">.</span>kind == exclusive_container<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ && current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>type<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ reagent x = current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ canonize<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>kind == EXCLUSIVE_CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Identifier">return</span> size_of<span class="Delimiter">(</span>x<span class="Delimiter">)</span> < SIZE<span class="Delimiter">(</span>data<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
diff --git a/html/034call.cc.html b/html/034call.cc.html
index 8c95766f..10ad7632 100644
--- a/html/034call.cc.html
+++ b/html/034call.cc.html
@@ -13,15 +13,15 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
-.PreProc { color: #c000c0; }
+.traceContains { color: #008000; }
.SalientComment { color: #00ffff; }
.cSpecial { color: #008000; }
+.PreProc { color: #c000c0; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
.Identifier { color: #804000; }
.Constant { color: #00a0a0; }
-.traceContains { color: #008000; }
-->
</style>
@@ -77,6 +77,9 @@ struct call <span class="Delimiter">{</span>
running_step_index = <span class="Constant">0</span><span class="Delimiter">;</span>
<span class="Comment">// End call Constructor</span>
<span class="Delimiter">}</span>
+ ~call<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+ <span class="Comment">// End call Destructor</span>
+ <span class="Delimiter">}</span>
<span class="Delimiter">};</span>
typedef list<call> call_stack<span class="Delimiter">;</span>
@@ -90,57 +93,80 @@ struct routine <span class="Delimiter">{</span>
<span class="Delimiter">};</span>
<span class="Delimiter">:(code)</span>
routine::routine<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ ++Trace_stream<span class="Delimiter">-></span>callstack_depth<span class="Delimiter">;</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"trace"</span><span class="Delimiter">)</span> << <span class="Constant">"new routine; incrementing callstack depth to "</span> << Trace_stream<span class="Delimiter">-></span>callstack_depth << end<span class="Delimiter">();</span>
+ assert<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>callstack_depth < <span class="Constant">9000</span><span class="Delimiter">);</span> <span class="Comment">// 9998-101 plus cushion</span>
+ <span class="Delimiter">}</span>
calls<span class="Delimiter">.</span>push_front<span class="Delimiter">(</span>call<span class="Delimiter">(</span>r<span class="Delimiter">));</span>
<span class="Comment">// End routine Constructor</span>
<span class="Delimiter">}</span>
+<span class="Delimiter">:(code)</span>
+inline call& current_call<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+ <span class="Identifier">return</span> Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">();</span>
+<span class="Delimiter">}</span>
+
<span class="SalientComment">//:: now update routine's helpers</span>
<span class="Delimiter">:(replace{} "inline long long int& current_step_index()")</span>
inline long long int& current_step_index<span class="Delimiter">()</span> <span class="Delimiter">{</span>
assert<span class="Delimiter">(</span>!Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
- <span class="Identifier">return</span> Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_step_index<span class="Delimiter">;</span>
+ <span class="Identifier">return</span> current_call<span class="Delimiter">().</span>running_step_index<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(replace{} "inline const string& current_recipe_name()")</span>
inline const string& current_recipe_name<span class="Delimiter">()</span> <span class="Delimiter">{</span>
assert<span class="Delimiter">(</span>!Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
- <span class="Identifier">return</span> Recipe[Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_recipe]<span class="Delimiter">.</span>name<span class="Delimiter">;</span>
+ <span class="Identifier">return</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> current_call<span class="Delimiter">().</span>running_recipe<span class="Delimiter">).</span>name<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(replace{} "inline const instruction& current_instruction()")</span>
inline const instruction& current_instruction<span class="Delimiter">()</span> <span class="Delimiter">{</span>
assert<span class="Delimiter">(</span>!Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
- <span class="Identifier">return</span> Recipe[Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_recipe]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_step_index<span class="Delimiter">);</span>
+ <span class="Identifier">return</span> to_instruction<span class="Delimiter">(</span>current_call<span class="Delimiter">());</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(code)</span>
+inline const instruction& to_instruction<span class="Delimiter">(</span>const call& call<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ <span class="Identifier">return</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> call<span class="Delimiter">.</span>running_recipe<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>call<span class="Delimiter">.</span>running_step_index<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
+<span class="Delimiter">:(after "Defined Recipe Checks")</span>
+<span class="Comment">// not a primitive; check that it's present in the book of recipes</span>
+if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>operation<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"undefined operation in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(replace{} "default:" following "End Primitive Recipe Implementations")</span>
default: <span class="Delimiter">{</span>
- <span class="Comment">// not a primitive; try to look up the book of recipes</span>
- if <span class="Delimiter">(</span>Recipe<span class="Delimiter">.</span>find<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>operation<span class="Delimiter">)</span> == Recipe<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": undefined operation in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ const instruction& call_instruction = current_instruction<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>Recipe<span class="Delimiter">.</span>find<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>operation<span class="Delimiter">)</span> == Recipe<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> <span class="Comment">// duplicate from Checks</span>
<span class="Comment">// stop running this instruction immediately</span>
++current_step_index<span class="Delimiter">();</span>
<span class="Identifier">continue</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+ <span class="Comment">// not a primitive; look up the book of recipes</span>
+ if <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ ++Trace_stream<span class="Delimiter">-></span>callstack_depth<span class="Delimiter">;</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"trace"</span><span class="Delimiter">)</span> << <span class="Constant">"incrementing callstack depth to "</span> << Trace_stream<span class="Delimiter">-></span>callstack_depth << end<span class="Delimiter">();</span>
+ assert<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>callstack_depth < <span class="Constant">9000</span><span class="Delimiter">);</span> <span class="Comment">// 9998-101 plus cushion</span>
+ <span class="Delimiter">}</span>
Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>push_front<span class="Delimiter">(</span>call<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>operation<span class="Delimiter">));</span>
- call_housekeeping:
- ++Callstack_depth<span class="Delimiter">;</span>
- assert<span class="Delimiter">(</span>Callstack_depth < <span class="Constant">9000</span><span class="Delimiter">);</span> <span class="Comment">// 9998-101 plus cushion</span>
+ <span class="Comment">// End Call Housekeeping</span>
<span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Comment">// not done with caller; don't increment current_step_index()</span>
<span class="Delimiter">}</span>
-<span class="Delimiter">:(scenario calling_undefined_recipe_warns)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Delimiter">:(scenario calling_undefined_recipe_fails)</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
foo
]
-<span class="traceContains">+warn: main: undefined operation in 'foo '</span>
+<span class="traceContains">+error: main: undefined operation in 'foo '</span>
<span class="Delimiter">:(scenario calling_undefined_recipe_handles_missing_result)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
x:number<span class="Special"> <- </span>foo
]
-<span class="traceContains">+warn: main: undefined operation in 'x:number <- foo '</span>
+<span class="traceContains">+error: main: undefined operation in 'x:number <- foo '</span>
<span class="SalientComment">//:: finally, we need to fix the termination conditions for the run loop</span>
@@ -151,7 +177,7 @@ inline bool routine::completed<span class="Delimiter">()</span> const <span clas
inline const vector<instruction>& routine::steps<span class="Delimiter">()</span> const <span class="Delimiter">{</span>
assert<span class="Delimiter">(</span>!calls<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
- <span class="Identifier">return</span> Recipe[calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_recipe]<span class="Delimiter">.</span>steps<span class="Delimiter">;</span>
+ <span class="Identifier">return</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_recipe<span class="Delimiter">).</span>steps<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(before "Running One Instruction")</span>
@@ -159,11 +185,15 @@ inline const vector<instruction>& routine::steps<span class="Delimiter
<span class="Comment">// it, and the one below that, and so on</span>
while <span class="Delimiter">(</span>current_step_index<span class="Delimiter">()</span> >= SIZE<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>steps<span class="Delimiter">()))</span> <span class="Delimiter">{</span>
<span class="Comment">// Falling Through End Of Recipe</span>
- --Callstack_depth<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"trace"</span><span class="Delimiter">)</span> << <span class="Constant">"fall-through: exiting "</span> << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">"; decrementing callstack depth from "</span> << Trace_stream<span class="Delimiter">-></span>callstack_depth << end<span class="Delimiter">();</span>
+ --Trace_stream<span class="Delimiter">-></span>callstack_depth<span class="Delimiter">;</span>
+ assert<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>callstack_depth >= <span class="Constant">0</span><span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>pop_front<span class="Delimiter">();</span>
if <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
<span class="Comment">// Complete Call Fallthrough</span>
- <span class="Comment">// todo: no products returned warning</span>
+ <span class="Comment">// todo: fail if no products returned</span>
++current_step_index<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
diff --git a/html/035call_ingredient.cc.html b/html/035call_ingredient.cc.html
index 517cf646..104c66dc 100644
--- a/html/035call_ingredient.cc.html
+++ b/html/035call_ingredient.cc.html
@@ -13,13 +13,13 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.traceContains { color: #008000; }
.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
.Identifier { color: #804000; }
.Constant { color: #00a0a0; }
-.traceContains { color: #008000; }
-->
</style>
@@ -55,41 +55,79 @@ recipe f [
<span class="Delimiter">:(before "End call Fields")</span>
vector<vector<double> > ingredient_atoms<span class="Delimiter">;</span>
+vector<type_tree*> ingredient_types<span class="Delimiter">;</span>
long long int next_ingredient_to_process<span class="Delimiter">;</span>
<span class="Delimiter">:(before "End call Constructor")</span>
next_ingredient_to_process = <span class="Constant">0</span><span class="Delimiter">;</span>
-<span class="Delimiter">:(after "call_housekeeping:")</span>
+<span class="Delimiter">:(before "End Call Housekeeping")</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
+ current_call<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
+ reagent ingredient = call_instruction<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ canonize_type<span class="Delimiter">(</span>ingredient<span class="Delimiter">);</span>
+ current_call<span class="Delimiter">().</span>ingredient_types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>ingredient<span class="Delimiter">.</span>type<span class="Delimiter">);</span>
+ ingredient<span class="Delimiter">.</span>type = <span class="Constant">NULL</span><span class="Delimiter">;</span> <span class="Comment">// release long-lived pointer</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End call Destructor")</span>
+for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>ingredient_types<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ delete ingredient_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
NEXT_INGREDIENT<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"next-ingredient"</span>] = NEXT_INGREDIENT<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"next-ingredient"</span><span class="Delimiter">,</span> NEXT_INGREDIENT<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case NEXT_INGREDIENT: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'next-ingredient' didn't expect any ingredients in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'next-ingredient' didn't expect any ingredients in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case NEXT_INGREDIENT: <span class="Delimiter">{</span>
assert<span class="Delimiter">(</span>!Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
- if <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>next_ingredient_to_process < SIZE<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>next_ingredient_to_process < SIZE<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ reagent product = current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ canonize_type<span class="Delimiter">(</span>product<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>product<span class="Delimiter">,</span>
+ current_call<span class="Delimiter">().</span>ingredient_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">),</span>
+ current_call<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>at<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">)</span>
+ <span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"wrong type for ingredient "</span> << current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Delimiter">}</span>
products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>
- Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>at<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">));</span>
+ current_call<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>at<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">));</span>
assert<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>products<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">);</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">);</span> <span class="Comment">// push a new vector</span>
products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
- ++Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">;</span>
+ ++current_call<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
else <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">)</span> < <span class="Constant">2</span><span class="Delimiter">)</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"no ingredient to save in "</span> << current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">);</span>
- products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> <span class="Comment">// todo: will fail noisily if we try to read a compound value</span>
+ <span class="Comment">// pad the first product with sufficient zeros to match its type</span>
+ long long int size = size_of<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < size<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
<span class="Delimiter">}</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+<span class="Delimiter">:(scenario next_ingredient_fail_on_missing)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+ f
+]
+recipe f [
+ <span class="Constant">11</span>:number<span class="Special"> <- </span>next-ingredient
+]
+<span class="traceContains">+error: f: no ingredient to save in 11:number</span>
+
<span class="Delimiter">:(scenario rewind_ingredients)</span>
recipe main [
f <span class="Constant">2</span>
@@ -108,10 +146,14 @@ recipe f [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
REWIND_INGREDIENTS<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"rewind-ingredients"</span>] = REWIND_INGREDIENTS<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"rewind-ingredients"</span><span class="Delimiter">,</span> REWIND_INGREDIENTS<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case REWIND_INGREDIENTS: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case REWIND_INGREDIENTS: <span class="Delimiter">{</span>
- Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>next_ingredient_to_process = <span class="Constant">0</span><span class="Delimiter">;</span>
+ current_call<span class="Delimiter">().</span>next_ingredient_to_process = <span class="Constant">0</span><span class="Delimiter">;</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -129,25 +171,28 @@ recipe f [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
INGREDIENT<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"ingredient"</span>] = INGREDIENT<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"ingredient"</span><span class="Delimiter">,</span> INGREDIENT<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case INGREDIENT: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'ingredient' expects exactly one ingredient, but got '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ 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>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'ingredient' expects exactly one ingredient, but got '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'ingredient' expects a literal ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> && !is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'ingredient' expects a literal ingredient, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
- if <span class="Delimiter">(</span>static_cast<long long int><span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> < SIZE<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">))</span> <span class="Delimiter">{</span>
- Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>next_ingredient_to_process = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case INGREDIENT: <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>static_cast<long long int><span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> < SIZE<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ current_call<span class="Delimiter">().</span>next_ingredient_to_process = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>
- Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>at<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">));</span>
+ current_call<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>at<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">));</span>
assert<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>products<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">);</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">);</span> <span class="Comment">// push a new vector</span>
products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
- ++Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">;</span>
+ ++current_call<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
else <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
diff --git a/html/036call_reply.cc.html b/html/036call_reply.cc.html
index bdc9cb07..45622e07 100644
--- a/html/036call_reply.cc.html
+++ b/html/036call_reply.cc.html
@@ -13,13 +13,13 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.traceContains { color: #008000; }
.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
.Identifier { color: #804000; }
.Constant { color: #00a0a0; }
-.traceContains { color: #008000; }
-->
</style>
@@ -48,36 +48,58 @@ recipe f [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
REPLY<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"reply"</span>] = REPLY<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"reply"</span><span class="Delimiter">,</span> REPLY<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case REPLY: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Comment">// continue to process rest of *caller* instruction</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case REPLY: <span class="Delimiter">{</span>
<span class="Comment">// Starting Reply</span>
const instruction& reply_inst = current_instruction<span class="Delimiter">();</span> <span class="Comment">// save pointer into recipe before pop</span>
const string& callee = current_recipe_name<span class="Delimiter">();</span>
- --Callstack_depth<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"trace"</span><span class="Delimiter">)</span> << <span class="Constant">"reply: decrementing callstack depth from "</span> << Trace_stream<span class="Delimiter">-></span>callstack_depth << end<span class="Delimiter">();</span>
+ --Trace_stream<span class="Delimiter">-></span>callstack_depth<span class="Delimiter">;</span>
+ assert<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>callstack_depth >= <span class="Constant">0</span><span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>pop_front<span class="Delimiter">();</span>
<span class="Comment">// just in case 'main' returns a value, drop it for now</span>
if <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">goto</span> stop_running_current_routine<span class="Delimiter">;</span>
const instruction& caller_instruction = current_instruction<span class="Delimiter">();</span>
+ <span class="Comment">// check types with the caller</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">)</span> > SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << <span class="Constant">"too few values replied from "</span> << callee << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> reply_inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>callee<span class="Delimiter">)</span> << <span class="Constant">"reply ingredient "</span> << reply_inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="Constant">" can't be saved in "</span> << caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ reagent lhs = reply_inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ canonize_type<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span>
+ reagent rhs = caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ canonize_type<span class="Delimiter">(</span>rhs<span class="Delimiter">);</span>
+ raise_error << debug_string<span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="Constant">" vs "</span> << debug_string<span class="Delimiter">(</span>rhs<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">goto</span> finish_reply<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
<span class="Comment">// make reply products available to caller</span>
copy<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> ingredients<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> inserter<span class="Delimiter">(</span>products<span class="Delimiter">,</span> products<span class="Delimiter">.</span>begin<span class="Delimiter">()));</span>
<span class="Comment">// check that any reply ingredients with /same-as-ingredient connect up</span>
<span class="Comment">// the corresponding ingredient and product in the caller.</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">)</span> > SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">))</span>
- raise << <span class="Constant">"too few values replied from "</span> << callee << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"result "</span> << i << <span class="Constant">" is "</span> << to_string<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"result "</span> << i << <span class="Constant">" is "</span> << to_string<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> << end<span class="Delimiter">();</span>
if <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>reply_inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> <span class="Constant">"same-as-ingredient"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
- vector<string> tmp = property<span class="Delimiter">(</span>reply_inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> <span class="Constant">"same-as-ingredient"</span><span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>tmp<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'same-as-ingredient' metadata should take exactly one value in "</span> << reply_inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ string_tree* tmp = property<span class="Delimiter">(</span>reply_inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> <span class="Constant">"same-as-ingredient"</span><span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!tmp || tmp<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"'same-as-ingredient' metadata should take exactly one value in "</span> << reply_inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">goto</span> finish_reply<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- long long int ingredient_index = to_integer<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
+ long long int ingredient_index = to_integer<span class="Delimiter">(</span>tmp<span class="Delimiter">-></span>value<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>ingredient_index >= SIZE<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>ingredients<span class="Delimiter">))</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'same-as-ingredient' metadata overflows ingredients in: "</span> << caller_instruction<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"'same-as-ingredient' metadata overflows ingredients in: "</span> << caller_instruction<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
if <span class="Delimiter">(</span>!is_dummy<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> && caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>value != caller_instruction<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>ingredient_index<span class="Delimiter">).</span>value<span class="Delimiter">)</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'same-as-ingredient' product from call to "</span> << callee << <span class="Constant">" must be "</span> << caller_instruction<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>ingredient_index<span class="Delimiter">).</span>original_string << <span class="Constant">" rather than "</span> << caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"'"</span> << caller_instruction<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"' should write to "</span> << caller_instruction<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>ingredient_index<span class="Delimiter">).</span>original_string << <span class="Constant">" rather than "</span> << caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
<span class="Comment">// End Reply</span>
@@ -93,53 +115,66 @@ recipe main [
recipe f [
<span class="Constant">12</span>:number<span class="Special"> <- </span>next-ingredient
<span class="Constant">13</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span>
- reply <span class="Constant">12</span>:point/<span class="Special">raw</span> <span class="Comment"># unsafe</span>
+ reply <span class="Constant">12</span>:point/<span class="Special">raw</span>
]
<span class="traceContains">+run: result 0 is [2, 35]</span>
<span class="traceContains">+mem: storing 2 in location 3</span>
<span class="traceContains">+mem: storing 35 in location 4</span>
+<span class="Delimiter">:(scenario reply_type_mismatch)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+ <span class="Constant">3</span>:number<span class="Special"> <- </span>f <span class="Constant">2</span>
+]
+recipe f [
+ <span class="Constant">12</span>:number<span class="Special"> <- </span>next-ingredient
+ <span class="Constant">13</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span>
+ <span class="Constant">14</span>:point<span class="Special"> <- </span>copy <span class="Constant">12</span>:point/<span class="Special">raw</span>
+ reply <span class="Constant">14</span>:point
+]
+<span class="traceContains">+error: f: reply ingredient 14:point can't be saved in 3:number</span>
+
<span class="Comment">//: In mu we'd like to assume that any instruction doesn't modify its</span>
<span class="Comment">//: ingredients unless they're also products. The /same-as-ingredient inside</span>
<span class="Comment">//: the recipe's 'reply' will help catch accidental misuse of such</span>
<span class="Comment">//: 'ingredient-products' (sometimes called in-out parameters in other languages).</span>
<span class="Delimiter">:(scenario reply_same_as_ingredient)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
<span class="Constant">2</span>:number<span class="Special"> <- </span>test1 <span class="Constant">1</span>:number <span class="Comment"># call with different ingredient and product</span>
]
recipe test1 [
- <span class="Constant">10</span>:address:number<span class="Special"> <- </span>next-ingredient
- reply <span class="Constant">10</span>:address:number/same-as-ingredient:<span class="Constant">0</span>
+ <span class="Constant">10</span>:number<span class="Special"> <- </span>next-ingredient
+ reply <span class="Constant">10</span>:number/same-as-ingredient:<span class="Constant">0</span>
]
-<span class="traceContains">+warn: main: 'same-as-ingredient' product from call to test1 must be 1:number rather than 2:number</span>
+<span class="traceContains">+error: main: '2:number <- test1 1:number' should write to 1:number rather than 2:number</span>
<span class="Delimiter">:(scenario reply_same_as_ingredient_dummy)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Comment"># % Hide_errors = true;</span>
recipe main [
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
_<span class="Special"> <- </span>test1 <span class="Constant">1</span>:number <span class="Comment"># call with different ingredient and product</span>
]
recipe test1 [
- <span class="Constant">10</span>:address:number<span class="Special"> <- </span>next-ingredient
- reply <span class="Constant">10</span>:address:number/same-as-ingredient:<span class="Constant">0</span>
+ <span class="Constant">10</span>:number<span class="Special"> <- </span>next-ingredient
+ reply <span class="Constant">10</span>:number/same-as-ingredient:<span class="Constant">0</span>
]
-$warn: <span class="Constant">0</span>
+$error: <span class="Constant">0</span>
<span class="Delimiter">:(code)</span>
string to_string<span class="Delimiter">(</span>const vector<double>& in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">"[]"</span><span class="Delimiter">;</span>
ostringstream out<span class="Delimiter">;</span>
if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>in<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- out << in<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ out << no_scientific<span class="Delimiter">(</span>in<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
<span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
out << <span class="Constant">"["</span><span class="Delimiter">;</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>in<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>i > <span class="Constant">0</span><span class="Delimiter">)</span> out << <span class="Constant">", "</span><span class="Delimiter">;</span>
- out << in<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ out << no_scientific<span class="Delimiter">(</span>in<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
<span class="Delimiter">}</span>
out << <span class="Constant">"]"</span><span class="Delimiter">;</span>
<span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
@@ -167,7 +202,7 @@ recipe test1 [
]
<span class="traceContains">+mem: storing 34 in location 1</span>
-<span class="Delimiter">:(before "End Rewrite Instruction(curr)")</span>
+<span class="Delimiter">:(before "End Rewrite Instruction(curr, recipe result)")</span>
<span class="Comment">// rewrite `reply-if a, b, c, ...` to</span>
<span class="Comment">// ```</span>
<span class="Comment">// jump-unless a, 1:offset</span>
@@ -175,7 +210,7 @@ recipe test1 [
<span class="Comment">// ```</span>
if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"reply-if"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- curr<span class="Delimiter">.</span>operation = Recipe_ordinal[<span class="Constant">"jump-unless"</span>]<span class="Delimiter">;</span>
+ curr<span class="Delimiter">.</span>operation = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"jump-unless"</span><span class="Delimiter">);</span>
curr<span class="Delimiter">.</span>name = <span class="Constant">"jump-unless"</span><span class="Delimiter">;</span>
vector<reagent> results<span class="Delimiter">;</span>
copy<span class="Delimiter">(</span>++curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> inserter<span class="Delimiter">(</span>results<span class="Delimiter">,</span> results<span class="Delimiter">.</span>end<span class="Delimiter">()));</span>
@@ -183,12 +218,12 @@ if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <
curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span><span class="Constant">"1:offset"</span><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>
curr<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
- curr<span class="Delimiter">.</span>operation = Recipe_ordinal[<span class="Constant">"reply"</span>]<span class="Delimiter">;</span>
+ curr<span class="Delimiter">.</span>operation = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"reply"</span><span class="Delimiter">);</span>
curr<span class="Delimiter">.</span>name = <span class="Constant">"reply"</span><span class="Delimiter">;</span>
curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>swap<span class="Delimiter">(</span>results<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
else <span class="Delimiter">{</span>
- raise << <span class="Constant">"'reply-if' never yields any products</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"'reply-if' never yields any products</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
<span class="Comment">// rewrite `reply-unless a, b, c, ...` to</span>
@@ -198,7 +233,7 @@ if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <
<span class="Comment">// ```</span>
if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"reply-unless"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- curr<span class="Delimiter">.</span>operation = Recipe_ordinal[<span class="Constant">"jump-if"</span>]<span class="Delimiter">;</span>
+ curr<span class="Delimiter">.</span>operation = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"jump-if"</span><span class="Delimiter">);</span>
curr<span class="Delimiter">.</span>name = <span class="Constant">"jump-if"</span><span class="Delimiter">;</span>
vector<reagent> results<span class="Delimiter">;</span>
copy<span class="Delimiter">(</span>++curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> inserter<span class="Delimiter">(</span>results<span class="Delimiter">,</span> results<span class="Delimiter">.</span>end<span class="Delimiter">()));</span>
@@ -206,12 +241,12 @@ if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <
curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span><span class="Constant">"1:offset"</span><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>
curr<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
- curr<span class="Delimiter">.</span>operation = Recipe_ordinal[<span class="Constant">"reply"</span>]<span class="Delimiter">;</span>
+ curr<span class="Delimiter">.</span>operation = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"reply"</span><span class="Delimiter">);</span>
curr<span class="Delimiter">.</span>name = <span class="Constant">"reply"</span><span class="Delimiter">;</span>
curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>swap<span class="Delimiter">(</span>results<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
else <span class="Delimiter">{</span>
- raise << <span class="Constant">"'reply-unless' never yields any products</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"'reply-unless' never yields any products</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
</pre>
diff --git a/html/037recipe.cc.html b/html/037recipe.cc.html
index 856e671c..44573495 100644
--- a/html/037recipe.cc.html
+++ b/html/037recipe.cc.html
@@ -13,13 +13,10 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
-.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
-.Special { color: #ff6060; }
.Identifier { color: #804000; }
.Constant { color: #00a0a0; }
-.traceContains { color: #008000; }
-->
</style>
@@ -35,61 +32,26 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment">//: also like to make the recipe a variable, pass recipes to "higher-order"</span>
<span class="Comment">//: recipes, return recipes from recipes and so on.</span>
-<span class="Delimiter">:(scenario call_literal_recipe)</span>
-recipe main [
- <span class="Constant">1</span>:number<span class="Special"> <- </span>call f:recipe<span class="Delimiter">,</span> <span class="Constant">34</span>
-]
-recipe f [
- <span class="Constant">2</span>:number<span class="Special"> <- </span>next-ingredient
- reply <span class="Constant">2</span>:number
-]
-<span class="traceContains">+mem: storing 34 in location 1</span>
-
-<span class="Delimiter">:(scenario call_variable)</span>
-recipe main [
- <span class="Constant">1</span>:recipe-ordinal<span class="Special"> <- </span>copy f:recipe
- <span class="Constant">2</span>:number<span class="Special"> <- </span>call <span class="Constant">1</span>:recipe-ordinal<span class="Delimiter">,</span> <span class="Constant">34</span>
-]
-recipe f [
- <span class="Constant">3</span>:number<span class="Special"> <- </span>next-ingredient
- reply <span class="Constant">3</span>:number
-]
-<span class="traceContains">+mem: storing 34 in location 2</span>
-
<span class="Delimiter">:(before "End Mu Types Initialization")</span>
<span class="Comment">// 'recipe' is a literal</span>
-Type_ordinal[<span class="Constant">"recipe"</span>] = <span class="Constant">0</span><span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"recipe"</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span>
<span class="Comment">// 'recipe-ordinal' is the literal that can store recipe literals</span>
-type_ordinal recipe_ordinal = Type_ordinal[<span class="Constant">"recipe-ordinal"</span>] = Next_type_ordinal++<span class="Delimiter">;</span>
-Type[recipe_ordinal]<span class="Delimiter">.</span>name = <span class="Constant">"recipe-ordinal"</span><span class="Delimiter">;</span>
+type_ordinal recipe_ordinal = put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"recipe-ordinal"</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_ordinal<span class="Delimiter">).</span>name = <span class="Constant">"recipe-ordinal"</span><span class="Delimiter">;</span>
<span class="Delimiter">:(before "End Reagent-parsing Exceptions")</span>
-if <span class="Delimiter">(</span>!r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">"recipe"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- r<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>Recipe_ordinal[r<span class="Delimiter">.</span>name]<span class="Delimiter">);</span>
+if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second && r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">-></span>value == <span class="Constant">"recipe"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ r<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> r<span class="Delimiter">.</span>name<span class="Delimiter">));</span>
<span class="Identifier">return</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
-<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
-CALL<span class="Delimiter">,</span>
-<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"call"</span>] = CALL<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
-case CALL: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'call' requires at least one ingredient (the recipe to call)</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- <span class="Comment">// Begin Call</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'call' should be a recipe, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- <span class="Comment">// todo: when we start doing type checking this will be a prime point of</span>
- <span class="Comment">// attention, so we don't accidentally allow external data to a program to</span>
- <span class="Comment">// run as code.</span>
- Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>push_front<span class="Delimiter">(</span>call<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
- ingredients<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>begin<span class="Delimiter">());</span> <span class="Comment">// drop the callee</span>
- <span class="Identifier">goto</span> call_housekeeping<span class="Delimiter">;</span>
+<span class="Delimiter">:(code)</span>
+bool is_mu_recipe<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>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">"recipe"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</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">"recipe-ordinal"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+ <span class="Comment">// End is_mu_recipe Cases</span>
+ <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
</pre>
</body>
diff --git a/html/038scheduler.cc.html b/html/038scheduler.cc.html
index 3a258741..16b3efbb 100644
--- a/html/038scheduler.cc.html
+++ b/html/038scheduler.cc.html
@@ -13,15 +13,15 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
-.SalientComment { color: #00ffff; }
+.traceContains { color: #008000; }
.traceAbsent { color: #c00000; }
+.SalientComment { color: #00ffff; }
.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
.Identifier { color: #804000; }
.Constant { color: #00a0a0; }
-.traceContains { color: #008000; }
-->
</style>
@@ -93,7 +93,7 @@ void run<span class="Delimiter">(</span>routine* rr<span class="Delimiter">)</sp
skip_to_next_routine<span class="Delimiter">();</span>
assert<span class="Delimiter">(</span>Current_routine<span class="Delimiter">);</span>
assert<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>state == RUNNING<span class="Delimiter">);</span>
- trace<span class="Delimiter">(</span><span class="Constant">"schedule"</span><span class="Delimiter">)</span> << current_routine_label<span class="Delimiter">()</span> << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9990</span><span class="Delimiter">,</span> <span class="Constant">"schedule"</span><span class="Delimiter">)</span> << current_routine_label<span class="Delimiter">()</span> << end<span class="Delimiter">();</span>
run_current_routine<span class="Delimiter">(</span>Scheduling_interval<span class="Delimiter">);</span>
<span class="Comment">// Scheduler State Transitions</span>
if <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>completed<span class="Delimiter">())</span>
@@ -129,10 +129,10 @@ void skip_to_next_routine<span class="Delimiter">()</span> <span class="Delimite
string current_routine_label<span class="Delimiter">()</span> <span class="Delimiter">{</span>
ostringstream result<span class="Delimiter">;</span>
- call_stack calls = Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">;</span>
- for <span class="Delimiter">(</span>call_stack::iterator p = calls<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != calls<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ const call_stack& calls = Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">;</span>
+ for <span class="Delimiter">(</span>call_stack::const_iterator p = calls<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != calls<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>p != calls<span class="Delimiter">.</span>begin<span class="Delimiter">())</span> result << <span class="Constant">'/'</span><span class="Delimiter">;</span>
- result << Recipe[p<span class="Delimiter">-></span>running_recipe]<span class="Delimiter">.</span>name<span class="Delimiter">;</span>
+ result << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> p<span class="Delimiter">-></span>running_recipe<span class="Delimiter">).</span>name<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Identifier">return</span> result<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
@@ -141,22 +141,16 @@ string current_routine_label<span class="Delimiter">()</span> <span class="Delim
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
delete Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
Routines<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+Current_routine = <span class="Constant">NULL</span><span class="Delimiter">;</span>
<span class="Comment">//: special case for the very first routine</span>
<span class="Delimiter">:(replace{} "void run_main(int argc, char* argv[])")</span>
void run_main<span class="Delimiter">(</span>int argc<span class="Delimiter">,</span> char* argv[]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- recipe_ordinal r = Recipe_ordinal[string<span class="Delimiter">(</span><span class="Constant">"main"</span><span class="Delimiter">)</span>]<span class="Delimiter">;</span>
+ recipe_ordinal r = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> string<span class="Delimiter">(</span><span class="Constant">"main"</span><span class="Delimiter">));</span>
if <span class="Delimiter">(</span>r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- <span class="Comment">// pass in commandline args as ingredients to main</span>
- <span class="Comment">// todo: test this</span>
- routine* rr = new routine<span class="Delimiter">(</span>r<span class="Delimiter">);</span>
- Current_routine = rr<span class="Delimiter">;</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">1</span><span class="Delimiter">;</span> i < argc<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- vector<double> arg<span class="Delimiter">;</span>
- arg<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_mu_string<span class="Delimiter">(</span>argv[i]<span class="Delimiter">));</span>
- Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>arg<span class="Delimiter">);</span>
- <span class="Delimiter">}</span>
- run<span class="Delimiter">(</span>rr<span class="Delimiter">);</span>
+ routine* main_routine = new routine<span class="Delimiter">(</span>r<span class="Delimiter">);</span>
+ <span class="Comment">// Update main_routine</span>
+ run<span class="Delimiter">(</span>main_routine<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
@@ -184,26 +178,31 @@ parent_index = -<span class="Constant">1</span><span class="Delimiter">;</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
START_RUNNING<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"start-running"</span>] = START_RUNNING<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"start-running"</span><span class="Delimiter">,</span> START_RUNNING<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case START_RUNNING: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"'start-running' requires at least one ingredient: the recipe to start running</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'start-running' requires at least one ingredient: the recipe to start running</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"first ingredient of 'start-running' should be a recipe, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>!ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"'start-running' received non-existent recipe: '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_recipe<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'start-running' should be a recipe, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="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">:(before "End Primitive Recipe Implementations")</span>
+case START_RUNNING: <span class="Delimiter">{</span>
routine* new_routine = new routine<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
new_routine<span class="Delimiter">-></span>parent_index = Current_routine_index<span class="Delimiter">;</span>
<span class="Comment">// populate ingredients</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
new_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
+ reagent ingredient = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ canonize_type<span class="Delimiter">(</span>ingredient<span class="Delimiter">);</span>
+ new_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>ingredient<span class="Delimiter">.</span>type<span class="Delimiter">);</span>
+ ingredient<span class="Delimiter">.</span>type = <span class="Constant">NULL</span><span class="Delimiter">;</span> <span class="Comment">// release long-lived pointer</span>
+ <span class="Delimiter">}</span>
Routines<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_routine<span class="Delimiter">);</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>new_routine<span class="Delimiter">-></span>id<span class="Delimiter">);</span>
@@ -243,7 +242,7 @@ recipe f2 [
<span class="traceContains">+schedule: f1</span>
<span class="traceContains">+run: 2:number <- copy 0</span>
-<span class="Delimiter">:(scenario start_running_takes_args)</span>
+<span class="Delimiter">:(scenario start_running_takes_ingredients)</span>
recipe f1 [
start-running f2:recipe<span class="Delimiter">,</span> <span class="Constant">3</span>
<span class="Comment"># wait for f2 to run</span>
@@ -296,6 +295,30 @@ recipe f1 [
<span class="traceContains">+schedule: f1</span>
<span class="traceAbsent">-run: idle</span>
+<span class="SalientComment">//:: Errors in a routine cause it to terminate.</span>
+
+<span class="Delimiter">:(scenario scheduler_terminates_routines_after_errors)</span>
+<span class="Special">% Hide_errors = true;</span>
+<span class="Special">% Scheduling_interval = 2;</span>
+recipe f1 [
+ start-running f2:recipe
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
+ <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
+]
+recipe f2 [
+ <span class="Comment"># divide by 0 twice</span>
+ <span class="Constant">3</span>:number<span class="Special"> <- </span>divide-with-remainder <span class="Constant">4</span><span class="Delimiter">,</span> <span class="Constant">0</span>
+ <span class="Constant">4</span>:number<span class="Special"> <- </span>divide-with-remainder <span class="Constant">4</span><span class="Delimiter">,</span> <span class="Constant">0</span>
+]
+<span class="Comment"># f2 should stop after first divide by 0</span>
+<span class="traceContains">+error: f2: divide by zero in '3:number <- divide-with-remainder 4, 0'</span>
+<span class="traceAbsent">-error: f2: divide by zero in '4:number <- divide-with-remainder 4, 0'</span>
+
+<span class="Delimiter">:(after "operator<<(ostream& os, unused end)")</span>
+ if <span class="Delimiter">(</span>Trace_stream && Trace_stream<span class="Delimiter">-></span>curr_label == <span class="Constant">"error"</span> && Current_routine<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ Current_routine<span class="Delimiter">-></span>state = COMPLETED<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+
<span class="SalientComment">//:: Routines are marked completed when their parent completes.</span>
<span class="Delimiter">:(scenario scheduler_kills_orphans)</span>
@@ -346,17 +369,21 @@ recipe f2 [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
ROUTINE_STATE<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"routine-state"</span>] = ROUTINE_STATE<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"routine-state"</span><span class="Delimiter">,</span> ROUTINE_STATE<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case ROUTINE_STATE: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'routine-state' requires exactly one ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ 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>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'routine-state' requires exactly one ingredient, but got "</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>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'routine-state' should be a routine id generated by 'start-running', but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'routine-state' should be a routine id generated by 'start-running', but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="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">:(before "End Primitive Recipe Implementations")</span>
+case ROUTINE_STATE: <span class="Delimiter">{</span>
long long int id = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
long long int result = -<span class="Constant">1</span><span class="Delimiter">;</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -375,17 +402,21 @@ case ROUTINE_STATE: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
RESTART<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"restart"</span>] = RESTART<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"restart"</span><span class="Delimiter">,</span> RESTART<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case RESTART: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'restart' requires exactly one ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ 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>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'restart' requires exactly one ingredient, but got "</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>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'restart' should be a routine id generated by 'start-running', but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'restart' should be a routine id generated by 'start-running', but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="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">:(before "End Primitive Recipe Implementations")</span>
+case RESTART: <span class="Delimiter">{</span>
long long int id = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>id == id<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -399,17 +430,21 @@ case RESTART: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
STOP<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"stop"</span>] = STOP<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"stop"</span><span class="Delimiter">,</span> STOP<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case STOP: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'stop' requires exactly one ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ 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>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'stop' requires exactly one ingredient, but got "</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>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'stop' should be a routine id generated by 'start-running', but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'stop' should be a routine id generated by 'start-running', but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="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">:(before "End Primitive Recipe Implementations")</span>
+case STOP: <span class="Delimiter">{</span>
long long int id = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>id == id<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -423,7 +458,11 @@ case STOP: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
_DUMP_ROUTINES<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"$dump-routines"</span>] = _DUMP_ROUTINES<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"$dump-routines"</span><span class="Delimiter">,</span> _DUMP_ROUTINES<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case _DUMP_ROUTINES: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case _DUMP_ROUTINES: <span class="Delimiter">{</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -456,7 +495,7 @@ DISCONTINUED<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Scheduler State Transitions")</span>
if <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>limit >= <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>limit <= Scheduling_interval<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- trace<span class="Delimiter">(</span><span class="Constant">"schedule"</span><span class="Delimiter">)</span> << <span class="Constant">"discontinuing routine "</span> << Current_routine<span class="Delimiter">-></span>id << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"schedule"</span><span class="Delimiter">)</span> << <span class="Constant">"discontinuing routine "</span> << Current_routine<span class="Delimiter">-></span>id << end<span class="Delimiter">();</span>
Current_routine<span class="Delimiter">-></span>state = DISCONTINUED<span class="Delimiter">;</span>
Current_routine<span class="Delimiter">-></span>limit = <span class="Constant">0</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -473,21 +512,25 @@ limit = -<span class="Constant">1</span><span class="Delimiter">;</span> <span
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
LIMIT_TIME<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"limit-time"</span>] = LIMIT_TIME<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"limit-time"</span><span class="Delimiter">,</span> LIMIT_TIME<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case LIMIT_TIME: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'limit-time' requires exactly two ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'limit-time' requires exactly two ingredient, but got "</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>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'limit-time' should be a routine id generated by 'start-running', but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'limit-time' should be a routine id generated by 'start-running', but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": second ingredient of 'limit-time' should be a number (of instructions to run for), but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"second ingredient of 'limit-time' should be a number (of instructions to run for), but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="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">:(before "End Primitive Recipe Implementations")</span>
+case LIMIT_TIME: <span class="Delimiter">{</span>
long long int id = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>id == id<span class="Delimiter">)</span> <span class="Delimiter">{</span>
diff --git a/html/039wait.cc.html b/html/039wait.cc.html
index dc19a3b3..057c54b6 100644
--- a/html/039wait.cc.html
+++ b/html/039wait.cc.html
@@ -13,8 +13,8 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
-.cSpecial { color: #008000; }
.traceContains { color: #008000; }
+.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
@@ -66,14 +66,19 @@ waiting_on_location = old_value_of_waiting_location = <span class="Constant">0</
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
WAIT_FOR_LOCATION<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"wait-for-location"</span>] = WAIT_FOR_LOCATION<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"wait-for-location"</span><span class="Delimiter">,</span> WAIT_FOR_LOCATION<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case WAIT_FOR_LOCATION: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case WAIT_FOR_LOCATION: <span class="Delimiter">{</span>
- reagent loc = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
+ reagent loc = 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>
+ canonize<span class="Delimiter">(</span>loc<span class="Delimiter">);</span>
Current_routine<span class="Delimiter">-></span>state = WAITING<span class="Delimiter">;</span>
Current_routine<span class="Delimiter">-></span>waiting_on_location = loc<span class="Delimiter">.</span>value<span class="Delimiter">;</span>
- Current_routine<span class="Delimiter">-></span>old_value_of_waiting_location = Memory[loc<span class="Delimiter">.</span>value]<span class="Delimiter">;</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"waiting for location "</span> << loc<span class="Delimiter">.</span>value << <span class="Constant">" to change from "</span> << Memory[loc<span class="Delimiter">.</span>value] << end<span class="Delimiter">();</span>
+ Current_routine<span class="Delimiter">-></span>old_value_of_waiting_location = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> loc<span class="Delimiter">.</span>value<span class="Delimiter">);</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"waiting for location "</span> << loc<span class="Delimiter">.</span>value << <span class="Constant">" to change from "</span> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> loc<span class="Delimiter">.</span>value<span class="Delimiter">))</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -83,8 +88,8 @@ case WAIT_FOR_LOCATION: <span class="Delimiter">{</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state != WAITING<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
if <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>waiting_on_location &&
- Memory[Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>waiting_on_location] != Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>old_value_of_waiting_location<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- trace<span class="Delimiter">(</span><span class="Constant">"schedule"</span><span class="Delimiter">)</span> << <span class="Constant">"waking up routine</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>waiting_on_location<span class="Delimiter">)</span> != Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>old_value_of_waiting_location<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"schedule"</span><span class="Delimiter">)</span> << <span class="Constant">"waking up routine</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state = RUNNING<span class="Delimiter">;</span>
Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>waiting_on_location = Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>old_value_of_waiting_location = <span class="Constant">0</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -120,24 +125,28 @@ waiting_on_routine = <span class="Constant">0</span><span class="Delimiter">;</s
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
WAIT_FOR_ROUTINE<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"wait-for-routine"</span>] = WAIT_FOR_ROUTINE<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"wait-for-routine"</span><span class="Delimiter">,</span> WAIT_FOR_ROUTINE<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case WAIT_FOR_ROUTINE: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'wait-for-routine' requires exactly one ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ 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>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'wait-for-routine' requires exactly one ingredient, but got "</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>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'wait-for-routine' should be a routine id generated by 'start-running', but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'wait-for-routine' should be a routine id generated by 'start-running', but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="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">:(before "End Primitive Recipe Implementations")</span>
+case WAIT_FOR_ROUTINE: <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == Current_routine<span class="Delimiter">-></span>id<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": routine can't wait for itself! "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"routine can't wait for itself! "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
Current_routine<span class="Delimiter">-></span>state = WAITING<span class="Delimiter">;</span>
Current_routine<span class="Delimiter">-></span>waiting_on_routine = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"waiting for routine "</span> << ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"waiting for routine "</span> << ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -152,7 +161,7 @@ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</
assert<span class="Delimiter">(</span>id != Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>id<span class="Delimiter">);</span> <span class="Comment">// routine can't wait on itself</span>
for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>Routines<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)-></span>id == id && Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)-></span>state != RUNNING<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- trace<span class="Delimiter">(</span><span class="Constant">"schedule"</span><span class="Delimiter">)</span> << <span class="Constant">"waking up routine "</span> << Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>id << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"schedule"</span><span class="Delimiter">)</span> << <span class="Constant">"waking up routine "</span> << Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>id << end<span class="Delimiter">();</span>
Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>state = RUNNING<span class="Delimiter">;</span>
Routines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>waiting_on_routine = <span class="Constant">0</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -162,7 +171,11 @@ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
SWITCH<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"switch"</span>] = SWITCH<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"switch"</span><span class="Delimiter">,</span> SWITCH<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case SWITCH: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case SWITCH: <span class="Delimiter">{</span>
long long int id = some_other_running_routine<span class="Delimiter">();</span>
diff --git a/html/040brace.cc.html b/html/040brace.cc.html
index eb62a889..6f994e22 100644
--- a/html/040brace.cc.html
+++ b/html/040brace.cc.html
@@ -13,13 +13,14 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.traceContains { color: #008000; }
.cSpecial { color: #008000; }
+.CommentedCode { color: #6c6c6c; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
.Identifier { color: #804000; }
.Constant { color: #00a0a0; }
-.traceContains { color: #008000; }
-->
</style>
@@ -60,99 +61,108 @@ recipe main [
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
<span class="Delimiter">}</span>
]
-<span class="traceContains">+after-brace: recipe main</span>
-<span class="traceContains">+after-brace: jump 1:offset</span>
-<span class="traceContains">+after-brace: copy ...</span>
+<span class="traceContains">+transform: --- transform braces for recipe main</span>
+<span class="traceContains">+transform: jump 1:offset</span>
+<span class="traceContains">+transform: copy ...</span>
-<span class="Comment">//: one-time setup</span>
-<span class="Delimiter">:(after "int main")</span>
- Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>transform_braces<span class="Delimiter">);</span>
+<span class="Delimiter">:(after "Begin Transforms")</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>transform_braces<span class="Delimiter">);</span> <span class="Comment">// idempotent</span>
<span class="Delimiter">:(code)</span>
void transform_braces<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
const int OPEN = <span class="Constant">0</span><span class="Delimiter">,</span> CLOSE = <span class="Constant">1</span><span class="Delimiter">;</span>
<span class="Comment">// use signed integer for step index because we'll be doing arithmetic on it</span>
list<pair<int<span class="Comment">/*</span><span class="Comment">OPEN/CLOSE</span><span class="Comment">*/</span><span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">step</span><span class="Comment">*/</span>long long int> > braces<span class="Delimiter">;</span>
- for <span class="Delimiter">(</span>long long int index = <span class="Constant">0</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- const instruction& inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"--- transform braces for recipe "</span> << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name << end<span class="Delimiter">();</span>
+<span class="CommentedCode">//? cerr << "--- transform braces for recipe " << get(Recipe, r).name << '\n';</span>
+ for <span class="Delimiter">(</span>long long int index = <span class="Constant">0</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ const instruction& inst = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label == <span class="Constant">"{"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- trace<span class="Delimiter">(</span><span class="Constant">"brace"</span><span class="Delimiter">)</span> << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": push (open, "</span> << index << <span class="Constant">")"</span> << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"push (open, "</span> << index << <span class="Constant">")"</span> << end<span class="Delimiter">();</span>
braces<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<int<span class="Delimiter">,</span>long long int><span class="Delimiter">(</span>OPEN<span class="Delimiter">,</span> index<span class="Delimiter">));</span>
<span class="Delimiter">}</span>
if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label == <span class="Constant">"}"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- trace<span class="Delimiter">(</span><span class="Constant">"brace"</span><span class="Delimiter">)</span> << <span class="Constant">"push (close, "</span> << index << <span class="Constant">")"</span> << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"push (close, "</span> << index << <span class="Constant">")"</span> << end<span class="Delimiter">();</span>
braces<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<int<span class="Delimiter">,</span>long long int><span class="Delimiter">(</span>CLOSE<span class="Delimiter">,</span> index<span class="Delimiter">));</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
stack<<span class="Comment">/*</span><span class="Comment">step</span><span class="Comment">*/</span>long long int> open_braces<span class="Delimiter">;</span>
- trace<span class="Delimiter">(</span><span class="Constant">"after-brace"</span><span class="Delimiter">)</span> << <span class="Constant">"recipe "</span> << Recipe[r]<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span>
- for <span class="Delimiter">(</span>long long int index = <span class="Constant">0</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- instruction& inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span>
+ for <span class="Delimiter">(</span>long long int index = <span class="Constant">0</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ instruction& inst = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label == <span class="Constant">"{"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
open_braces<span class="Delimiter">.</span>push<span class="Delimiter">(</span>index<span class="Delimiter">);</span>
<span class="Identifier">continue</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label == <span class="Constant">"}"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>open_braces<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+ raise << <span class="Constant">"missing '{' in "</span> << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
open_braces<span class="Delimiter">.</span>pop<span class="Delimiter">();</span>
<span class="Identifier">continue</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>is_label<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation != Recipe_ordinal[<span class="Constant">"loop"</span>]
- && inst<span class="Delimiter">.</span>operation != Recipe_ordinal[<span class="Constant">"loop-if"</span>]
- && inst<span class="Delimiter">.</span>operation != Recipe_ordinal[<span class="Constant">"loop-unless"</span>]
- && inst<span class="Delimiter">.</span>operation != Recipe_ordinal[<span class="Constant">"break"</span>]
- && inst<span class="Delimiter">.</span>operation != Recipe_ordinal[<span class="Constant">"break-if"</span>]
- && inst<span class="Delimiter">.</span>operation != Recipe_ordinal[<span class="Constant">"break-unless"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- trace<span class="Delimiter">(</span><span class="Constant">"after-brace"</span><span class="Delimiter">)</span> << inst<span class="Delimiter">.</span>name << <span class="Constant">" ..."</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>old_name != <span class="Constant">"loop"</span>
+ && inst<span class="Delimiter">.</span>old_name != <span class="Constant">"loop-if"</span>
+ && inst<span class="Delimiter">.</span>old_name != <span class="Constant">"loop-unless"</span>
+ && inst<span class="Delimiter">.</span>old_name != <span class="Constant">"break"</span>
+ && inst<span class="Delimiter">.</span>old_name != <span class="Constant">"break-if"</span>
+ && inst<span class="Delimiter">.</span>old_name != <span class="Constant">"break-unless"</span><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> << inst<span class="Delimiter">.</span>old_name << <span class="Constant">" ..."</span> << end<span class="Delimiter">();</span>
<span class="Identifier">continue</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Comment">// check for errors</span>
- if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-if"</span><span class="Delimiter">)</span> != string::npos || inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-unless"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>old_name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-if"</span><span class="Delimiter">)</span> != string::npos || inst<span class="Delimiter">.</span>old_name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-unless"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- raise << inst<span class="Delimiter">.</span>name << <span class="Constant">" expects 1 or 2 ingredients, but got none</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << inst<span class="Delimiter">.</span>old_name << <span class="Constant">" expects 1 or 2 ingredients, but got none</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">continue</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
<span class="Comment">// update instruction operation</span>
- if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-if"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span>
- inst<span class="Delimiter">.</span>operation = Recipe_ordinal[<span class="Constant">"jump-if"</span>]<span class="Delimiter">;</span>
- else if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-unless"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span>
- inst<span class="Delimiter">.</span>operation = Recipe_ordinal[<span class="Constant">"jump-unless"</span>]<span class="Delimiter">;</span>
- else
- inst<span class="Delimiter">.</span>operation = Recipe_ordinal[<span class="Constant">"jump"</span>]<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>old_name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-if"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ inst<span class="Delimiter">.</span>name = <span class="Constant">"jump-if"</span><span class="Delimiter">;</span>
+ inst<span class="Delimiter">.</span>operation = JUMP_IF<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ else if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>old_name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-unless"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ inst<span class="Delimiter">.</span>name = <span class="Constant">"jump-unless"</span><span class="Delimiter">;</span>
+ inst<span class="Delimiter">.</span>operation = JUMP_UNLESS<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ else <span class="Delimiter">{</span>
+ inst<span class="Delimiter">.</span>name = <span class="Constant">"jump"</span><span class="Delimiter">;</span>
+ inst<span class="Delimiter">.</span>operation = JUMP<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
<span class="Comment">// check for explicitly provided targets</span>
- if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-if"</span><span class="Delimiter">)</span> != string::npos || inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-unless"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>old_name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-if"</span><span class="Delimiter">)</span> != string::npos || inst<span class="Delimiter">.</span>old_name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-unless"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Comment">// conditional branches check arg 1</span>
if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">1</span> && is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- trace<span class="Delimiter">(</span><span class="Constant">"after-brace"</span><span class="Delimiter">)</span> << <span class="Constant">"jump "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name << <span class="Constant">":offset"</span> << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << inst<span class="Delimiter">.</span>name << <span class="Constant">' '</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name << <span class="Constant">":offset"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">continue</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
else <span class="Delimiter">{</span>
<span class="Comment">// unconditional branches check arg 0</span>
if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- trace<span class="Delimiter">(</span><span class="Constant">"after-brace"</span><span class="Delimiter">)</span> << <span class="Constant">"jump "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name << <span class="Constant">":offset"</span> << end<span class="Delimiter">();</span>
+ 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">"jump "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name << <span class="Constant">":offset"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">continue</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
<span class="Comment">// if implicit, compute target</span>
reagent target<span class="Delimiter">;</span>
- target<span class="Delimiter">.</span>types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"offset"</span>]<span class="Delimiter">);</span>
+ target<span class="Delimiter">.</span>type = new type_tree<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"offset"</span><span class="Delimiter">));</span>
+ target<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">"offset"</span><span class="Delimiter">);</span>
target<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
if <span class="Delimiter">(</span>open_braces<span class="Delimiter">.</span>empty<span class="Delimiter">())</span>
- raise << inst<span class="Delimiter">.</span>name << <span class="Constant">" needs a '{' before</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
- else if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"loop"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span>
+ raise_error << inst<span class="Delimiter">.</span>old_name << <span class="Constant">" needs a '{' before</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ else if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>old_name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"loop"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span>
target<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>open_braces<span class="Delimiter">.</span>top<span class="Delimiter">()</span>-index<span class="Delimiter">);</span>
else <span class="Comment">// break instruction</span>
target<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>matching_brace<span class="Delimiter">(</span>open_braces<span class="Delimiter">.</span>top<span class="Delimiter">(),</span> braces<span class="Delimiter">,</span> r<span class="Delimiter">)</span> - index - <span class="Constant">1</span><span class="Delimiter">);</span>
inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>target<span class="Delimiter">);</span>
<span class="Comment">// log computed target</span>
- if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-if"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span>
- trace<span class="Delimiter">(</span><span class="Constant">"after-brace"</span><span class="Delimiter">)</span> << <span class="Constant">"jump-if "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name << <span class="Constant">", "</span> << target<span class="Delimiter">.</span>value << <span class="Constant">":offset"</span> << end<span class="Delimiter">();</span>
- else if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"-unless"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span>
- trace<span class="Delimiter">(</span><span class="Constant">"after-brace"</span><span class="Delimiter">)</span> << <span class="Constant">"jump-unless "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name << <span class="Constant">", "</span> << target<span class="Delimiter">.</span>value << <span class="Constant">":offset"</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">"jump"</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">"jump "</span> << no_scientific<span class="Delimiter">(</span>target<span class="Delimiter">.</span>value<span class="Delimiter">)</span> << <span class="Constant">":offset"</span> << end<span class="Delimiter">();</span>
else
- trace<span class="Delimiter">(</span><span class="Constant">"after-brace"</span><span class="Delimiter">)</span> << <span class="Constant">"jump "</span> << target<span class="Delimiter">.</span>value << <span class="Constant">":offset"</span> << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << inst<span class="Delimiter">.</span>name << <span class="Constant">' '</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name << <span class="Constant">", "</span> << no_scientific<span class="Delimiter">(</span>target<span class="Delimiter">.</span>value<span class="Delimiter">)</span> << <span class="Constant">":offset"</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
@@ -165,34 +175,10 @@ long long int matching_brace<span class="Delimiter">(</span>long long int index<
stacksize += <span class="Delimiter">(</span>p<span class="Delimiter">-></span>first ? <span class="Constant">1</span> : -<span class="Constant">1</span><span class="Delimiter">);</span>
if <span class="Delimiter">(</span>stacksize == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> p<span class="Delimiter">-></span>second<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- raise << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": unbalanced '{'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">return</span> SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> <span class="Comment">// exit current routine</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"unbalanced '{'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span> SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">);</span> <span class="Comment">// exit current routine</span>
<span class="Delimiter">}</span>
-<span class="Comment">// temporarily suppress run</span>
-void transform<span class="Delimiter">(</span>string form<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- load<span class="Delimiter">(</span>form<span class="Delimiter">);</span>
- transform_all<span class="Delimiter">();</span>
-<span class="Delimiter">}</span>
-
-<span class="Comment">//: Make sure these pseudo recipes get consistent numbers in all tests, even</span>
-<span class="Comment">//: though they aren't implemented.</span>
-
-<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
-BREAK<span class="Delimiter">,</span>
-BREAK_IF<span class="Delimiter">,</span>
-BREAK_UNLESS<span class="Delimiter">,</span>
-LOOP<span class="Delimiter">,</span>
-LOOP_IF<span class="Delimiter">,</span>
-LOOP_UNLESS<span class="Delimiter">,</span>
-<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"break"</span>] = BREAK<span class="Delimiter">;</span>
-Recipe_ordinal[<span class="Constant">"break-if"</span>] = BREAK_IF<span class="Delimiter">;</span>
-Recipe_ordinal[<span class="Constant">"break-unless"</span>] = BREAK_UNLESS<span class="Delimiter">;</span>
-Recipe_ordinal[<span class="Constant">"loop"</span>] = LOOP<span class="Delimiter">;</span>
-Recipe_ordinal[<span class="Constant">"loop-if"</span>] = LOOP_IF<span class="Delimiter">;</span>
-Recipe_ordinal[<span class="Constant">"loop-unless"</span>] = LOOP_UNLESS<span class="Delimiter">;</span>
-
<span class="Delimiter">:(scenario loop)</span>
recipe main [
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
@@ -202,11 +188,11 @@ recipe main [
loop
<span class="Delimiter">}</span>
]
-<span class="traceContains">+after-brace: recipe main</span>
-<span class="traceContains">+after-brace: copy ...</span>
-<span class="traceContains">+after-brace: copy ...</span>
-<span class="traceContains">+after-brace: copy ...</span>
-<span class="traceContains">+after-brace: jump -2:offset</span>
+<span class="traceContains">+transform: --- transform braces for recipe main</span>
+<span class="traceContains">+transform: copy ...</span>
+<span class="traceContains">+transform: copy ...</span>
+<span class="traceContains">+transform: copy ...</span>
+<span class="traceContains">+transform: jump -2:offset</span>
<span class="Delimiter">:(scenario break_empty_block)</span>
recipe main [
@@ -215,9 +201,9 @@ recipe main [
<span class="Identifier">break</span>
<span class="Delimiter">}</span>
]
-<span class="traceContains">+after-brace: recipe main</span>
-<span class="traceContains">+after-brace: copy ...</span>
-<span class="traceContains">+after-brace: jump 0:offset</span>
+<span class="traceContains">+transform: --- transform braces for recipe main</span>
+<span class="traceContains">+transform: copy ...</span>
+<span class="traceContains">+transform: jump 0:offset</span>
<span class="Delimiter">:(scenario break_cascading)</span>
recipe main [
@@ -229,10 +215,10 @@ recipe main [
<span class="Identifier">break</span>
<span class="Delimiter">}</span>
]
-<span class="traceContains">+after-brace: recipe main</span>
-<span class="traceContains">+after-brace: copy ...</span>
-<span class="traceContains">+after-brace: jump 0:offset</span>
-<span class="traceContains">+after-brace: jump 0:offset</span>
+<span class="traceContains">+transform: --- transform braces for recipe main</span>
+<span class="traceContains">+transform: copy ...</span>
+<span class="traceContains">+transform: jump 0:offset</span>
+<span class="traceContains">+transform: jump 0:offset</span>
<span class="Delimiter">:(scenario break_cascading_2)</span>
recipe main [
@@ -246,12 +232,12 @@ recipe main [
<span class="Identifier">break</span>
<span class="Delimiter">}</span>
]
-<span class="traceContains">+after-brace: recipe main</span>
-<span class="traceContains">+after-brace: copy ...</span>
-<span class="traceContains">+after-brace: copy ...</span>
-<span class="traceContains">+after-brace: jump 1:offset</span>
-<span class="traceContains">+after-brace: copy ...</span>
-<span class="traceContains">+after-brace: jump 0:offset</span>
+<span class="traceContains">+transform: --- transform braces for recipe main</span>
+<span class="traceContains">+transform: copy ...</span>
+<span class="traceContains">+transform: copy ...</span>
+<span class="traceContains">+transform: jump 1:offset</span>
+<span class="traceContains">+transform: copy ...</span>
+<span class="traceContains">+transform: jump 0:offset</span>
<span class="Delimiter">:(scenario break_if)</span>
recipe main [
@@ -265,12 +251,12 @@ recipe main [
<span class="Identifier">break</span>
<span class="Delimiter">}</span>
]
-<span class="traceContains">+after-brace: recipe main</span>
-<span class="traceContains">+after-brace: copy ...</span>
-<span class="traceContains">+after-brace: copy ...</span>
-<span class="traceContains">+after-brace: jump-if 2, 1:offset</span>
-<span class="traceContains">+after-brace: copy ...</span>
-<span class="traceContains">+after-brace: jump 0:offset</span>
+<span class="traceContains">+transform: --- transform braces for recipe main</span>
+<span class="traceContains">+transform: copy ...</span>
+<span class="traceContains">+transform: copy ...</span>
+<span class="traceContains">+transform: jump-if 2, 1:offset</span>
+<span class="traceContains">+transform: copy ...</span>
+<span class="traceContains">+transform: jump 0:offset</span>
<span class="Delimiter">:(scenario break_nested)</span>
recipe main [
@@ -284,7 +270,7 @@ recipe main [
<span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
<span class="Delimiter">}</span>
]
-<span class="traceContains">+after-brace: jump 4:offset</span>
+<span class="traceContains">+transform: jump 4:offset</span>
<span class="Delimiter">:(scenario break_nested_degenerate)</span>
recipe main [
@@ -297,7 +283,7 @@ recipe main [
<span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
<span class="Delimiter">}</span>
]
-<span class="traceContains">+after-brace: jump 3:offset</span>
+<span class="traceContains">+transform: jump 3:offset</span>
<span class="Delimiter">:(scenario break_nested_degenerate_2)</span>
recipe main [
@@ -309,17 +295,17 @@ recipe main [
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
]
-<span class="traceContains">+after-brace: jump 2:offset</span>
+<span class="traceContains">+transform: jump 2:offset</span>
<span class="Delimiter">:(scenario break_label)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
<span class="Delimiter">{</span>
<span class="Identifier">break</span> +foo:offset
<span class="Delimiter">}</span>
]
-<span class="traceContains">+after-brace: jump +foo:offset</span>
+<span class="traceContains">+transform: jump +foo:offset</span>
<span class="Delimiter">:(scenario break_unless)</span>
recipe main [
@@ -330,11 +316,11 @@ recipe main [
<span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
<span class="Delimiter">}</span>
]
-<span class="traceContains">+after-brace: recipe main</span>
-<span class="traceContains">+after-brace: copy ...</span>
-<span class="traceContains">+after-brace: copy ...</span>
-<span class="traceContains">+after-brace: jump-unless 2, 1:offset</span>
-<span class="traceContains">+after-brace: copy ...</span>
+<span class="traceContains">+transform: --- transform braces for recipe main</span>
+<span class="traceContains">+transform: copy ...</span>
+<span class="traceContains">+transform: copy ...</span>
+<span class="traceContains">+transform: jump-unless 2, 1:offset</span>
+<span class="traceContains">+transform: copy ...</span>
<span class="Delimiter">:(scenario loop_unless)</span>
recipe main [
@@ -345,11 +331,11 @@ recipe main [
<span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
<span class="Delimiter">}</span>
]
-<span class="traceContains">+after-brace: recipe main</span>
-<span class="traceContains">+after-brace: copy ...</span>
-<span class="traceContains">+after-brace: copy ...</span>
-<span class="traceContains">+after-brace: jump-unless 2, -1:offset</span>
-<span class="traceContains">+after-brace: copy ...</span>
+<span class="traceContains">+transform: --- transform braces for recipe main</span>
+<span class="traceContains">+transform: copy ...</span>
+<span class="traceContains">+transform: copy ...</span>
+<span class="traceContains">+transform: jump-unless 2, -1:offset</span>
+<span class="traceContains">+transform: copy ...</span>
<span class="Delimiter">:(scenario loop_nested)</span>
recipe main [
@@ -363,8 +349,8 @@ recipe main [
<span class="Constant">5</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
<span class="Delimiter">}</span>
]
-<span class="traceContains">+after-brace: recipe main</span>
-<span class="traceContains">+after-brace: jump-if 4, -5:offset</span>
+<span class="traceContains">+transform: --- transform braces for recipe main</span>
+<span class="traceContains">+transform: jump-if 4, -5:offset</span>
<span class="Delimiter">:(scenario loop_label)</span>
recipe main [
@@ -372,9 +358,9 @@ recipe main [
+foo
<span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
]
-<span class="traceContains">+after-brace: recipe main</span>
-<span class="traceContains">+after-brace: copy ...</span>
-<span class="traceContains">+after-brace: copy ...</span>
+<span class="traceContains">+transform: --- transform braces for recipe main</span>
+<span class="traceContains">+transform: copy ...</span>
+<span class="traceContains">+transform: copy ...</span>
<span class="Comment">//: test how things actually run</span>
<span class="Delimiter">:(scenarios run)</span>
@@ -394,21 +380,47 @@ recipe test-factorial [
]
<span class="traceContains">+mem: location 2 is 120</span>
-<span class="Delimiter">:(scenario break_outside_braces_warns)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Delimiter">:(scenario break_outside_braces_fails)</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
<span class="Identifier">break</span>
]
-<span class="traceContains">+warn: break needs a '{' before</span>
+<span class="traceContains">+error: break needs a '{' before</span>
-<span class="Delimiter">:(scenario break_conditional_without_ingredient_warns)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Delimiter">:(scenario break_conditional_without_ingredient_fails)</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
<span class="Delimiter">{</span>
<span class="Identifier">break</span>-if
<span class="Delimiter">}</span>
]
-<span class="traceContains">+warn: break-if expects 1 or 2 ingredients, but got none</span>
+<span class="traceContains">+error: break-if expects 1 or 2 ingredients, but got none</span>
+
+<span class="Comment">//: Make sure these pseudo recipes get consistent numbers in all tests, even</span>
+<span class="Comment">//: though they aren't implemented. Allows greater flexibility in ordering</span>
+<span class="Comment">//: transforms.</span>
+
+<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
+BREAK<span class="Delimiter">,</span>
+BREAK_IF<span class="Delimiter">,</span>
+BREAK_UNLESS<span class="Delimiter">,</span>
+LOOP<span class="Delimiter">,</span>
+LOOP_IF<span class="Delimiter">,</span>
+LOOP_UNLESS<span class="Delimiter">,</span>
+<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"break"</span><span class="Delimiter">,</span> BREAK<span class="Delimiter">);</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"break-if"</span><span class="Delimiter">,</span> BREAK_IF<span class="Delimiter">);</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"break-unless"</span><span class="Delimiter">,</span> BREAK_UNLESS<span class="Delimiter">);</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"loop"</span><span class="Delimiter">,</span> LOOP<span class="Delimiter">);</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"loop-if"</span><span class="Delimiter">,</span> LOOP_IF<span class="Delimiter">);</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"loop-unless"</span><span class="Delimiter">,</span> LOOP_UNLESS<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case BREAK: <span class="Identifier">break</span><span class="Delimiter">;</span>
+case BREAK_IF: <span class="Identifier">break</span><span class="Delimiter">;</span>
+case BREAK_UNLESS: <span class="Identifier">break</span><span class="Delimiter">;</span>
+case LOOP: <span class="Identifier">break</span><span class="Delimiter">;</span>
+case LOOP_IF: <span class="Identifier">break</span><span class="Delimiter">;</span>
+case LOOP_UNLESS: <span class="Identifier">break</span><span class="Delimiter">;</span>
</pre>
</body>
</html>
diff --git a/html/041jump_target.cc.html b/html/041jump_target.cc.html
index 8c0ce0cf..53f93910 100644
--- a/html/041jump_target.cc.html
+++ b/html/041jump_target.cc.html
@@ -13,8 +13,8 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
-.traceAbsent { color: #c00000; }
.traceContains { color: #008000; }
+.traceAbsent { color: #c00000; }
.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
@@ -50,41 +50,41 @@ recipe main [
<span class="traceAbsent">-mem: storing 0 in location 1</span>
<span class="Delimiter">:(before "End Mu Types Initialization")</span>
-Type_ordinal[<span class="Constant">"label"</span>] = <span class="Constant">0</span><span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"label"</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span>
-<span class="Delimiter">:(after "int main")</span>
- Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>transform_labels<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "Transform.push_back(transform_braces)")</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>transform_labels<span class="Delimiter">);</span> <span class="Comment">// idempotent</span>
<span class="Delimiter">:(code)</span>
void transform_labels<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
map<string<span class="Delimiter">,</span> long long int> offset<span class="Delimiter">;</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- const instruction& inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ const instruction& inst = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>label<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && inst<span class="Delimiter">.</span>label<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">'+'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>offset<span class="Delimiter">.</span>find<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label<span class="Delimiter">)</span> == offset<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>offset<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>label<span class="Delimiter">))</span> <span class="Delimiter">{</span>
offset[inst<span class="Delimiter">.</span>label] = i<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
else <span class="Delimiter">{</span>
- raise << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": duplicate label '"</span> << inst<span class="Delimiter">.</span>label << <span class="Constant">"'"</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"duplicate label '"</span> << inst<span class="Delimiter">.</span>label << <span class="Constant">"'"</span> << end<span class="Delimiter">();</span>
<span class="Comment">// have all jumps skip some random but noticeable and deterministic amount of code</span>
offset[inst<span class="Delimiter">.</span>label] = <span class="Constant">9999</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- instruction& inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"jump"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ instruction& inst = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">"jump"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
replace_offset<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">),</span> offset<span class="Delimiter">,</span> i<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"jump-if"</span>] || inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"jump-unless"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">"jump-if"</span> || inst<span class="Delimiter">.</span>name == <span class="Constant">"jump-unless"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
replace_offset<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">),</span> offset<span class="Delimiter">,</span> i<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">((</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"loop"</span>] || inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"break"</span>]<span class="Delimiter">)</span>
+ if <span class="Delimiter">((</span>inst<span class="Delimiter">.</span>name == <span class="Constant">"loop"</span> || inst<span class="Delimiter">.</span>name == <span class="Constant">"break"</span><span class="Delimiter">)</span>
&& SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
replace_offset<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">),</span> offset<span class="Delimiter">,</span> i<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">((</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"loop-if"</span>] || inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"loop-unless"</span>]
- || inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"break-if"</span>] || inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"break-unless"</span>]<span class="Delimiter">)</span>
+ if <span class="Delimiter">((</span>inst<span class="Delimiter">.</span>name == <span class="Constant">"loop-if"</span> || inst<span class="Delimiter">.</span>name == <span class="Constant">"loop-unless"</span>
+ || inst<span class="Delimiter">.</span>name == <span class="Constant">"break-if"</span> || inst<span class="Delimiter">.</span>name == <span class="Constant">"break-unless"</span><span class="Delimiter">)</span>
&& SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> == <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
replace_offset<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">),</span> offset<span class="Delimiter">,</span> i<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
@@ -94,19 +94,19 @@ void transform_labels<span class="Delimiter">(</span>const recipe_ordinal r<span
<span class="Delimiter">:(code)</span>
void replace_offset<span class="Delimiter">(</span>reagent& x<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">const</span><span class="Comment">*/</span> map<string<span class="Delimiter">,</span> long long int>& offset<span class="Delimiter">,</span> const long long int current_offset<span class="Delimiter">,</span> const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Delimiter">{</span>
- raise << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": jump target must be offset or label but is "</span> << x<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"jump target must be offset or label but is "</span> << x<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
x<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> <span class="Comment">// no jump by default</span>
<span class="Identifier">return</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
assert<span class="Delimiter">(</span>!x<span class="Delimiter">.</span>initialized<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// non-labels will be handled like other number operands</span>
if <span class="Delimiter">(</span>!is_jump_target<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span>
- raise << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": can't jump to label "</span> << x<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"can't jump to label "</span> << x<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
x<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> <span class="Comment">// no jump by default</span>
<span class="Identifier">return</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>offset<span class="Delimiter">.</span>find<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">)</span> == offset<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- raise << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": can't find label "</span> << x<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>offset<span class="Delimiter">,</span> x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"can't find label "</span> << x<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
x<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> <span class="Comment">// no jump by default</span>
<span class="Identifier">return</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -167,18 +167,18 @@ recipe main [
<span class="traceContains">+mem: storing 0 in location 5</span>
<span class="traceAbsent">-mem: storing 0 in location 4</span>
-<span class="Delimiter">:(scenario recipe_warns_on_duplicate_jump_target)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Delimiter">:(scenario recipe_fails_on_duplicate_jump_target)</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
+label
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
+label
<span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
]
-<span class="traceContains">+warn: main: duplicate label '+label'</span>
+<span class="traceContains">+error: main: duplicate label '+label'</span>
<span class="Delimiter">:(scenario jump_ignores_nontarget_label)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
<span class="Comment"># first a few lines of padding to exercise the offset computation</span>
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
@@ -189,7 +189,7 @@ recipe main [
$target
<span class="Constant">5</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
]
-<span class="traceContains">+warn: main: can't jump to label $target</span>
+<span class="traceContains">+error: main: can't jump to label $target</span>
</pre>
</body>
</html>
diff --git a/html/042name.cc.html b/html/042name.cc.html
index 16cf8117..da006079 100644
--- a/html/042name.cc.html
+++ b/html/042name.cc.html
@@ -13,15 +13,16 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
-.cSpecial { color: #008000; }
-.SalientComment { color: #00ffff; }
+.traceContains { color: #008000; }
.traceAbsent { color: #c00000; }
+.Identifier { color: #804000; }
+.cSpecial { color: #008000; }
.Constant { color: #00a0a0; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
-.Identifier { color: #804000; }
-.traceContains { color: #008000; }
+.CommentedCode { color: #6c6c6c; }
+.SalientComment { color: #00ffff; }
-->
</style>
@@ -45,15 +46,16 @@ recipe main [
<span class="traceContains">+mem: storing 0 in location 1</span>
<span class="Delimiter">:(scenarios transform)</span>
-<span class="Delimiter">:(scenario transform_names_warns)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Delimiter">:(scenario transform_names_fails_on_use_before_define)</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
x:number<span class="Special"> <- </span>copy y:number
]
-<span class="traceContains">+warn: use before set: y in main</span>
+<span class="traceContains">+error: main: use before set: y</span>
+<span class="Comment"># todo: detect conditional defines</span>
-<span class="Delimiter">:(after "int main")</span>
- Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>transform_names<span class="Delimiter">);</span>
+<span class="Delimiter">:(after "Transform.push_back(check_or_set_invalid_types")</span> <span class="Comment">// there'll be other transforms relating to types; they all need to happen first</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>transform_names<span class="Delimiter">);</span> <span class="Comment">// idempotent</span>
<span class="Delimiter">:(before "End Globals")</span>
map<recipe_ordinal<span class="Delimiter">,</span> map<string<span class="Delimiter">,</span> long long int> > Name<span class="Delimiter">;</span>
@@ -64,31 +66,33 @@ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</
<span class="Delimiter">:(code)</span>
void transform_names<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"--- transform names for recipe "</span> << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name << end<span class="Delimiter">();</span>
+<span class="CommentedCode">//? cerr << "--- transform names for recipe " << get(Recipe, r).name << '\n';</span>
bool names_used = <span class="Constant">false</span><span class="Delimiter">;</span>
bool numeric_locations_used = <span class="Constant">false</span><span class="Delimiter">;</span>
map<string<span class="Delimiter">,</span> long long int>& names = Name[r]<span class="Delimiter">;</span>
<span class="Comment">// store the indices 'used' so far in the map</span>
long long int& curr_idx = names[<span class="Constant">""</span>]<span class="Delimiter">;</span>
++curr_idx<span class="Delimiter">;</span> <span class="Comment">// avoid using index 0, benign skip in some other cases</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- instruction& inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
- <span class="Comment">// Per-recipe Transforms</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ instruction& inst = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ <span class="Comment">// End transform_names(inst) Special-cases</span>
<span class="Comment">// map names to addresses</span>
for <span class="Delimiter">(</span>long long int in = <span class="Constant">0</span><span class="Delimiter">;</span> in < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>is_numeric_location<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">)))</span> numeric_locations_used = <span class="Constant">true</span><span class="Delimiter">;</span>
if <span class="Delimiter">(</span>is_named_location<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">)))</span> names_used = <span class="Constant">true</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>disqualified<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">),</span> inst<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>disqualified<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">),</span> inst<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
if <span class="Delimiter">(</span>!already_transformed<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">),</span> names<span class="Delimiter">))</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"use before set: "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">).</span>name << <span class="Constant">" in "</span> << Recipe[r]<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"use before set: "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">).</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">).</span>set_value<span class="Delimiter">(</span>lookup_name<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">),</span> r<span class="Delimiter">));</span>
<span class="Delimiter">}</span>
for <span class="Delimiter">(</span>long long int out = <span class="Constant">0</span><span class="Delimiter">;</span> out < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++out<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>is_numeric_location<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">)))</span> numeric_locations_used = <span class="Constant">true</span><span class="Delimiter">;</span>
if <span class="Delimiter">(</span>is_named_location<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">)))</span> names_used = <span class="Constant">true</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>disqualified<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">),</span> inst<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>disqualified<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">),</span> inst<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
if <span class="Delimiter">(</span>names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">).</span>name<span class="Delimiter">)</span> == names<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- trace<span class="Delimiter">(</span><span class="Constant">"name"</span><span class="Delimiter">)</span> << <span class="Constant">"assign "</span> << inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">).</span>name << <span class="Constant">" "</span> << curr_idx << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"name"</span><span class="Delimiter">)</span> << <span class="Constant">"assign "</span> << inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">).</span>name << <span class="Constant">" "</span> << curr_idx << end<span class="Delimiter">();</span>
names[inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">).</span>name] = curr_idx<span class="Delimiter">;</span>
curr_idx += size_of<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">));</span>
<span class="Delimiter">}</span>
@@ -96,12 +100,12 @@ void transform_names<span class="Delimiter">(</span>const recipe_ordinal r<span
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
if <span class="Delimiter">(</span>names_used && numeric_locations_used<span class="Delimiter">)</span>
- raise << <span class="Constant">"mixing variable names and numeric addresses in "</span> << Recipe[r]<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"mixing variable names and numeric addresses</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
-bool disqualified<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">mutable</span><span class="Comment">*/</span> reagent& x<span class="Delimiter">,</span> const instruction& inst<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"missing type in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+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>
+ if <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Delimiter">{</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>
@@ -113,27 +117,28 @@ bool disqualified<span class="Delimiter">(</span><span class="Comment">/*</span>
<span class="Delimiter">}</span>
bool already_transformed<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">,</span> const map<string<span class="Delimiter">,</span> long long int>& names<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- <span class="Identifier">return</span> names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>r<span class="Delimiter">.</span>name<span class="Delimiter">)</span> != names<span class="Delimiter">.</span>end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span> contains_key<span class="Delimiter">(</span>names<span class="Delimiter">,</span> r<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
long long int lookup_name<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">,</span> const recipe_ordinal default_recipe<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Identifier">return</span> Name[default_recipe][r<span class="Delimiter">.</span>name]<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
-type_ordinal skip_addresses<span class="Delimiter">(</span>const vector<type_ordinal>& types<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>types<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> != Type_ordinal[<span class="Constant">"address"</span>]<span class="Delimiter">)</span> <span class="Identifier">return</span> types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+type_ordinal skip_addresses<span class="Delimiter">(</span>type_tree* type<span class="Delimiter">,</span> const string& recipe_name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ for <span class="Delimiter">(;</span> type<span class="Delimiter">;</span> type = type<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <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> type<span class="Delimiter">-></span>value<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- raise << <span class="Constant">"expected a container"</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>recipe_name<span class="Delimiter">)</span> << <span class="Constant">"expected a container"</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
-int find_element_name<span class="Delimiter">(</span>const type_ordinal t<span class="Delimiter">,</span> const string& name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- const type_info& container = Type[t]<span class="Delimiter">;</span>
+int find_element_name<span class="Delimiter">(</span>const type_ordinal t<span class="Delimiter">,</span> const string& name<span class="Delimiter">,</span> const string& recipe_name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ const type_info& container = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> t<span class="Delimiter">);</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>container<span class="Delimiter">.</span>element_names<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>container<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == name<span class="Delimiter">)</span> <span class="Identifier">return</span> i<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- raise << <span class="Constant">"unknown element "</span> << name << <span class="Constant">" in container "</span> << Type[t]<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>recipe_name<span class="Delimiter">)</span> << <span class="Constant">"unknown element "</span> << name << <span class="Constant">" in container "</span> << get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> t<span class="Delimiter">).</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -151,13 +156,6 @@ bool is_named_location<span class="Delimiter">(</span>const reagent& x<span
<span class="Identifier">return</span> !is_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
-bool is_raw<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Comment">/*</span><span class="Comment">skip value+type</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>properties<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>first == <span class="Constant">"raw"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
-<span class="Delimiter">}</span>
-
bool is_special_name<span class="Delimiter">(</span>const string& s<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>s == <span class="Constant">"_"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
if <span class="Delimiter">(</span>s == <span class="Constant">"0"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
@@ -176,51 +174,51 @@ recipe main [
<span class="Comment">//: an escape hatch to suppress name conversion that we'll use later</span>
<span class="Delimiter">:(scenarios run)</span>
<span class="Delimiter">:(scenario transform_names_passes_raw)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
x:number/<span class="Special">raw <- </span>copy <span class="Constant">0</span>
]
<span class="traceAbsent">-name: assign x 1</span>
-<span class="traceContains">+warn: can't write to location 0 in 'x:number/raw <- copy 0'</span>
+<span class="traceContains">+error: can't write to location 0 in 'x:number/raw <- copy 0'</span>
<span class="Delimiter">:(scenarios transform)</span>
-<span class="Delimiter">:(scenario transform_names_warns_when_mixing_names_and_numeric_locations)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Delimiter">:(scenario transform_names_fails_when_mixing_names_and_numeric_locations)</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
x:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:number
]
-<span class="traceContains">+warn: mixing variable names and numeric addresses in main</span>
+<span class="traceContains">+error: main: mixing variable names and numeric addresses</span>
-<span class="Delimiter">:(scenario transform_names_warns_when_mixing_names_and_numeric_locations_2)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Delimiter">:(scenario transform_names_fails_when_mixing_names_and_numeric_locations_2)</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
x:number<span class="Special"> <- </span>copy <span class="Constant">1</span>
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy x:number
]
-<span class="traceContains">+warn: mixing variable names and numeric addresses in main</span>
+<span class="traceContains">+error: main: mixing variable names and numeric addresses</span>
-<span class="Delimiter">:(scenario transform_names_does_not_warn_when_mixing_names_and_raw_locations)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Delimiter">:(scenario transform_names_does_not_fail_when_mixing_names_and_raw_locations)</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
x:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:number/<span class="Special">raw</span>
]
-<span class="traceAbsent">-warn: mixing variable names and numeric addresses in main</span>
-$warn: <span class="Constant">0</span>
+<span class="traceAbsent">-error: main: mixing variable names and numeric addresses</span>
+$error: <span class="Constant">0</span>
-<span class="Delimiter">:(scenario transform_names_does_not_warn_when_mixing_names_and_literals)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Delimiter">:(scenario transform_names_does_not_fail_when_mixing_names_and_literals)</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
x:number<span class="Special"> <- </span>copy <span class="Constant">1</span>
]
-<span class="traceAbsent">-warn: mixing variable names and numeric addresses in main</span>
-$warn: <span class="Constant">0</span>
+<span class="traceAbsent">-error: main: mixing variable names and numeric addresses</span>
+$error: <span class="Constant">0</span>
<span class="SalientComment">//:: Support element names for containers in 'get' and 'get-address'.</span>
<span class="Comment">//: update our running example container for the next test</span>
<span class="Delimiter">:(before "End Mu Types Initialization")</span>
-Type[point]<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">"x"</span><span class="Delimiter">);</span>
-Type[point]<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">"y"</span><span class="Delimiter">);</span>
+get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> point<span class="Delimiter">).</span>element_names<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">"x"</span><span class="Delimiter">);</span>
+get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> point<span class="Delimiter">).</span>element_names<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span><span class="Constant">"y"</span><span class="Delimiter">);</span>
<span class="Delimiter">:(scenario transform_names_transforms_container_elements)</span>
recipe main [
p:address:point<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># unsafe</span>
@@ -230,21 +228,20 @@ recipe main [
<span class="traceContains">+name: element y of type point is at offset 1</span>
<span class="traceContains">+name: element x of type point is at offset 0</span>
-<span class="Delimiter">:(after "Per-recipe Transforms")</span>
+<span class="Delimiter">:(before "End transform_names(inst) Special-cases")</span>
<span class="Comment">// replace element names of containers with offsets</span>
-if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"get"</span>]
- || inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"get-address"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">"get"</span> || inst<span class="Delimiter">.</span>name == <span class="Constant">"get-address"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": exactly 2 ingredients expected in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"exactly 2 ingredients expected in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
if <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span>
- raise << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": expected ingredient 1 of "</span> << <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"get"</span>] ? <span class="Constant">"'get'"</span> : <span class="Constant">"'get-address'"</span><span class="Delimiter">)</span> << <span class="Constant">" to have type 'offset'; got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"expected ingredient 1 of "</span> << <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">"get"</span> ? <span class="Constant">"'get'"</span> : <span class="Constant">"'get-address'"</span><span class="Delimiter">)</span> << <span class="Constant">" to have type 'offset'; got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">.</span>find_first_not_of<span class="Delimiter">(</span><span class="Constant">"0123456789"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Comment">// since first non-address in base type must be a container, we don't have to canonize</span>
- type_ordinal base_type = skip_addresses<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>types<span class="Delimiter">);</span>
- inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>set_value<span class="Delimiter">(</span>find_element_name<span class="Delimiter">(</span>base_type<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">));</span>
- trace<span class="Delimiter">(</span><span class="Constant">"name"</span><span class="Delimiter">)</span> << <span class="Constant">"element "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name << <span class="Constant">" of type "</span> << Type[base_type]<span class="Delimiter">.</span>name << <span class="Constant">" is at offset "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>value << end<span class="Delimiter">();</span>
+ type_ordinal base_type = skip_addresses<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>type<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">);</span>
+ inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>set_value<span class="Delimiter">(</span>find_element_name<span class="Delimiter">(</span>base_type<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">));</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"name"</span><span class="Delimiter">)</span> << <span class="Constant">"element "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name << <span class="Constant">" of type "</span> << get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name << <span class="Constant">" is at offset "</span> << no_scientific<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>value<span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
@@ -252,8 +249,8 @@ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation
<span class="Delimiter">:(scenarios transform)</span>
<span class="Delimiter">:(scenario transform_names_handles_containers)</span>
recipe main [
- a:point<span class="Special"> <- </span>copy <span class="Constant">0</span>
- b:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
+ a:point<span class="Special"> <- </span>copy <span class="Constant">0</span>/<span class="Special">raw</span>
+ b:number<span class="Special"> <- </span>copy <span class="Constant">0</span>/<span class="Special">raw</span>
]
<span class="traceContains">+name: assign a 1</span>
<span class="traceContains">+name: assign b 3</span>
@@ -271,19 +268,19 @@ recipe main [
<span class="traceContains">+name: variant p of type number-or-point has tag 1</span>
<span class="traceContains">+mem: storing 13 in location 20</span>
-<span class="Delimiter">:(after "Per-recipe Transforms")</span>
+<span class="Delimiter">:(before "End transform_names(inst) Special-cases")</span>
<span class="Comment">// convert variant names of exclusive containers</span>
-if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"maybe-convert"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">"maybe-convert"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": exactly 2 ingredients expected in '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"exactly 2 ingredients expected in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
assert<span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)));</span>
if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">.</span>find_first_not_of<span class="Delimiter">(</span><span class="Constant">"0123456789"</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Comment">// since first non-address in base type must be an exclusive container, we don't have to canonize</span>
- type_ordinal base_type = skip_addresses<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>types<span class="Delimiter">);</span>
- inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>set_value<span class="Delimiter">(</span>find_element_name<span class="Delimiter">(</span>base_type<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">));</span>
- trace<span class="Delimiter">(</span><span class="Constant">"name"</span><span class="Delimiter">)</span> << <span class="Constant">"variant "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name << <span class="Constant">" of type "</span> << Type[base_type]<span class="Delimiter">.</span>name << <span class="Constant">" has tag "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>value << end<span class="Delimiter">();</span>
+ type_ordinal base_type = skip_addresses<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>type<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">);</span>
+ inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>set_value<span class="Delimiter">(</span>find_element_name<span class="Delimiter">(</span>base_type<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">));</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"name"</span><span class="Delimiter">)</span> << <span class="Constant">"variant "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name << <span class="Constant">" of type "</span> << get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name << <span class="Constant">" has tag "</span> << no_scientific<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>value<span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
</pre>
diff --git a/html/043new.cc.html b/html/043new.cc.html
index 82eaa244..35398d9f 100644
--- a/html/043new.cc.html
+++ b/html/043new.cc.html
@@ -13,9 +13,9 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
-.cSpecial { color: #008000; }
-.SalientComment { color: #00ffff; }
.traceContains { color: #008000; }
+.SalientComment { color: #00ffff; }
+.cSpecial { color: #008000; }
.CommentedCode { color: #6c6c6c; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
@@ -57,81 +57,87 @@ long long int alloc<span class="Delimiter">,</span> alloc_max<span class="Delimi
alloc = Memory_allocated_until<span class="Delimiter">;</span>
Memory_allocated_until += Initial_memory_per_routine<span class="Delimiter">;</span>
alloc_max = Memory_allocated_until<span class="Delimiter">;</span>
-trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"new"</span><span class="Delimiter">)</span> << <span class="Constant">"routine allocated memory from "</span> << alloc << <span class="Constant">" to "</span> << alloc_max << end<span class="Delimiter">();</span>
-
-<span class="SalientComment">//:: First handle 'type' operands.</span>
+trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"new"</span><span class="Delimiter">)</span> << <span class="Constant">"routine allocated memory from "</span> << alloc << <span class="Constant">" to "</span> << alloc_max << end<span class="Delimiter">();</span>
+<span class="SalientComment">//:: 'new' takes a weird 'type' as its first ingredient; don't error on it</span>
<span class="Delimiter">:(before "End Mu Types Initialization")</span>
-Type_ordinal[<span class="Constant">"type"</span>] = <span class="Constant">0</span><span class="Delimiter">;</span>
-<span class="Delimiter">:(after "Per-recipe Transforms")</span>
-<span class="Comment">// replace type names with type_ordinals</span>
-if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == Recipe_ordinal[<span class="Constant">"new"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- <span class="Comment">// End NEW Transform Special-cases</span>
- <span class="Comment">// first arg must be of type 'type'</span>
- if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span>
- raise << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": 'new' expects one or two ingredients</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
- if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>empty<span class="Delimiter">()</span>
- || inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>empty<span class="Delimiter">()</span>
- || inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> != <span class="Constant">"type"</span><span class="Delimiter">)</span>
- raise << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": first ingredient of 'new' should be a type, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- if <span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">.</span>find<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">)</span> == Type_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
- raise << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">": unknown type "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>set_value<span class="Delimiter">(</span>Type_ordinal[inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name]<span class="Delimiter">);</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"new"</span><span class="Delimiter">)</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name << <span class="Constant">" -> "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name << end<span class="Delimiter">();</span>
- end_new_transform:<span class="Delimiter">;</span>
-<span class="Delimiter">}</span>
-
-<span class="SalientComment">//:: Now implement the primitive recipe.</span>
-<span class="Comment">//: todo: build 'new' in mu itself</span>
+put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"type"</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span>
+<span class="SalientComment">//:: typecheck 'new' instructions</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
NEW<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"new"</span>] = NEW<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"new"</span><span class="Delimiter">,</span> NEW<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case NEW: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> || SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'new' requires one or two ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> || SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'new' requires one or two ingredients, but got "</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>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'new' should be a type, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Comment">// End NEW Check Special-cases</span>
+ reagent type = inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!is_mu_type_literal<span class="Delimiter">(</span>type<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'new' should be a type, but got "</span> << type<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- <span class="Comment">// compute the space we need</span>
- long long int size = <span class="Constant">0</span><span class="Delimiter">;</span>
- long long int array_length = <span class="Constant">0</span><span class="Delimiter">;</span>
- <span class="Delimiter">{</span>
- vector<type_ordinal> type<span class="Delimiter">;</span>
- type<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>value<span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- <span class="Comment">// array</span>
- array_length = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"mem"</span><span class="Delimiter">)</span> << <span class="Constant">"array size is "</span> << array_length << end<span class="Delimiter">();</span>
- size = array_length*size_of<span class="Delimiter">(</span>type<span class="Delimiter">)</span> + <span class="Comment">/*</span><span class="Comment">space for length</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- else <span class="Delimiter">{</span>
- <span class="Comment">// scalar</span>
- size = size_of<span class="Delimiter">(</span>type<span class="Delimiter">);</span>
+ <span class="Identifier">break</span><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>
+<span class="Delimiter">:(after "Transform.push_back(check_instruction)")</span> <span class="Comment">// check_instruction will guard against direct 'allocate' instructions below</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>transform_new_to_allocate<span class="Delimiter">);</span> <span class="Comment">// idempotent</span>
+
+<span class="Delimiter">:(code)</span>
+void transform_new_to_allocate<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"--- convert 'new' to 'allocate' for recipe "</span> << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name << end<span class="Delimiter">();</span>
+<span class="CommentedCode">//? cerr << "--- convert 'new' to 'allocate' for recipe " << get(Recipe, r).name << '\n';</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ instruction& inst = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ <span class="Comment">// Convert 'new' To 'allocate'</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">"new"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ inst<span class="Delimiter">.</span>operation = ALLOCATE<span class="Delimiter">;</span>
+ string_tree* type_name = new string_tree<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">);</span>
+ <span class="Comment">// End Post-processing(type_name) When Converting 'new'</span>
+ type_tree* type = new_type_tree<span class="Delimiter">(</span>type_name<span class="Delimiter">);</span>
+ inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>set_value<span class="Delimiter">(</span>size_of<span class="Delimiter">(</span>type<span class="Delimiter">));</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">"new"</span><span class="Delimiter">)</span> << <span class="Constant">"size of "</span> << debug_string<span class="Delimiter">(</span>type_name<span class="Delimiter">)</span> << <span class="Constant">" is "</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>value << end<span class="Delimiter">();</span>
+ delete type<span class="Delimiter">;</span>
+ delete type_name<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+<span class="SalientComment">//:: implement 'allocate' based on size</span>
+
+<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
+ALLOCATE<span class="Delimiter">,</span>
+<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"allocate"</span><span class="Delimiter">,</span> ALLOCATE<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case ALLOCATE: <span class="Delimiter">{</span>
+ <span class="Comment">// compute the space we need</span>
+ long long int size = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ <span class="Comment">// array</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">"array size is "</span> << ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
+ size = <span class="Comment">/*</span><span class="Comment">space for length</span><span class="Comment">*/</span><span class="Constant">1</span> + size*ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
<span class="CommentedCode">//? Total_alloc += size;</span>
<span class="CommentedCode">//? Num_alloc++;</span>
<span class="Comment">// compute the region of memory to return</span>
<span class="Comment">// really crappy at the moment</span>
ensure_space<span class="Delimiter">(</span>size<span class="Delimiter">);</span>
const long long int result = Current_routine<span class="Delimiter">-></span>alloc<span class="Delimiter">;</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"mem"</span><span class="Delimiter">)</span> << <span class="Constant">"new alloc: "</span> << result << end<span class="Delimiter">();</span>
+ 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">"new alloc: "</span> << result << end<span class="Delimiter">();</span>
<span class="Comment">// save result</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
<span class="Comment">// initialize allocated space</span>
- for <span class="Delimiter">(</span>long long int address = result<span class="Delimiter">;</span> address < result+size<span class="Delimiter">;</span> ++address<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- Memory[address] = <span class="Constant">0</span><span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- Memory[result] = array_length<span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
+ for <span class="Delimiter">(</span>long long int address = result<span class="Delimiter">;</span> address < result+size<span class="Delimiter">;</span> ++address<span class="Delimiter">)</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span>
+ <span class="Comment">// initialize array length</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> result<span class="Delimiter">,</span> ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
<span class="Comment">// bump</span>
Current_routine<span class="Delimiter">-></span>alloc += size<span class="Delimiter">;</span>
<span class="Comment">// no support for reclaiming memory</span>
@@ -139,6 +145,20 @@ case NEW: <span class="Delimiter">{</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+<span class="SalientComment">//:: ensure we never call 'allocate' directly; its types are not checked</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case ALLOCATE: <span class="Delimiter">{</span>
+ raise << <span class="Constant">"never call 'allocate' directly'; always use 'new'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="SalientComment">//:: ensure we never call 'new' without translating it (unless we add special-cases later)</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case NEW: <span class="Delimiter">{</span>
+ raise << <span class="Constant">"no implementation for 'new'; why wasn't it translated to 'allocate'?</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
<span class="CommentedCode">//? :(before "End Globals")</span>
<span class="CommentedCode">//? long long int Total_alloc = 0;</span>
<span class="CommentedCode">//? long long int Num_alloc = 0;</span>
@@ -163,13 +183,13 @@ void ensure_space<span class="Delimiter">(</span>long long int size<span class="
Current_routine<span class="Delimiter">-></span>alloc = Memory_allocated_until<span class="Delimiter">;</span>
Memory_allocated_until += Initial_memory_per_routine<span class="Delimiter">;</span>
Current_routine<span class="Delimiter">-></span>alloc_max = Memory_allocated_until<span class="Delimiter">;</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"new"</span><span class="Delimiter">)</span> << <span class="Constant">"routine allocated memory from "</span> << Current_routine<span class="Delimiter">-></span>alloc << <span class="Constant">" to "</span> << Current_routine<span class="Delimiter">-></span>alloc_max << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"new"</span><span class="Delimiter">)</span> << <span class="Constant">"routine allocated memory from "</span> << Current_routine<span class="Delimiter">-></span>alloc << <span class="Constant">" to "</span> << Current_routine<span class="Delimiter">-></span>alloc_max << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(scenario new_initializes)</span>
<span class="Special">% Memory_allocated_until = 10;</span>
-<span class="Special">% Memory[Memory_allocated_until] = 1;</span>
+<span class="Special">% put(Memory, Memory_allocated_until, 1);</span>
recipe main [
<span class="Constant">1</span>:address:number<span class="Special"> <- </span>new number:type
<span class="Constant">2</span>:number<span class="Special"> <- </span>copy *<span class="Constant">1</span>:address:number
@@ -247,25 +267,31 @@ Free_list<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
ABANDON<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"abandon"</span>] = ABANDON<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"abandon"</span><span class="Delimiter">,</span> ABANDON<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case ABANDON: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'abandon' requires one ingredient, but got '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ 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>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'abandon' requires one ingredient, but got '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'abandon' should be an address, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ reagent types = inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ canonize_type<span class="Delimiter">(</span>types<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!types<span class="Delimiter">.</span>type || types<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>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'abandon' should be an address, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="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">:(before "End Primitive Recipe Implementations")</span>
+case ABANDON: <span class="Delimiter">{</span>
long long int address = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- reagent types = canonize<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
- if <span class="Delimiter">(</span>types<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> || types<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> != Type_ordinal[<span class="Constant">"address"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'abandon' should be an address, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- reagent target_type = lookup_memory<span class="Delimiter">(</span>types<span class="Delimiter">);</span>
- abandon<span class="Delimiter">(</span>address<span class="Delimiter">,</span> size_of<span class="Delimiter">(</span>target_type<span class="Delimiter">));</span>
+ reagent types = 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>
+ canonize<span class="Delimiter">(</span>types<span class="Delimiter">);</span>
+ <span class="Comment">// lookup_memory without drop_one_lookup {</span>
+ types<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> types<span class="Delimiter">.</span>value<span class="Delimiter">));</span>
+ drop_address_from_type<span class="Delimiter">(</span>types<span class="Delimiter">);</span>
+ <span class="Comment">// }</span>
+ abandon<span class="Delimiter">(</span>address<span class="Delimiter">,</span> size_of<span class="Delimiter">(</span>types<span class="Delimiter">));</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -276,26 +302,26 @@ void abandon<span class="Delimiter">(</span>long long int address<span class="De
<span class="CommentedCode">//? cerr << "abandon: " << size << '\n';</span>
<span class="Comment">// clear memory</span>
for <span class="Delimiter">(</span>long long int curr = address<span class="Delimiter">;</span> curr < address+size<span class="Delimiter">;</span> ++curr<span class="Delimiter">)</span>
- Memory[curr] = <span class="Constant">0</span><span class="Delimiter">;</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> curr<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span>
<span class="Comment">// append existing free list to address</span>
- Memory[address] = Free_list[size]<span class="Delimiter">;</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">,</span> Free_list[size]<span class="Delimiter">);</span>
Free_list[size] = address<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
-<span class="Delimiter">:(before "ensure_space(size)" following "case NEW")</span>
+<span class="Delimiter">:(before "ensure_space(size)" following "case ALLOCATE")</span>
if <span class="Delimiter">(</span>Free_list[size]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
long long int result = Free_list[size]<span class="Delimiter">;</span>
- Free_list[size] = Memory[result]<span class="Delimiter">;</span>
+ Free_list[size] = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> result<span class="Delimiter">);</span>
for <span class="Delimiter">(</span>long long int curr = result+<span class="Constant">1</span><span class="Delimiter">;</span> curr < result+size<span class="Delimiter">;</span> ++curr<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>Memory[curr] != <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": memory in free list was not zeroed out: "</span> << curr << <span class="Constant">'/'</span> << result << <span class="Constant">"; somebody wrote to us after free!!!</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> curr<span class="Delimiter">)</span> != <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"memory in free list was not zeroed out: "</span> << curr << <span class="Constant">'/'</span> << result << <span class="Constant">"; somebody wrote to us after free!!!</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Comment">// always fatal</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span>
- Memory[result] = array_length<span class="Delimiter">;</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> result<span class="Delimiter">,</span> ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
else
- Memory[result] = <span class="Constant">0</span><span class="Delimiter">;</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> result<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
@@ -341,23 +367,16 @@ recipe main [
<span class="Comment"># unicode for '«'</span>
<span class="traceContains">+mem: storing 171 in location 3</span>
-<span class="Delimiter">:(before "End NEW Transform Special-cases")</span>
- if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">()</span>
- && !inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>empty<span class="Delimiter">()</span>
- && !inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>empty<span class="Delimiter">()</span>
- && inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">"literal-string"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- <span class="Comment">// skip transform</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>initialized = <span class="Constant">true</span><span class="Delimiter">;</span>
- <span class="Identifier">goto</span> end_new_transform<span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
-
+<span class="Delimiter">:(before "End NEW Check Special-cases")</span>
+if <span class="Delimiter">(</span>is_literal_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">:(before "Convert 'new' To 'allocate'")</span>
+if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">"new"</span> && is_literal_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
<span class="Delimiter">:(after "case NEW" following "Primitive Recipe Implementations")</span>
-if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span>
- && current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">"literal-string"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
- products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>new_mu_string<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">));</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
-<span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>is_literal_string<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
+ products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>new_mu_string<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">));</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
<span class="Delimiter">:(code)</span>
long long int new_mu_string<span class="Delimiter">(</span>const string& contents<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -368,14 +387,14 @@ long long int new_mu_string<span class="Delimiter">(</span>const string& con
ensure_space<span class="Delimiter">(</span>string_length+<span class="Constant">1</span><span class="Delimiter">);</span> <span class="Comment">// don't forget the extra location for array size</span>
<span class="Comment">// initialize string</span>
long long int result = Current_routine<span class="Delimiter">-></span>alloc<span class="Delimiter">;</span>
- Memory[Current_routine<span class="Delimiter">-></span>alloc++] = string_length<span class="Delimiter">;</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> Current_routine<span class="Delimiter">-></span>alloc++<span class="Delimiter">,</span> string_length<span class="Delimiter">);</span>
long long int curr = <span class="Constant">0</span><span class="Delimiter">;</span>
const char* raw_contents = contents<span class="Delimiter">.</span>c_str<span class="Delimiter">();</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < string_length<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
uint32_t curr_character<span class="Delimiter">;</span>
assert<span class="Delimiter">(</span>curr < SIZE<span class="Delimiter">(</span>contents<span class="Delimiter">));</span>
tb_utf8_char_to_unicode<span class="Delimiter">(</span>&curr_character<span class="Delimiter">,</span> &raw_contents[curr]<span class="Delimiter">);</span>
- Memory[Current_routine<span class="Delimiter">-></span>alloc] = curr_character<span class="Delimiter">;</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> Current_routine<span class="Delimiter">-></span>alloc<span class="Delimiter">,</span> curr_character<span class="Delimiter">);</span>
curr += tb_utf8_char_length<span class="Delimiter">(</span>raw_contents[curr]<span class="Delimiter">);</span>
++Current_routine<span class="Delimiter">-></span>alloc<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -383,6 +402,17 @@ long long int new_mu_string<span class="Delimiter">(</span>const string& con
<span class="Identifier">return</span> result<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+<span class="Comment">//: pass in commandline args as ingredients to main</span>
+<span class="Comment">//: todo: test this</span>
+
+<span class="Delimiter">:(after "Update main_routine")</span>
+Current_routine = main_routine<span class="Delimiter">;</span>
+for <span class="Delimiter">(</span>long long int i = <span class="Constant">1</span><span class="Delimiter">;</span> i < argc<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ vector<double> arg<span class="Delimiter">;</span>
+ arg<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_mu_string<span class="Delimiter">(</span>argv[i]<span class="Delimiter">));</span>
+ current_call<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>arg<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
<span class="Comment">//: stash recognizes strings</span>
<span class="Delimiter">:(scenario stash_string)</span>
@@ -398,6 +428,13 @@ if <span class="Delimiter">(</span>is_mu_string<span class="Delimiter">(</span>r
<span class="Identifier">return</span> read_mu_string<span class="Delimiter">(</span>data<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
<span class="Delimiter">}</span>
+<span class="Delimiter">:(scenario unicode_string)</span>
+recipe main [
+ x:address:array:character<span class="Special"> <- </span>new [♠]
+ stash [foo:]<span class="Delimiter">,</span> x:address:array:character
+]
+<span class="traceContains">+app: foo: ♠</span>
+
<span class="Comment">//: Allocate more to routine when initializing a literal string</span>
<span class="Delimiter">:(scenario new_string_overflow)</span>
<span class="Special">% Initial_memory_per_routine = 2;</span>
@@ -423,22 +460,30 @@ long long int unicode_length<span class="Delimiter">(</span>const string& s<
<span class="Delimiter">}</span>
bool is_mu_string<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- <span class="Identifier">return</span> SIZE<span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">)</span> == <span class="Constant">3</span>
- && x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == Type_ordinal[<span class="Constant">"address"</span>]
- && x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)</span> == Type_ordinal[<span class="Constant">"array"</span>]
- && x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">)</span> == Type_ordinal[<span class="Constant">"character"</span>]<span class="Delimiter">;</span>
+ <span class="Identifier">return</span> x<span class="Delimiter">.</span>type
+ && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">)</span>
+ && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right
+ && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">)</span>
+ && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right
+ && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"character"</span><span class="Delimiter">)</span>
+ && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right == <span class="Constant">NULL</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
string read_mu_string<span class="Delimiter">(</span>long long int address<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- long long int size = Memory[address]<span class="Delimiter">;</span>
+ long long int size = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>size == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">""</span><span class="Delimiter">;</span>
ostringstream tmp<span class="Delimiter">;</span>
for <span class="Delimiter">(</span>long long int curr = address+<span class="Constant">1</span><span class="Delimiter">;</span> curr <= address+size<span class="Delimiter">;</span> ++curr<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- <span class="Comment">// todo: unicode</span>
- tmp << <span class="Delimiter">(</span>char<span class="Delimiter">)(</span>int<span class="Delimiter">)</span>Memory[curr]<span class="Delimiter">;</span>
+ tmp << to_unicode<span class="Delimiter">(</span>static_cast<uint32_t><span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> curr<span class="Delimiter">)));</span>
<span class="Delimiter">}</span>
<span class="Identifier">return</span> tmp<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
+
+bool is_mu_type_literal<span class="Delimiter">(</span>reagent r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+<span class="CommentedCode">//? if (!r.properties.empty())</span>
+<span class="CommentedCode">//? dump_property(r.properties.at(0).second, cerr);</span>
+ <span class="Identifier">return</span> is_literal<span class="Delimiter">(</span>r<span class="Delimiter">)</span> && !r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second && r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">-></span>value == <span class="Constant">"type"</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
</pre>
</body>
</html>
diff --git a/html/044space.cc.html b/html/044space.cc.html
index 7c46d504..0bd414cb 100644
--- a/html/044space.cc.html
+++ b/html/044space.cc.html
@@ -13,9 +13,9 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.traceContains { color: #008000; }
.traceAbsent { color: #c00000; }
.SalientComment { color: #00ffff; }
-.traceContains { color: #008000; }
.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
@@ -42,7 +42,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># then location 0 is really location 11, location 1 is really location 12, and so on.</span>
recipe main [
<span class="Constant">10</span>:number<span class="Special"> <- </span>copy <span class="Constant">5</span> <span class="Comment"># pretend array; in practice we'll use new</span>
- default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span>
+ default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span>/<span class="Special">raw</span>
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">23</span>
]
<span class="traceContains">+mem: storing 23 in location 12</span>
@@ -54,14 +54,15 @@ recipe main [
<span class="Comment"># pretend array</span>
<span class="Constant">1000</span>:number<span class="Special"> <- </span>copy <span class="Constant">5</span>
<span class="Comment"># actual start of this recipe</span>
- default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">1000</span>
- <span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">3</span>
+ default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">1000</span>/<span class="Special">raw</span>
+ <span class="Constant">1</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">3</span>/<span class="Special">raw</span>
<span class="Constant">8</span>:number/<span class="Special">raw <- </span>copy *<span class="Constant">1</span>:address:number
]
<span class="traceContains">+mem: storing 34 in location 8</span>
<span class="SalientComment">//:: first disable name conversion for 'default-space'</span>
<span class="Delimiter">:(scenario convert_names_passes_default_space)</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
default-space:number<span class="Delimiter">,</span> x:number<span class="Special"> <- </span>copy <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">1</span>
]
@@ -80,24 +81,19 @@ long long int default_space<span class="Delimiter">;</span>
<span class="Delimiter">:(before "End call Constructor")</span>
default_space = <span class="Constant">0</span><span class="Delimiter">;</span>
-<span class="Delimiter">:(replace "reagent r = x" following "reagent canonize(reagent x)")</span>
-reagent r = absolutize<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End canonize(x) Special-cases")</span>
+ absolutize<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
<span class="Delimiter">:(code)</span>
-reagent absolutize<span class="Delimiter">(</span>reagent x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">)</span> || is_dummy<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> x<span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"default-space"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> x<span class="Delimiter">;</span>
+void absolutize<span class="Delimiter">(</span>reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">)</span> || is_dummy<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"default-space"</span><span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
if <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>initialized<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">": reagent not initialized: "</span> << x<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">return</span> x<span class="Delimiter">;</span>
+ raise_error << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">": reagent not initialized: "</span> << x<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
- reagent r = x<span class="Delimiter">;</span>
- r<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>address<span class="Delimiter">(</span>r<span class="Delimiter">.</span>value<span class="Delimiter">,</span> space_base<span class="Delimiter">(</span>r<span class="Delimiter">)));</span>
- r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> vector<string> ><span class="Delimiter">(</span><span class="Constant">"raw"</span><span class="Delimiter">,</span> vector<string><span class="Delimiter">()));</span>
- assert<span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>r<span class="Delimiter">));</span>
- <span class="Identifier">return</span> r<span class="Delimiter">;</span>
+ x<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>address<span class="Delimiter">(</span>x<span class="Delimiter">.</span>value<span class="Delimiter">,</span> space_base<span class="Delimiter">(</span>x<span class="Delimiter">)));</span>
+ x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> string_tree*><span class="Delimiter">(</span><span class="Constant">"raw"</span><span class="Delimiter">,</span> <span class="Constant">NULL</span><span class="Delimiter">));</span>
+ assert<span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">));</span>
<span class="Delimiter">}</span>
-<span class="Delimiter">:(before "return result" following "reagent lookup_memory(reagent x)")</span>
-result<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> vector<string> ><span class="Delimiter">(</span><span class="Constant">"raw"</span><span class="Delimiter">,</span> vector<string><span class="Delimiter">()));</span>
<span class="SalientComment">//:: fix 'get'</span>
@@ -109,14 +105,14 @@ recipe main [
<span class="Comment"># pretend array</span>
<span class="Constant">1000</span>:number<span class="Special"> <- </span>copy <span class="Constant">5</span>
<span class="Comment"># actual start of this recipe</span>
- default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">1000</span>
- <span class="Constant">1</span>:address:point<span class="Special"> <- </span>copy <span class="Constant">12</span>
+ default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">1000</span>/<span class="Special">raw</span>
+ <span class="Constant">1</span>:address:point<span class="Special"> <- </span>copy <span class="Constant">12</span>/<span class="Special">raw</span>
<span class="Constant">9</span>:number/<span class="Special">raw <- </span>get *<span class="Constant">1</span>:address:point<span class="Delimiter">,</span> <span class="Constant">1</span>:offset
]
<span class="traceContains">+mem: storing 35 in location 9</span>
<span class="Delimiter">:(after "reagent tmp" following "case GET:")</span>
-tmp<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> vector<string> ><span class="Delimiter">(</span><span class="Constant">"raw"</span><span class="Delimiter">,</span> vector<string><span class="Delimiter">()));</span>
+tmp<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> string_tree*><span class="Delimiter">(</span><span class="Constant">"raw"</span><span class="Delimiter">,</span> <span class="Constant">NULL</span><span class="Delimiter">));</span>
<span class="SalientComment">//:: fix 'index'</span>
@@ -129,14 +125,14 @@ recipe main [
<span class="Comment"># pretend array</span>
<span class="Constant">1000</span>:number<span class="Special"> <- </span>copy <span class="Constant">5</span>
<span class="Comment"># actual start of this recipe</span>
- default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">1000</span>
- <span class="Constant">1</span>:address:array:number<span class="Special"> <- </span>copy <span class="Constant">12</span>
+ default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">1000</span>/<span class="Special">raw</span>
+ <span class="Constant">1</span>:address:array:number<span class="Special"> <- </span>copy <span class="Constant">12</span>/<span class="Special">raw</span>
<span class="Constant">9</span>:number/<span class="Special">raw <- </span>index *<span class="Constant">1</span>:address:array:number<span class="Delimiter">,</span> <span class="Constant">1</span>
]
<span class="traceContains">+mem: storing 35 in location 9</span>
<span class="Delimiter">:(after "reagent tmp" following "case INDEX:")</span>
-tmp<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> vector<string> ><span class="Delimiter">(</span><span class="Constant">"raw"</span><span class="Delimiter">,</span> vector<string><span class="Delimiter">()));</span>
+tmp<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> string_tree*><span class="Delimiter">(</span><span class="Constant">"raw"</span><span class="Delimiter">,</span> <span class="Constant">NULL</span><span class="Delimiter">));</span>
<span class="SalientComment">//:: convenience operation to automatically deduce the amount of space to</span>
<span class="SalientComment">//:: allocate in a default space with names</span>
@@ -156,7 +152,7 @@ if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <spa
<span class="Delimiter">:(before "End is_special_name Cases")</span>
if <span class="Delimiter">(</span>s == <span class="Constant">"number-of-locals"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Rewrite Instruction(curr)")</span>
+<span class="Delimiter">:(before "End Rewrite Instruction(curr, recipe result)")</span>
<span class="Comment">// rewrite `new-default-space` to</span>
<span class="Comment">// `default-space:address:array:location <- new location:type, number-of-locals:literal`</span>
<span class="Comment">// where N is Name[recipe][""]</span>
@@ -166,14 +162,14 @@ if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <
<span class="Delimiter">:(after "vector<double> read_memory(reagent x)")</span>
if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"number-of-locals"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
vector<double> result<span class="Delimiter">;</span>
- result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>Name[Recipe_ordinal[current_recipe_name<span class="Delimiter">()</span>]][<span class="Constant">""</span>]<span class="Delimiter">);</span>
+ result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>Name[get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> current_recipe_name<span class="Delimiter">())</span>][<span class="Constant">""</span>]<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>result<span class="Delimiter">.</span>back<span class="Delimiter">()</span> == <span class="Constant">0</span><span class="Delimiter">)</span>
- raise << <span class="Constant">"no space allocated for default-space in recipe "</span> << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">"; are you using names</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"no space allocated for default-space in recipe "</span> << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">"; are you using names?</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">return</span> result<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(after "void write_memory(reagent x, vector<double> data)")</span>
if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"number-of-locals"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": can't write to special name 'number-of-locals'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"can't write to special name 'number-of-locals'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">return</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -201,7 +197,7 @@ try_reclaim_locals<span class="Delimiter">();</span>
<span class="Comment">//: now 'local-scope' is identical to 'new-default-space' except that we'll</span>
<span class="Comment">//: reclaim the default-space when the routine exits</span>
-<span class="Delimiter">:(before "End Rewrite Instruction(curr)")</span>
+<span class="Delimiter">:(before "End Rewrite Instruction(curr, recipe result)")</span>
if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"local-scope"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
rewrite_default_space_instruction<span class="Delimiter">(</span>curr<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
@@ -209,22 +205,22 @@ if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <
<span class="Delimiter">:(code)</span>
void try_reclaim_locals<span class="Delimiter">()</span> <span class="Delimiter">{</span>
<span class="Comment">// only reclaim routines starting with 'local-scope'</span>
- const recipe_ordinal r = Recipe_ordinal[current_recipe_name<span class="Delimiter">()</span>]<span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
- const instruction& inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name != <span class="Constant">"local-scope"</span><span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
- abandon<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>default_space<span class="Delimiter">,</span>
+ const recipe_ordinal r = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> current_recipe_name<span class="Delimiter">());</span>
+ if <span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
+ const instruction& inst = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>old_name != <span class="Constant">"local-scope"</span><span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
+ abandon<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>default_space<span class="Delimiter">,</span>
<span class="Comment">/*</span><span class="Comment">array length</span><span class="Comment">*/</span><span class="Constant">1</span>+<span class="Comment">/*</span><span class="Comment">number-of-locals</span><span class="Comment">*/</span>Name[r][<span class="Constant">""</span>]<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
void rewrite_default_space_instruction<span class="Delimiter">(</span>instruction& curr<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- curr<span class="Delimiter">.</span>operation = Recipe_ordinal[<span class="Constant">"new"</span>]<span class="Delimiter">;</span>
if <span class="Delimiter">(</span>!curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span>
- raise << <span class="Constant">"new-default-space can't take any ingredients</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << curr<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">" can't take any ingredients</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ curr<span class="Delimiter">.</span>name = <span class="Constant">"new"</span><span class="Delimiter">;</span>
curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span><span class="Constant">"location:type"</span><span class="Delimiter">));</span>
curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span><span class="Constant">"number-of-locals:literal"</span><span class="Delimiter">));</span>
if <span class="Delimiter">(</span>!curr<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span>
- raise << <span class="Constant">"new-default-space can't take any results</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ 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:array:location"</span><span class="Delimiter">));</span>
<span class="Delimiter">}</span>
@@ -232,37 +228,46 @@ void rewrite_default_space_instruction<span class="Delimiter">(</span>instructio
<span class="Delimiter">:(code)</span>
long long int space_base<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- <span class="Identifier">return</span> Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>default_space<span class="Delimiter">;</span>
+ <span class="Comment">// temporary stub; will be replaced in a later layer</span>
+ <span class="Identifier">return</span> current_call<span class="Delimiter">().</span>default_space<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
long long int address<span class="Delimiter">(</span>long long int offset<span class="Delimiter">,</span> long long int base<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>base == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> offset<span class="Delimiter">;</span> <span class="Comment">// raw</span>
- if <span class="Delimiter">(</span>offset >= static_cast<long long int><span class="Delimiter">(</span>Memory[base]<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>offset >= static_cast<long long int><span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> base<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
<span class="Comment">// todo: test</span>
- raise << <span class="Constant">"location "</span> << offset << <span class="Constant">" is out of bounds "</span> << Memory[base] << <span class="Constant">" at "</span> << base << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"location "</span> << offset << <span class="Constant">" is out of bounds "</span> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> base<span class="Delimiter">))</span> << <span class="Constant">" at "</span> << base << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
<span class="Identifier">return</span> base+<span class="Constant">1</span> + offset<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(after "void write_memory(reagent x, vector<double> data)")</span>
if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"default-space"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>data<span class="Delimiter">))</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'default-space' should be of type address:array:location, but tried to write "</span> << to_string<span class="Delimiter">(</span>data<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>default_space = data<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>data<span class="Delimiter">)</span>
+ || !x<span class="Delimiter">.</span>type
+ || x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">)</span>
+ || !x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right
+ || x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">)</span>
+ || !x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right
+ || x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"location"</span><span class="Delimiter">)</span>
+ || x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"'default-space' should be of type address:array:location, but tried to write "</span> << to_string<span class="Delimiter">(</span>data<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Delimiter">}</span>
+ current_call<span class="Delimiter">().</span>default_space = data<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
<span class="Identifier">return</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(scenario get_default_space)</span>
recipe main [
- default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span>
- <span class="Constant">1</span>:number/<span class="Special">raw <- </span>copy default-space:address:array:location
+ default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span>/<span class="Special">raw</span>
+ <span class="Constant">1</span>:address:array:location/<span class="Special">raw <- </span>copy default-space:address:array:location
]
<span class="traceContains">+mem: storing 10 in location 1</span>
<span class="Delimiter">:(after "vector<double> read_memory(reagent x)")</span>
if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"default-space"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
vector<double> result<span class="Delimiter">;</span>
- result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>default_space<span class="Delimiter">);</span>
+ result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>default_space<span class="Delimiter">);</span>
<span class="Identifier">return</span> result<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
</pre>
diff --git a/html/045space_surround.cc.html b/html/045space_surround.cc.html
index 6ceb3696..da74d215 100644
--- a/html/045space_surround.cc.html
+++ b/html/045space_surround.cc.html
@@ -13,8 +13,8 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
-.cSpecial { color: #008000; }
.traceContains { color: #008000; }
+.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
@@ -42,11 +42,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
recipe main [
<span class="Constant">10</span>:number<span class="Special"> <- </span>copy <span class="Constant">5</span> <span class="Comment"># pretend array</span>
<span class="Constant">20</span>:number<span class="Special"> <- </span>copy <span class="Constant">5</span> <span class="Comment"># pretend array</span>
- default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span>
- <span class="Constant">0</span>:address:array:location/names:dummy<span class="Special"> <- </span>copy <span class="Constant">20</span> <span class="Comment"># later layers will explain the /names: property</span>
+ default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span>/<span class="Special">raw</span>
+ <span class="Constant">0</span>:address:array:location/names:dummy<span class="Special"> <- </span>copy <span class="Constant">20</span>/<span class="Special">raw</span> <span class="Comment"># later layers will explain the /names: property</span>
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">32</span>
<span class="Constant">1</span>:number/space:<span class="Constant">1</span><span class="Special"> <- </span>copy <span class="Constant">33</span>
]
+recipe dummy [
+]
<span class="Comment"># chain space</span>
<span class="traceContains">+mem: storing 20 in location 11</span>
<span class="Comment"># store to default-space</span>
@@ -60,23 +62,23 @@ recipe main [
<span class="Delimiter">:(replace{} "long long int space_base(const reagent& x)")</span>
long long int space_base<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- <span class="Identifier">return</span> space_base<span class="Delimiter">(</span>x<span class="Delimiter">,</span> space_index<span class="Delimiter">(</span>x<span class="Delimiter">),</span> Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>default_space<span class="Delimiter">);</span>
+ <span class="Identifier">return</span> space_base<span class="Delimiter">(</span>x<span class="Delimiter">,</span> space_index<span class="Delimiter">(</span>x<span class="Delimiter">),</span> current_call<span class="Delimiter">().</span>default_space<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
long long int space_base<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">,</span> long long int space_index<span class="Delimiter">,</span> long long int base<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>space_index == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Identifier">return</span> base<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- long long int result = space_base<span class="Delimiter">(</span>x<span class="Delimiter">,</span> space_index-<span class="Constant">1</span><span class="Delimiter">,</span> Memory[base+<span class="Constant">1</span>]<span class="Delimiter">);</span>
+ long long int result = space_base<span class="Delimiter">(</span>x<span class="Delimiter">,</span> space_index-<span class="Constant">1</span><span class="Delimiter">,</span> get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> base+<span class="Constant">1</span><span class="Delimiter">));</span>
<span class="Identifier">return</span> result<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
long long int space_index<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
for <span class="Delimiter">(</span>long long int i = <span class="Comment">/*</span><span class="Comment">skip name:type</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>first == <span class="Constant">"space"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": /space metadata should take exactly one value in "</span> << x<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">return</span> to_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
+ if <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second || x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">-></span>right<span class="Delimiter">)</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"/space metadata should take exactly one value in "</span> << x<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span> to_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">-></span>value<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
<span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
diff --git a/html/046closure_name.cc.html b/html/046closure_name.cc.html
index 4587a5aa..13c7ddd2 100644
--- a/html/046closure_name.cc.html
+++ b/html/046closure_name.cc.html
@@ -13,13 +13,14 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.traceContains { color: #008000; }
+.Identifier { color: #804000; }
.cSpecial { color: #008000; }
.Constant { color: #00a0a0; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
-.Identifier { color: #804000; }
-.traceContains { color: #008000; }
+.CommentedCode { color: #6c6c6c; }
-->
</style>
@@ -59,47 +60,58 @@ recipe increment-counter [
reply y:number/space:<span class="Constant">1</span>
]
-<span class="traceContains">+name: recipe increment-counter is surrounded by new-counter</span>
+<span class="traceContains">+name: lexically surrounding space for recipe increment-counter comes from new-counter</span>
<span class="traceContains">+mem: storing 5 in location 3</span>
<span class="Comment">//: To make this work, compute the recipe that provides names for the</span>
-<span class="Comment">//: surrounding space of each recipe. This must happen before transform_names.</span>
+<span class="Comment">//: surrounding space of each recipe.</span>
<span class="Delimiter">:(before "End Globals")</span>
map<recipe_ordinal<span class="Delimiter">,</span> recipe_ordinal> Surrounding_space<span class="Delimiter">;</span>
-<span class="Delimiter">:(after "int main")</span>
- Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>collect_surrounding_spaces<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "Transform.push_back(transform_names)")</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>collect_surrounding_spaces<span class="Delimiter">);</span> <span class="Comment">// idempotent</span>
<span class="Delimiter">:(code)</span>
void collect_surrounding_spaces<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- const instruction& inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ 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">"--- collect surrounding spaces for recipe "</span> << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name << end<span class="Delimiter">();</span>
+<span class="CommentedCode">//? cerr << "--- collect surrounding spaces for recipe " << get(Recipe, r).name << '\n';</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ const instruction& inst = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>is_label<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>name != <span class="Constant">"0"</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>types<span class="Delimiter">)</span> != <span class="Constant">3</span>
- || inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> != Type_ordinal[<span class="Constant">"address"</span>]
- || inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)</span> != Type_ordinal[<span class="Constant">"array"</span>]
- || inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>types<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">)</span> != Type_ordinal[<span class="Constant">"location"</span>]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"slot 0 should always have type address:array:location, but is "</span> << inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ type_tree* type = inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>type<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>!type
+ || type<span class="Delimiter">-></span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">)</span>
+ || !type<span class="Delimiter">-></span>right
+ || type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">)</span>
+ || !type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right
+ || type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"location"</span><span class="Delimiter">)</span>
+ || type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << <span class="Constant">"slot 0 should always have type address:array:location, but is "</span> << inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ string_tree* s = property<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">),</span> <span class="Constant">"names"</span><span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!s<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << <span class="Constant">"slot 0 requires a /names property in recipe "</span> << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name << end<span class="Delimiter">();</span>
<span class="Identifier">continue</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- vector<string> s = property<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">),</span> <span class="Constant">"names"</span><span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>s<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"slot 0 requires a /names property in recipe "</span> << Recipe[r]<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>s<span class="Delimiter">-></span>right<span class="Delimiter">)</span> raise_error << <span class="Constant">"slot 0 should have a single value in /names, but got "</span> << inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ const string& surrounding_recipe_name = s<span class="Delimiter">-></span>value<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Surrounding_space<span class="Delimiter">,</span> r<span class="Delimiter">)</span>
+ && Surrounding_space[r] != get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> surrounding_recipe_name<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << <span class="Constant">"recipe "</span> << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name << <span class="Constant">" can have only one 'surrounding' recipe but has "</span> << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> Surrounding_space[r]<span class="Delimiter">).</span>name << <span class="Constant">" and "</span> << surrounding_recipe_name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">continue</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>s<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span> raise << <span class="Constant">"slot 0 should have a single value in /names, but got "</span> << inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- string surrounding_recipe_name = s<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>Surrounding_space<span class="Delimiter">.</span>find<span class="Delimiter">(</span>r<span class="Delimiter">)</span> != Surrounding_space<span class="Delimiter">.</span>end<span class="Delimiter">()</span>
- && Surrounding_space[r] != Recipe_ordinal[surrounding_recipe_name]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"recipe "</span> << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">" can have only one 'surrounding' recipe but has "</span> << Recipe[Surrounding_space[r]]<span class="Delimiter">.</span>name << <span class="Constant">" and "</span> << surrounding_recipe_name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"name"</span><span class="Delimiter">)</span> << <span class="Constant">"lexically surrounding space for recipe "</span> << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name << <span class="Constant">" comes from "</span> << surrounding_recipe_name << end<span class="Delimiter">();</span>
+<span class="CommentedCode">//? cerr << "lexically surrounding space for recipe " << get(Recipe, r).name << " comes from " << surrounding_recipe_name << '\n';</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> surrounding_recipe_name<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise << <span class="Constant">"can't find recipe providing surrounding space for "</span> << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name << <span class="Constant">": "</span> << surrounding_recipe_name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">continue</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- trace<span class="Delimiter">(</span><span class="Constant">"name"</span><span class="Delimiter">)</span> << <span class="Constant">"recipe "</span> << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">" is surrounded by "</span> << surrounding_recipe_name << end<span class="Delimiter">();</span>
- Surrounding_space[r] = Recipe_ordinal[surrounding_recipe_name]<span class="Delimiter">;</span>
+ Surrounding_space[r] = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> surrounding_recipe_name<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
@@ -110,12 +122,12 @@ void collect_surrounding_spaces<span class="Delimiter">(</span>const recipe_ordi
<span class="Delimiter">:(replace{} "long long int lookup_name(const reagent& r, const recipe_ordinal default_recipe)")</span>
long long int lookup_name<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">,</span> const recipe_ordinal default_recipe<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>!has_property<span class="Delimiter">(</span>x<span class="Delimiter">,</span> <span class="Constant">"space"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>Name[default_recipe]<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> raise << <span class="Constant">"name not found: "</span> << x<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>Name[default_recipe]<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> raise_error << <span class="Constant">"name not found: "</span> << x<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">return</span> Name[default_recipe][x<span class="Delimiter">.</span>name]<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- vector<string> p = property<span class="Delimiter">(</span>x<span class="Delimiter">,</span> <span class="Constant">"space"</span><span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>p<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> raise << <span class="Constant">"/space property should have exactly one (non-negative integer) value</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
- long long int n = to_integer<span class="Delimiter">(</span>p<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
+ string_tree* p = property<span class="Delimiter">(</span>x<span class="Delimiter">,</span> <span class="Constant">"space"</span><span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!p || p<span class="Delimiter">-></span>right<span class="Delimiter">)</span> raise_error << <span class="Constant">"/space property should have exactly one (non-negative integer) value</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ long long int n = to_integer<span class="Delimiter">(</span>p<span class="Delimiter">-></span>value<span class="Delimiter">);</span>
assert<span class="Delimiter">(</span>n >= <span class="Constant">0</span><span class="Delimiter">);</span>
recipe_ordinal surrounding_recipe = lookup_surrounding_recipe<span class="Delimiter">(</span>default_recipe<span class="Delimiter">,</span> n<span class="Delimiter">);</span>
set<recipe_ordinal> done<span class="Delimiter">;</span>
@@ -127,12 +139,12 @@ long long int lookup_name<span class="Delimiter">(</span>const reagent& x<sp
<span class="Comment">// recursively call transform_names on it.</span>
long long int lookup_name<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">,</span> const recipe_ordinal r<span class="Delimiter">,</span> set<recipe_ordinal>& done<span class="Delimiter">,</span> vector<recipe_ordinal>& path<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>!Name[r]<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> Name[r][x<span class="Delimiter">.</span>name]<span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>done<span class="Delimiter">.</span>find<span class="Delimiter">(</span>r<span class="Delimiter">)</span> != done<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"can't compute address of "</span> << x<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">" because "</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>done<span class="Delimiter">,</span> r<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << <span class="Constant">"can't compute address of "</span> << x<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">" because "</span> << end<span class="Delimiter">();</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>path<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << path<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i-<span class="Constant">1</span><span class="Delimiter">)</span> << <span class="Constant">" requires computing names of "</span> << path<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << path<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i-<span class="Constant">1</span><span class="Delimiter">)</span> << <span class="Constant">" requires computing names of "</span> << path<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
- raise << path<span class="Delimiter">.</span>at<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>path<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">)</span> << <span class="Constant">" requires computing names of "</span> << r << <span class="Constant">"..ad infinitum</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << path<span class="Delimiter">.</span>at<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>path<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">)</span> << <span class="Constant">" requires computing names of "</span> << r << <span class="Constant">"..ad infinitum</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
done<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>r<span class="Delimiter">);</span>
@@ -144,26 +156,26 @@ long long int lookup_name<span class="Delimiter">(</span>const reagent& x<sp
recipe_ordinal lookup_surrounding_recipe<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">,</span> long long int n<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>n == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> r<span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>Surrounding_space<span class="Delimiter">.</span>find<span class="Delimiter">(</span>r<span class="Delimiter">)</span> == Surrounding_space<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"don't know surrounding recipe of "</span> << Recipe[r]<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Surrounding_space<span class="Delimiter">,</span> r<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << <span class="Constant">"don't know surrounding recipe of "</span> << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
assert<span class="Delimiter">(</span>Surrounding_space[r]<span class="Delimiter">);</span>
<span class="Identifier">return</span> lookup_surrounding_recipe<span class="Delimiter">(</span>Surrounding_space[r]<span class="Delimiter">,</span> n-<span class="Constant">1</span><span class="Delimiter">);</span>
<span class="Delimiter">}</span>
-<span class="Comment">//: weaken use-before-set warnings just a tad</span>
+<span class="Comment">//: weaken use-before-set detection just a tad</span>
<span class="Delimiter">:(replace{} "bool already_transformed(const reagent& r, const map<string, long long int>& names)")</span>
bool already_transformed<span class="Delimiter">(</span>const reagent& r<span class="Delimiter">,</span> const map<string<span class="Delimiter">,</span> long long int>& names<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">"space"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
- vector<string> p = property<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">"space"</span><span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>p<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"/space property should have exactly one (non-negative integer) value in "</span> << r<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ string_tree* p = property<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">"space"</span><span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!p || p<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << <span class="Constant">"/space property should have exactly one (non-negative integer) value in "</span> << r<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>p<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> != <span class="Constant">"0"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>p<span class="Delimiter">-></span>value != <span class="Constant">"0"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- <span class="Identifier">return</span> names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>r<span class="Delimiter">.</span>name<span class="Delimiter">)</span> != names<span class="Delimiter">.</span>end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span> contains_key<span class="Delimiter">(</span>names<span class="Delimiter">,</span> r<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
</pre>
</body>
diff --git a/html/047global.cc.html b/html/047global.cc.html
index c90a4500..da8d790f 100644
--- a/html/047global.cc.html
+++ b/html/047global.cc.html
@@ -13,8 +13,8 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
-.cSpecial { color: #008000; }
.traceContains { color: #008000; }
+.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
@@ -42,8 +42,8 @@ recipe main [
<span class="Constant">10</span>:number<span class="Special"> <- </span>copy <span class="Constant">5</span>
<span class="Constant">20</span>:number<span class="Special"> <- </span>copy <span class="Constant">5</span>
<span class="Comment"># actual start of this recipe</span>
- global-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">20</span>
- default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span>
+ global-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">20</span>/<span class="Special">raw</span>
+ default-space:address:array:location<span class="Special"> <- </span>copy <span class="Constant">10</span>/<span class="Special">raw</span>
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">23</span>
<span class="Constant">1</span>:number/space:global<span class="Special"> <- </span>copy <span class="Constant">24</span>
]
@@ -64,10 +64,18 @@ long long int global_space<span class="Delimiter">;</span>
global_space = <span class="Constant">0</span><span class="Delimiter">;</span>
<span class="Delimiter">:(after "void write_memory(reagent x, vector<double> data)")</span>
if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"global-space"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>data<span class="Delimiter">))</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'global-space' should be of type address:array:location, but tried to write "</span> << to_string<span class="Delimiter">(</span>data<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>data<span class="Delimiter">)</span>
+ || !x<span class="Delimiter">.</span>type
+ || x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">)</span>
+ || !x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right
+ || x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">)</span>
+ || !x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right
+ || x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"location"</span><span class="Delimiter">)</span>
+ || x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"'global-space' should be of type address:array:location, but tried to write "</span> << to_string<span class="Delimiter">(</span>data<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Delimiter">}</span>
if <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>global_space<span class="Delimiter">)</span>
- raise << <span class="Constant">"routine already has a global-space; you can't over-write your globals"</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"routine already has a global-space; you can't over-write your globals"</span> << end<span class="Delimiter">();</span>
Current_routine<span class="Delimiter">-></span>global_space = data<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
<span class="Identifier">return</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -76,7 +84,7 @@ global_space = <span class="Constant">0</span><span class="Delimiter">;</span>
<span class="Delimiter">:(after "long long int space_base(const reagent& x)")</span>
if <span class="Delimiter">(</span>is_global<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>!Current_routine<span class="Delimiter">-></span>global_space<span class="Delimiter">)</span>
- raise << <span class="Constant">"routine has no global space</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"routine has no global space</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">return</span> Current_routine<span class="Delimiter">-></span>global_space<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -84,14 +92,14 @@ global_space = <span class="Constant">0</span><span class="Delimiter">;</span>
<span class="Comment">//: don't want to make them too comfortable to use.</span>
<span class="Delimiter">:(scenario global_space_with_names)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
global-space:address:array:location<span class="Special"> <- </span>new location:type<span class="Delimiter">,</span> <span class="Constant">10</span>
x:number<span class="Special"> <- </span>copy <span class="Constant">23</span>
<span class="Constant">1</span>:number/space:global<span class="Special"> <- </span>copy <span class="Constant">24</span>
]
-<span class="Comment"># don't warn that we're mixing numeric addresses and names</span>
-$warn: <span class="Constant">0</span>
+<span class="Comment"># don't complain about mixing numeric addresses and names</span>
+$error: <span class="Constant">0</span>
<span class="Delimiter">:(after "bool is_numeric_location(const reagent& x)")</span>
if <span class="Delimiter">(</span>is_global<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
@@ -102,7 +110,7 @@ $warn: <span class="Constant">0</span>
bool is_global<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
for <span class="Delimiter">(</span>long long int i = <span class="Comment">/*</span><span class="Comment">skip name:type</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>first == <span class="Constant">"space"</span><span class="Delimiter">)</span>
- <span class="Identifier">return</span> !x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">"global"</span><span class="Delimiter">;</span>
+ <span class="Identifier">return</span> x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second && x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">-></span>value == <span class="Constant">"global"</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
diff --git a/html/048check_type_by_name.cc.html b/html/048check_type_by_name.cc.html
new file mode 100644
index 00000000..d091ba31
--- /dev/null
+++ b/html/048check_type_by_name.cc.html
@@ -0,0 +1,137 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>Mu - 048check_type_by_name.cc</title>
+<meta name="Generator" content="Vim/7.4">
+<meta name="plugin-version" content="vim7.4_v1">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
+<meta name="colorscheme" content="minimal">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
+body { font-family: monospace; color: #eeeeee; background-color: #080808; }
+* { font-size: 1.05em; }
+.traceContains { color: #008000; }
+.Identifier { color: #804000; }
+.cSpecial { color: #008000; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
+.Special { color: #ff6060; }
+.CommentedCode { color: #6c6c6c; }
+.Todo { color: #000000; background-color: #ffff00; padding-bottom: 1px; }
+-->
+</style>
+
+<script type='text/javascript'>
+<!--
+
+-->
+</script>
+</head>
+<body>
+<pre id='vimCodeElement'>
+<span class="Comment">//: Some simple sanity checks for types, and also attempts to guess them where</span>
+<span class="Comment">//: they aren't provided.</span>
+<span class="Comment">//:</span>
+<span class="Comment">//: You still have to provide the full type the first time you mention a</span>
+<span class="Comment">//: variable in a recipe. You have to explicitly name :offset and :variant</span>
+<span class="Comment">//: every single time. You can't use the same name with multiple types in a</span>
+<span class="Comment">//: single recipe.</span>
+
+<span class="Delimiter">:(scenario transform_fails_on_reusing_name_with_different_type)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+ x:number<span class="Special"> <- </span>copy <span class="Constant">1</span>
+ x:boolean<span class="Special"> <- </span>copy <span class="Constant">1</span>
+]
+<span class="traceContains">+error: main: x used with multiple types</span>
+
+<span class="Delimiter">:(before "Transform.push_back(check_or_set_invalid_types)")</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_types_by_name<span class="Delimiter">);</span> <span class="Comment">// idempotent</span>
+
+<span class="Delimiter">:(code)</span>
+void check_types_by_name<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"--- deduce types for recipe "</span> << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name << end<span class="Delimiter">();</span>
+<span class="CommentedCode">//? cerr << "--- deduce types for recipe " << get(Recipe, r).name << '\n';</span>
+ map<string<span class="Delimiter">,</span> type_tree*> type<span class="Delimiter">;</span>
+ map<string<span class="Delimiter">,</span> string_tree*> type_name<span class="Delimiter">;</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ instruction& inst = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ for <span class="Delimiter">(</span>long long int in = <span class="Constant">0</span><span class="Delimiter">;</span> in < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ deduce_missing_type<span class="Delimiter">(</span>type<span class="Delimiter">,</span> type_name<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">));</span>
+ check_type<span class="Delimiter">(</span>type<span class="Delimiter">,</span> type_name<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">),</span> 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>
+ deduce_missing_type<span class="Delimiter">(</span>type<span class="Delimiter">,</span> type_name<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">));</span>
+ check_type<span class="Delimiter">(</span>type<span class="Delimiter">,</span> type_name<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">),</span> r<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+void deduce_missing_type<span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> type_tree*>& type<span class="Delimiter">,</span> map<string<span class="Delimiter">,</span> string_tree*>& type_name<span class="Delimiter">,</span> reagent& x<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="Identifier">return</span><span class="Delimiter">;</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="Identifier">return</span><span class="Delimiter">;</span>
+ x<span class="Delimiter">.</span>type = new type_tree<span class="Delimiter">(</span>*type[x<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> << 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>
+ assert<span class="Delimiter">(</span>!x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">);</span>
+ 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>*type_name[x<span class="Delimiter">.</span>name]<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+void check_type<span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> type_tree*>& type<span class="Delimiter">,</span> map<string<span class="Delimiter">,</span> string_tree*>& type_name<span class="Delimiter">,</span> const reagent& x<span class="Delimiter">,</span> const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// </span><span class="Todo">TODO</span><span class="Comment">: delete this</span>
+ <span class="Comment">// if you use raw locations you're probably doing something unsafe</span>
+ if <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// will throw a more precise error elsewhere</span>
+ 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>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>type_name<span class="Delimiter">,</span> x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ type_name[x<span class="Delimiter">.</span>name] = x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>type[x<span class="Delimiter">.</span>name]<span class="Delimiter">,</span> x<span class="Delimiter">.</span>type<span class="Delimiter">))</span>
+ 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>
+
+<span class="Delimiter">:(scenario transform_fills_in_missing_types)</span>
+recipe main [
+ x:number<span class="Special"> <- </span>copy <span class="Constant">1</span>
+ y:number<span class="Special"> <- </span>add x<span class="Delimiter">,</span> <span class="Constant">1</span>
+]
+
+<span class="Delimiter">:(scenario transform_fills_in_missing_types_in_product)</span>
+recipe main [
+ x:number<span class="Special"> <- </span>copy <span class="Constant">1</span>
+ x<span class="Special"> <- </span>copy <span class="Constant">2</span>
+]
+
+<span class="Delimiter">:(scenario transform_fills_in_missing_types_in_product_and_ingredient)</span>
+recipe main [
+ x:number<span class="Special"> <- </span>copy <span class="Constant">1</span>
+ x<span class="Special"> <- </span>add x<span class="Delimiter">,</span> <span class="Constant">1</span>
+]
+<span class="traceContains">+mem: storing 2 in location 1</span>
+
+<span class="Delimiter">:(scenario transform_fails_on_missing_types_in_first_mention)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+ x<span class="Special"> <- </span>copy <span class="Constant">1</span>
+ x:number<span class="Special"> <- </span>copy <span class="Constant">2</span>
+]
+<span class="traceContains">+error: main: missing type for x in 'x <- copy 1'</span>
+
+<span class="Delimiter">:(scenario typo_in_address_type_fails)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+ y:address:charcter<span class="Special"> <- </span>new character:type
+ *y<span class="Special"> <- </span>copy <span class="Constant">67</span>
+]
+<span class="traceContains">+error: main: unknown type in 'y:address:charcter <- new character:type'</span>
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/html/048typecheck.cc.html b/html/048typecheck.cc.html
deleted file mode 100644
index f39bc4bf..00000000
--- a/html/048typecheck.cc.html
+++ /dev/null
@@ -1,128 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-<meta http-equiv="content-type" content="text/html; charset=UTF-8">
-<title>Mu - 048typecheck.cc</title>
-<meta name="Generator" content="Vim/7.4">
-<meta name="plugin-version" content="vim7.4_v1">
-<meta name="syntax" content="cpp">
-<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
-<meta name="colorscheme" content="minimal">
-<style type="text/css">
-<!--
-pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
-body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1.05em; }
-.cSpecial { color: #008000; }
-.Constant { color: #00a0a0; }
-.Comment { color: #9090ff; }
-.Delimiter { color: #a04060; }
-.Special { color: #ff6060; }
-.Identifier { color: #804000; }
-.traceContains { color: #008000; }
--->
-</style>
-
-<script type='text/javascript'>
-<!--
-
--->
-</script>
-</head>
-<body>
-<pre id='vimCodeElement'>
-<span class="Comment">//: Some simple sanity checks for types, and also attempts to guess them where</span>
-<span class="Comment">//: they aren't provided.</span>
-<span class="Comment">//:</span>
-<span class="Comment">//: You still have to provide the full type the first time you mention a</span>
-<span class="Comment">//: variable in a recipe. You have to explicitly name :offset and :variant</span>
-<span class="Comment">//: every single time. You can't use the same name with multiple types in a</span>
-<span class="Comment">//: single recipe.</span>
-
-<span class="Delimiter">:(scenario transform_types_warns_on_reusing_name_with_different_type)</span>
-<span class="Special">% Hide_warnings = true;</span>
-recipe main [
- x:number<span class="Special"> <- </span>copy <span class="Constant">1</span>
- x:boolean<span class="Special"> <- </span>copy <span class="Constant">1</span>
-]
-<span class="traceContains">+warn: x used with multiple types in main</span>
-
-<span class="Delimiter">:(after "int main")</span>
- Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>transform_types<span class="Delimiter">);</span>
-
-<span class="Delimiter">:(code)</span>
-void transform_types<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- map<string<span class="Delimiter">,</span> vector<type_ordinal> > metadata<span class="Delimiter">;</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- instruction& inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
- for <span class="Delimiter">(</span>long long int in = <span class="Constant">0</span><span class="Delimiter">;</span> in < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- deduce_missing_type<span class="Delimiter">(</span>metadata<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">));</span>
- check_metadata<span class="Delimiter">(</span>metadata<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">),</span> r<span class="Delimiter">);</span>
- <span class="Delimiter">}</span>
- for <span class="Delimiter">(</span>long long int out = <span class="Constant">0</span><span class="Delimiter">;</span> out < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++out<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- deduce_missing_type<span class="Delimiter">(</span>metadata<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">));</span>
- check_metadata<span class="Delimiter">(</span>metadata<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">),</span> r<span class="Delimiter">);</span>
- <span class="Delimiter">}</span>
- <span class="Delimiter">}</span>
-<span class="Delimiter">}</span>
-
-void check_metadata<span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> vector<type_ordinal> >& metadata<span class="Delimiter">,</span> const reagent& x<span class="Delimiter">,</span> const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
- <span class="Comment">// if you use raw locations you're probably doing something unsafe</span>
- if <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// will throw a more precise warning elsewhere</span>
- if <span class="Delimiter">(</span>metadata<span class="Delimiter">.</span>find<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">)</span> == metadata<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
- metadata[x<span class="Delimiter">.</span>name] = x<span class="Delimiter">.</span>types<span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>metadata[x<span class="Delimiter">.</span>name] != x<span class="Delimiter">.</span>types<span class="Delimiter">)</span>
- raise << x<span class="Delimiter">.</span>name << <span class="Constant">" used with multiple types in "</span> << Recipe[r]<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
-<span class="Delimiter">}</span>
-
-<span class="Delimiter">:(scenario transform_types_fills_in_missing_types)</span>
-recipe main [
- x:number<span class="Special"> <- </span>copy <span class="Constant">1</span>
- y:number<span class="Special"> <- </span>add x<span class="Delimiter">,</span> <span class="Constant">1</span>
-]
-
-<span class="Delimiter">:(code)</span>
-void deduce_missing_type<span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> vector<type_ordinal> >& metadata<span class="Delimiter">,</span> reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>metadata<span class="Delimiter">.</span>find<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">)</span> == metadata<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
- copy<span class="Delimiter">(</span>metadata[x<span class="Delimiter">.</span>name]<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> metadata[x<span class="Delimiter">.</span>name]<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> inserter<span class="Delimiter">(</span>x<span class="Delimiter">.</span>types<span class="Delimiter">,</span> x<span class="Delimiter">.</span>types<span class="Delimiter">.</span>begin<span class="Delimiter">()));</span>
- assert<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
- x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>resize<span class="Delimiter">(</span>metadata[x<span class="Delimiter">.</span>name]<span class="Delimiter">.</span>size<span class="Delimiter">());</span>
- x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> vector<string> ><span class="Delimiter">(</span><span class="Constant">"as-before"</span><span class="Delimiter">,</span> vector<string><span class="Delimiter">()));</span>
-<span class="Delimiter">}</span>
-
-<span class="Delimiter">:(scenario transform_types_fills_in_missing_types_in_product)</span>
-recipe main [
- x:number<span class="Special"> <- </span>copy <span class="Constant">1</span>
- x<span class="Special"> <- </span>copy <span class="Constant">2</span>
-]
-
-<span class="Delimiter">:(scenario transform_types_fills_in_missing_types_in_product_and_ingredient)</span>
-recipe main [
- x:number<span class="Special"> <- </span>copy <span class="Constant">1</span>
- x<span class="Special"> <- </span>add x<span class="Delimiter">,</span> <span class="Constant">1</span>
-]
-<span class="traceContains">+mem: storing 2 in location 1</span>
-
-<span class="Delimiter">:(scenario transform_warns_on_missing_types_in_first_mention)</span>
-<span class="Special">% Hide_warnings = true;</span>
-recipe main [
- x<span class="Special"> <- </span>copy <span class="Constant">1</span>
- x:number<span class="Special"> <- </span>copy <span class="Constant">2</span>
-]
-<span class="traceContains">+warn: missing type in 'x <- copy 1'</span>
-
-<span class="Delimiter">:(scenario typo_in_address_type_warns)</span>
-<span class="Special">% Hide_warnings = true;</span>
-recipe main [
- y:address:charcter<span class="Special"> <- </span>new character:type
- *y<span class="Special"> <- </span>copy <span class="Constant">67</span>
-]
-<span class="traceContains">+warn: unknown type: charcter</span>
-</pre>
-</body>
-</html>
-<!-- vim: set foldmethod=manual : -->
diff --git a/html/050scenario.cc.html b/html/050scenario.cc.html
index e6184407..c586b575 100644
--- a/html/050scenario.cc.html
+++ b/html/050scenario.cc.html
@@ -13,10 +13,10 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
-.cSpecial { color: #008000; }
-.SalientComment { color: #00ffff; }
.traceContains { color: #008000; }
.CommentedCode { color: #6c6c6c; }
+.SalientComment { color: #00ffff; }
+.cSpecial { color: #008000; }
.traceAbsent { color: #c00000; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
@@ -110,8 +110,8 @@ else if <span class="Delimiter">(</span>command == <span class="Constant">"
scenario parse_scenario<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
scenario result<span class="Delimiter">;</span>
result<span class="Delimiter">.</span>name = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>Scenario_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>result<span class="Delimiter">.</span>name<span class="Delimiter">)</span> != Scenario_names<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
- raise << <span class="Constant">"duplicate scenario name: "</span> << result<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Scenario_names<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">))</span>
+ raise_error << <span class="Constant">"duplicate scenario name: "</span> << result<span class="Delimiter">.</span>name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
Scenario_names<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>result<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
assert<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'['</span><span class="Delimiter">);</span>
@@ -224,7 +224,11 @@ recipe main [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
RUN<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"run"</span>] = RUN<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">,</span> RUN<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case RUN: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case RUN: <span class="Delimiter">{</span>
ostringstream tmp<span class="Delimiter">;</span>
@@ -232,6 +236,11 @@ case RUN: <span class="Delimiter">{</span>
vector<recipe_ordinal> tmp_recipe = load<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>str<span class="Delimiter">());</span>
bind_special_scenario_names<span class="Delimiter">(</span>tmp_recipe<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
transform_all<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ ++Trace_stream<span class="Delimiter">-></span>callstack_depth<span class="Delimiter">;</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">"trace"</span><span class="Delimiter">)</span> << <span class="Constant">"run: incrementing callstack depth to "</span> << Trace_stream<span class="Delimiter">-></span>callstack_depth << end<span class="Delimiter">();</span>
+ assert<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>callstack_depth < <span class="Constant">9000</span><span class="Delimiter">);</span> <span class="Comment">// 9998-101 plus cushion</span>
+ <span class="Delimiter">}</span>
Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>push_front<span class="Delimiter">(</span>call<span class="Delimiter">(</span>tmp_recipe<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
<span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Comment">// not done with caller; don't increment current_step_index()</span>
<span class="Delimiter">}</span>
@@ -256,7 +265,7 @@ recipe main [
<span class="traceContains">+mem: storing 13 in location 1</span>
<span class="traceContains">+mem: storing 13 in location 2</span>
-<span class="Comment">//: 'memory-should-contain' raises warnings if specific locations aren't as expected</span>
+<span class="Comment">//: 'memory-should-contain' raises errors if specific locations aren't as expected</span>
<span class="Comment">//: Also includes some special support for checking strings.</span>
<span class="Delimiter">:(before "End Globals")</span>
@@ -266,19 +275,23 @@ Scenario_testing_scenario = <span class="Constant">false</span><span class="Deli
<span class="Delimiter">:(scenario memory_check)</span>
<span class="Special">% Scenario_testing_scenario = true;</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
memory-should-contain [
<span class="Constant">1</span><span class="Special"> <- </span><span class="Constant">13</span>
]
]
<span class="traceContains">+run: checking location 1</span>
-<span class="traceContains">+warn: expected location 1 to contain 13 but saw 0</span>
+<span class="traceContains">+error: expected location 1 to contain 13 but saw 0</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
MEMORY_SHOULD_CONTAIN<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"memory-should-contain"</span>] = MEMORY_SHOULD_CONTAIN<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"memory-should-contain"</span><span class="Delimiter">,</span> MEMORY_SHOULD_CONTAIN<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case MEMORY_SHOULD_CONTAIN: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case MEMORY_SHOULD_CONTAIN: <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
@@ -299,22 +312,22 @@ void check_memory<span class="Delimiter">(</span>const string& s<span class=
check_type<span class="Delimiter">(</span>lhs<span class="Delimiter">,</span> in<span class="Delimiter">);</span>
<span class="Identifier">continue</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- int address = to_integer<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span>
+ long long int address = to_integer<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span>
skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
string _assign<span class="Delimiter">;</span> in >> _assign<span class="Delimiter">;</span> assert<span class="Delimiter">(</span>_assign == <span class="Constant">"<-"</span><span class="Delimiter">);</span>
skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
- int value = <span class="Constant">0</span><span class="Delimiter">;</span> in >> value<span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>locations_checked<span class="Delimiter">.</span>find<span class="Delimiter">(</span>address<span class="Delimiter">)</span> != locations_checked<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
- raise << <span class="Constant">"duplicate expectation for location "</span> << address << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"checking location "</span> << address << end<span class="Delimiter">();</span>
- if <span class="Delimiter">(</span>Memory[address] != value<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ double value = <span class="Constant">0</span><span class="Delimiter">;</span> in >> value<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>locations_checked<span class="Delimiter">,</span> address<span class="Delimiter">))</span>
+ raise_error << <span class="Constant">"duplicate expectation for location "</span> << address << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"checking location "</span> << address << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">)</span> != value<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>Current_scenario && !Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Comment">// genuine test in a mu file</span>
- raise << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span> << Current_scenario<span class="Delimiter">-></span>name << <span class="Constant">": expected location "</span> << address << <span class="Constant">" to contain "</span> << value << <span class="Constant">" but saw "</span> << Memory[address] << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span> << Current_scenario<span class="Delimiter">-></span>name << <span class="Constant">": expected location "</span> << address << <span class="Constant">" to contain "</span> << no_scientific<span class="Delimiter">(</span>value<span class="Delimiter">)</span> << <span class="Constant">" but saw "</span> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">))</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
else <span class="Delimiter">{</span>
<span class="Comment">// just testing scenario support</span>
- raise << <span class="Constant">"expected location "</span> << address << <span class="Constant">" to contain "</span> << value << <span class="Constant">" but saw "</span> << Memory[address] << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"expected location "</span> << address << <span class="Constant">" to contain "</span> << no_scientific<span class="Delimiter">(</span>value<span class="Delimiter">)</span> << <span class="Constant">" but saw "</span> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">))</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
if <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span>
Passed = <span class="Constant">false</span><span class="Delimiter">;</span>
@@ -328,7 +341,7 @@ void check_memory<span class="Delimiter">(</span>const string& s<span class=
void check_type<span class="Delimiter">(</span>const string& lhs<span class="Delimiter">,</span> istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
reagent x<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">"string"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">-></span>value == <span class="Constant">"string"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
x<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>to_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">));</span>
skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
string _assign = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
@@ -342,16 +355,16 @@ void check_type<span class="Delimiter">(</span>const string& lhs<span class=
check_string<span class="Delimiter">(</span>address<span class="Delimiter">,</span> literal<span class="Delimiter">);</span>
<span class="Identifier">return</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- raise << <span class="Constant">"don't know how to check memory for "</span> << lhs << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"don't know how to check memory for "</span> << lhs << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
void check_string<span class="Delimiter">(</span>long long int address<span class="Delimiter">,</span> const string& literal<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"checking string length at "</span> << address << end<span class="Delimiter">();</span>
- if <span class="Delimiter">(</span>Memory[address] != SIZE<span class="Delimiter">(</span>literal<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"checking string length at "</span> << address << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">)</span> != SIZE<span class="Delimiter">(</span>literal<span class="Delimiter">))</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>Current_scenario && !Scenario_testing_scenario<span class="Delimiter">)</span>
- raise << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span> << Current_scenario<span class="Delimiter">-></span>name << <span class="Constant">": expected location "</span> << address << <span class="Constant">" to contain length "</span> << SIZE<span class="Delimiter">(</span>literal<span class="Delimiter">)</span> << <span class="Constant">" of string ["</span> << literal << <span class="Constant">"] but saw "</span> << Memory[address] << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span> << Current_scenario<span class="Delimiter">-></span>name << <span class="Constant">": expected location "</span> << address << <span class="Constant">" to contain length "</span> << SIZE<span class="Delimiter">(</span>literal<span class="Delimiter">)</span> << <span class="Constant">" of string ["</span> << literal << <span class="Constant">"] but saw "</span> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">))</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
else
- raise << <span class="Constant">"expected location "</span> << address << <span class="Constant">" to contain length "</span> << SIZE<span class="Delimiter">(</span>literal<span class="Delimiter">)</span> << <span class="Constant">" of string ["</span> << literal << <span class="Constant">"] but saw "</span> << Memory[address] << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"expected location "</span> << address << <span class="Constant">" to contain length "</span> << SIZE<span class="Delimiter">(</span>literal<span class="Delimiter">)</span> << <span class="Constant">" of string ["</span> << literal << <span class="Constant">"] but saw "</span> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">))</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
if <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span>
Passed = <span class="Constant">false</span><span class="Delimiter">;</span>
++Num_failures<span class="Delimiter">;</span>
@@ -360,15 +373,15 @@ void check_string<span class="Delimiter">(</span>long long int address<span clas
<span class="Delimiter">}</span>
++address<span class="Delimiter">;</span> <span class="Comment">// now skip length</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>literal<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- trace<span class="Delimiter">(</span>Primitive_recipe_depth<span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"checking location "</span> << address+i << end<span class="Delimiter">();</span>
- if <span class="Delimiter">(</span>Memory[address+i] != literal<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"checking location "</span> << address+i << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address+i<span class="Delimiter">)</span> != literal<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>Current_scenario && !Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Comment">// genuine test in a mu file</span>
- raise << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span> << Current_scenario<span class="Delimiter">-></span>name << <span class="Constant">": expected location "</span> << <span class="Delimiter">(</span>address+i<span class="Delimiter">)</span> << <span class="Constant">" to contain "</span> << literal<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> << <span class="Constant">" but saw "</span> << Memory[address+i] << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span> << Current_scenario<span class="Delimiter">-></span>name << <span class="Constant">": expected location "</span> << <span class="Delimiter">(</span>address+i<span class="Delimiter">)</span> << <span class="Constant">" to contain "</span> << literal<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> << <span class="Constant">" but saw "</span> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address+i<span class="Delimiter">))</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
else <span class="Delimiter">{</span>
<span class="Comment">// just testing scenario support</span>
- raise << <span class="Constant">"expected location "</span> << <span class="Delimiter">(</span>address+i<span class="Delimiter">)</span> << <span class="Constant">" to contain "</span> << literal<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> << <span class="Constant">" but saw "</span> << Memory[address+i] << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"expected location "</span> << <span class="Delimiter">(</span>address+i<span class="Delimiter">)</span> << <span class="Constant">" to contain "</span> << literal<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> << <span class="Constant">" but saw "</span> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address+i<span class="Delimiter">))</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
if <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span>
Passed = <span class="Constant">false</span><span class="Delimiter">;</span>
@@ -381,18 +394,18 @@ void check_string<span class="Delimiter">(</span>long long int address<span clas
<span class="Delimiter">:(scenario memory_check_multiple)</span>
<span class="Special">% Scenario_testing_scenario = true;</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
memory-should-contain [
<span class="Constant">1</span><span class="Special"> <- </span><span class="Constant">0</span>
<span class="Constant">1</span><span class="Special"> <- </span><span class="Constant">0</span>
]
]
-<span class="traceContains">+warn: duplicate expectation for location 1</span>
+<span class="traceContains">+error: duplicate expectation for location 1</span>
<span class="Delimiter">:(scenario memory_check_string_length)</span>
<span class="Special">% Scenario_testing_scenario = true;</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">3</span>
<span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">97</span> <span class="Comment"># 'a'</span>
@@ -402,7 +415,7 @@ recipe main [
<span class="Constant">1</span>:string<span class="Special"> <- </span>[ab]
]
]
-<span class="traceContains">+warn: expected location 1 to contain length 2 of string [ab] but saw 3</span>
+<span class="traceContains">+error: expected location 1 to contain length 2 of string [ab] but saw 3</span>
<span class="Delimiter">:(scenario memory_check_string)</span>
recipe main [
@@ -425,21 +438,25 @@ recipe main [
<span class="Comment">// that the lines are present *and* in the specified sequence. (There can be</span>
<span class="Comment">// other lines in between.)</span>
-<span class="Delimiter">:(scenario trace_check_warns_on_failure)</span>
+<span class="Delimiter">:(scenario trace_check_fails)</span>
<span class="Special">% Scenario_testing_scenario = true;</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
trace-should-contain [
a: b
a: d
]
]
-<span class="traceContains">+warn: missing [b] in trace with label a</span>
+<span class="traceContains">+error: missing [b] in trace with label a</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
TRACE_SHOULD_CONTAIN<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"trace-should-contain"</span>] = TRACE_SHOULD_CONTAIN<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"trace-should-contain"</span><span class="Delimiter">,</span> TRACE_SHOULD_CONTAIN<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case TRACE_SHOULD_CONTAIN: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case TRACE_SHOULD_CONTAIN: <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
@@ -448,7 +465,7 @@ case TRACE_SHOULD_CONTAIN: <span class="Delimiter">{</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(code)</span>
-<span class="Comment">// simplified version of check_trace_contents() that emits warnings rather</span>
+<span class="Comment">// simplified version of check_trace_contents() that emits errors rather</span>
<span class="Comment">// than just printing to stderr</span>
bool check_trace<span class="Delimiter">(</span>const string& expected<span class="Delimiter">)</span> <span class="Delimiter">{</span>
Trace_stream<span class="Delimiter">-></span>newline<span class="Delimiter">();</span>
@@ -465,8 +482,8 @@ bool check_trace<span class="Delimiter">(</span>const string& expected<span
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
- raise << <span class="Constant">"missing ["</span> << expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>contents << <span class="Constant">"] "</span>
- << <span class="Constant">"in trace with label "</span> << expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>label << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"missing ["</span> << expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>contents << <span class="Constant">"] "</span>
+ << <span class="Constant">"in trace with label "</span> << expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>label << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
Passed = <span class="Constant">false</span><span class="Delimiter">;</span>
<span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -483,9 +500,9 @@ vector<trace_line> parse_trace<span class="Delimiter">(</span>const string
<span class="Identifier">return</span> result<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
-<span class="Delimiter">:(scenario trace_check_warns_on_failure_in_later_line)</span>
+<span class="Delimiter">:(scenario trace_check_fails_in_nonfirst_line)</span>
<span class="Special">% Scenario_testing_scenario = true;</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
run [
trace <span class="Constant">1</span><span class="Delimiter">,</span> [a]<span class="Delimiter">,</span> [b]
@@ -495,11 +512,11 @@ recipe main [
a: d
]
]
-<span class="traceContains">+warn: missing [d] in trace with label a</span>
+<span class="traceContains">+error: missing [d] in trace with label a</span>
<span class="Delimiter">:(scenario trace_check_passes_silently)</span>
<span class="Special">% Scenario_testing_scenario = true;</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
run [
trace <span class="Constant">1</span><span class="Delimiter">,</span> [a]<span class="Delimiter">,</span> [b]
@@ -508,16 +525,16 @@ recipe main [
a: b
]
]
-<span class="traceAbsent">-warn: missing [b] in trace with label a</span>
-$warn: <span class="Constant">0</span>
+<span class="traceAbsent">-error: missing [b] in trace with label a</span>
+$error: <span class="Constant">0</span>
<span class="Comment">//: 'trace-should-not-contain' is like the '-' lines in our scenarios so far</span>
<span class="Comment">//: Each trace line is separately checked for absense. Order is *not*</span>
<span class="Comment">//: important, so you can't say things like "B should not exist after A."</span>
-<span class="Delimiter">:(scenario trace_negative_check_warns_on_failure)</span>
+<span class="Delimiter">:(scenario trace_negative_check_fails)</span>
<span class="Special">% Scenario_testing_scenario = true;</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
run [
trace <span class="Constant">1</span><span class="Delimiter">,</span> [a]<span class="Delimiter">,</span> [b]
@@ -526,12 +543,16 @@ recipe main [
a: b
]
]
-<span class="traceContains">+warn: unexpected [b] in trace with label a</span>
+<span class="traceContains">+error: unexpected [b] in trace with label a</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
TRACE_SHOULD_NOT_CONTAIN<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"trace-should-not-contain"</span>] = TRACE_SHOULD_NOT_CONTAIN<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"trace-should-not-contain"</span><span class="Delimiter">,</span> TRACE_SHOULD_NOT_CONTAIN<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case TRACE_SHOULD_NOT_CONTAIN: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case TRACE_SHOULD_NOT_CONTAIN: <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
@@ -540,14 +561,14 @@ case TRACE_SHOULD_NOT_CONTAIN: <span class="Delimiter">{</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(code)</span>
-<span class="Comment">// simplified version of check_trace_contents() that emits warnings rather</span>
+<span class="Comment">// simplified version of check_trace_contents() that emits errors rather</span>
<span class="Comment">// than just printing to stderr</span>
bool check_trace_missing<span class="Delimiter">(</span>const string& in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
Trace_stream<span class="Delimiter">-></span>newline<span class="Delimiter">();</span>
vector<trace_line> lines = parse_trace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>lines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span>lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>label<span class="Delimiter">,</span> lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>contents<span class="Delimiter">)</span> != <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"unexpected ["</span> << lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>contents << <span class="Constant">"] in trace with label "</span> << lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>label << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"unexpected ["</span> << lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>contents << <span class="Constant">"] in trace with label "</span> << lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>label << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
Passed = <span class="Constant">false</span><span class="Delimiter">;</span>
<span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -557,18 +578,18 @@ bool check_trace_missing<span class="Delimiter">(</span>const string& in<spa
<span class="Delimiter">:(scenario trace_negative_check_passes_silently)</span>
<span class="Special">% Scenario_testing_scenario = true;</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
trace-should-not-contain [
a: b
]
]
-<span class="traceAbsent">-warn: unexpected [b] in trace with label a</span>
-$warn: <span class="Constant">0</span>
+<span class="traceAbsent">-error: unexpected [b] in trace with label a</span>
+$error: <span class="Constant">0</span>
-<span class="Delimiter">:(scenario trace_negative_check_warns_on_any_unexpected_line)</span>
+<span class="Delimiter">:(scenario trace_negative_check_fails_on_any_unexpected_line)</span>
<span class="Special">% Scenario_testing_scenario = true;</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
run [
trace <span class="Constant">1</span><span class="Delimiter">,</span> [a]<span class="Delimiter">,</span> [d]
@@ -578,7 +599,7 @@ recipe main [
a: d
]
]
-<span class="traceContains">+warn: unexpected [d] in trace with label a</span>
+<span class="traceContains">+error: unexpected [d] in trace with label a</span>
<span class="Delimiter">:(scenario trace_count_check)</span>
recipe main [
@@ -591,35 +612,39 @@ recipe main [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
CHECK_TRACE_COUNT_FOR_LABEL<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"check-trace-count-for-label"</span>] = CHECK_TRACE_COUNT_FOR_LABEL<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"check-trace-count-for-label"</span><span class="Delimiter">,</span> CHECK_TRACE_COUNT_FOR_LABEL<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case CHECK_TRACE_COUNT_FOR_LABEL: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'check-trace-for-label' requires exactly two ingredients, but got '"</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'check-trace-for-label' requires exactly two ingredients, but got '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'check-trace-for-label' should be a number (count), but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'check-trace-for-label' should be a number (count), but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- long long int expected_count = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>!is_literal_string<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": second ingredient of 'check-trace-for-label' should be a literal string (label), but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_literal_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"second ingredient of 'check-trace-for-label' should be a literal string (label), but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="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">:(before "End Primitive Recipe Implementations")</span>
+case CHECK_TRACE_COUNT_FOR_LABEL: <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
+ long long int expected_count = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
string label = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">;</span>
long long int count = trace_count<span class="Delimiter">(</span>label<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>count != expected_count<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>Current_scenario && !Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Comment">// genuine test in a mu file</span>
- raise << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span> << Current_scenario<span class="Delimiter">-></span>name << <span class="Constant">": "</span> << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": expected "</span> << expected_count << <span class="Constant">" lines in trace with label "</span> << label << <span class="Constant">" in trace: "</span><span class="Delimiter">;</span>
+ raise_error << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span> << Current_scenario<span class="Delimiter">-></span>name << <span class="Constant">": "</span> << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"expected "</span> << expected_count << <span class="Constant">" lines in trace with label "</span> << label << <span class="Constant">" in trace: "</span><span class="Delimiter">;</span>
DUMP<span class="Delimiter">(</span>label<span class="Delimiter">);</span>
- raise<span class="Delimiter">;</span>
+ raise_error<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
else <span class="Delimiter">{</span>
<span class="Comment">// just testing scenario support</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": expected "</span> << expected_count << <span class="Constant">" lines in trace with label "</span> << label << <span class="Constant">" in trace</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"expected "</span> << expected_count << <span class="Constant">" lines in trace with label "</span> << label << <span class="Constant">" in trace</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
if <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span>
Passed = <span class="Constant">false</span><span class="Delimiter">;</span>
@@ -631,14 +656,14 @@ case CHECK_TRACE_COUNT_FOR_LABEL: <span class="Delimiter">{</span>
<span class="Delimiter">:(scenario trace_count_check_2)</span>
<span class="Special">% Scenario_testing_scenario = true;</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
run [
trace <span class="Constant">1</span><span class="Delimiter">,</span> [a]<span class="Delimiter">,</span> [foo]
]
check-trace-count-for-label <span class="Constant">2</span><span class="Delimiter">,</span> [a]
]
-<span class="traceContains">+warn: main: expected 2 lines in trace with label a in trace</span>
+<span class="traceContains">+error: main: expected 2 lines in trace with label a in trace</span>
<span class="Comment">//: Minor detail: ignore 'system' calls in scenarios, since anything we do</span>
<span class="Comment">//: with them is by definition impossible to test through mu.</span>
diff --git a/html/052tangle.cc.html b/html/052tangle.cc.html
index 95fc502f..4fc37210 100644
--- a/html/052tangle.cc.html
+++ b/html/052tangle.cc.html
@@ -13,6 +13,7 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.traceContains { color: #008000; }
.traceAbsent { color: #c00000; }
.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
@@ -20,7 +21,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
.Special { color: #ff6060; }
.Identifier { color: #804000; }
.Constant { color: #00a0a0; }
-.traceContains { color: #008000; }
-->
</style>
@@ -69,27 +69,29 @@ Fragments_used<span class="Delimiter">.</span>clear<span class="Delimiter">();</
<span class="Delimiter">:(before "End Command Handlers")</span>
else if <span class="Delimiter">(</span>command == <span class="Constant">"before"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
string label = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
- recipe tmp = slurp_body<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+ recipe tmp<span class="Delimiter">;</span>
+ slurp_body<span class="Delimiter">(</span>in<span class="Delimiter">,</span> tmp<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>is_waypoint<span class="Delimiter">(</span>label<span class="Delimiter">))</span>
Before_fragments[label]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>Before_fragments[label]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> tmp<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> tmp<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>end<span class="Delimiter">());</span>
else
- raise << <span class="Constant">"can't tangle before label "</span> << label << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"can't tangle before label "</span> << label << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
else if <span class="Delimiter">(</span>command == <span class="Constant">"after"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
string label = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
- recipe tmp = slurp_body<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+ recipe tmp<span class="Delimiter">;</span>
+ slurp_body<span class="Delimiter">(</span>in<span class="Delimiter">,</span> tmp<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>is_waypoint<span class="Delimiter">(</span>label<span class="Delimiter">))</span>
After_fragments[label]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>After_fragments[label]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> tmp<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> tmp<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>end<span class="Delimiter">());</span>
else
- raise << <span class="Constant">"can't tangle after label "</span> << label << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"can't tangle after label "</span> << label << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
<span class="Comment">//: after all recipes are loaded, insert fragments at appropriate labels.</span>
-<span class="Delimiter">:(after "int main")</span>
- Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>insert_fragments<span class="Delimiter">);</span>
+<span class="Delimiter">:(after "Begin Transforms")</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>insert_fragments<span class="Delimiter">);</span> <span class="Comment">// NOT idempotent</span>
-<span class="Comment">//; We might need to perform multiple passes, in case inserted fragments</span>
+<span class="Comment">//: We might need to perform multiple passes, in case inserted fragments</span>
<span class="Comment">//: include more labels that need further insertions. Track which labels we've</span>
<span class="Comment">//: already processed using an extra field.</span>
<span class="Delimiter">:(before "End instruction Fields")</span>
@@ -105,8 +107,8 @@ void insert_fragments<span class="Delimiter">(</span>const recipe_ordinal r<span
made_progress = <span class="Constant">false</span><span class="Delimiter">;</span>
<span class="Comment">// create a new vector because insertions invalidate iterators</span>
vector<instruction> result<span class="Delimiter">;</span>
- for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- const instruction& inst = Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ const instruction& inst = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>is_label || !is_waypoint<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label<span class="Delimiter">)</span> || inst<span class="Delimiter">.</span>tangle_done<span class="Delimiter">)</span> <span class="Delimiter">{</span>
result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>inst<span class="Delimiter">);</span>
<span class="Identifier">continue</span><span class="Delimiter">;</span>
@@ -115,16 +117,16 @@ void insert_fragments<span class="Delimiter">(</span>const recipe_ordinal r<span
made_progress = <span class="Constant">true</span><span class="Delimiter">;</span>
Fragments_used<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label<span class="Delimiter">);</span>
ostringstream prefix<span class="Delimiter">;</span>
- prefix << <span class="Constant">'+'</span> << Recipe[r]<span class="Delimiter">.</span>name << <span class="Constant">'_'</span> << pass << <span class="Constant">'_'</span> << i<span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>Before_fragments<span class="Delimiter">.</span>find<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label<span class="Delimiter">)</span> != Before_fragments<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+ prefix << <span class="Constant">'+'</span> << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name << <span class="Constant">'_'</span> << pass << <span class="Constant">'_'</span> << i<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Before_fragments<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>label<span class="Delimiter">))</span> <span class="Delimiter">{</span>
append_fragment<span class="Delimiter">(</span>result<span class="Delimiter">,</span> Before_fragments[inst<span class="Delimiter">.</span>label]<span class="Delimiter">.</span>steps<span class="Delimiter">,</span> prefix<span class="Delimiter">.</span>str<span class="Delimiter">());</span>
<span class="Delimiter">}</span>
result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>inst<span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>After_fragments<span class="Delimiter">.</span>find<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label<span class="Delimiter">)</span> != After_fragments<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>After_fragments<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>label<span class="Delimiter">))</span> <span class="Delimiter">{</span>
append_fragment<span class="Delimiter">(</span>result<span class="Delimiter">,</span> After_fragments[inst<span class="Delimiter">.</span>label]<span class="Delimiter">.</span>steps<span class="Delimiter">,</span> prefix<span class="Delimiter">.</span>str<span class="Delimiter">());</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
- Recipe[r]<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>swap<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
+ get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>swap<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
++pass<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
@@ -145,7 +147,7 @@ void append_fragment<span class="Delimiter">(</span>vector<instruction>&am
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>patch<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
instruction inst = patch<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>is_label<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>jump_targets<span class="Delimiter">.</span>find<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>label<span class="Delimiter">)</span> != jump_targets<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
+ if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>jump_targets<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>label<span class="Delimiter">))</span>
inst<span class="Delimiter">.</span>label = prefix+inst<span class="Delimiter">.</span>label<span class="Delimiter">;</span>
base<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>inst<span class="Delimiter">);</span>
<span class="Identifier">continue</span><span class="Delimiter">;</span>
@@ -153,7 +155,7 @@ void append_fragment<span class="Delimiter">(</span>vector<instruction>&am
for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span>
reagent& x = inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">"label"</span> && jump_targets<span class="Delimiter">.</span>find<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">)</span> != jump_targets<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
+ if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">-></span>value == <span class="Constant">"label"</span> && contains_key<span class="Delimiter">(</span>jump_targets<span class="Delimiter">,</span> x<span class="Delimiter">.</span>name<span class="Delimiter">))</span>
x<span class="Delimiter">.</span>name = prefix+x<span class="Delimiter">.</span>name<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
base<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>inst<span class="Delimiter">);</span>
@@ -164,22 +166,22 @@ bool is_waypoint<span class="Delimiter">(</span>string label<span class="Delimit
<span class="Identifier">return</span> *label<span class="Delimiter">.</span>begin<span class="Delimiter">()</span> == <span class="Constant">'<'</span> && *label<span class="Delimiter">.</span>rbegin<span class="Delimiter">()</span> == <span class="Constant">'>'</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
-<span class="Comment">//: warn about unapplied fragments</span>
+<span class="Comment">//: complain about unapplied fragments</span>
<span class="Delimiter">:(before "End Globals")</span>
bool Transform_check_insert_fragments_Ran = <span class="Constant">false</span><span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End One-time Setup")</span>
-Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_insert_fragments<span class="Delimiter">);</span> <span class="Comment">// final transform</span>
+<span class="Delimiter">:(after "Transform.push_back(insert_fragments)")</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_insert_fragments<span class="Delimiter">);</span> <span class="Comment">// idempotent</span>
<span class="Delimiter">:(code)</span>
void check_insert_fragments<span class="Delimiter">(</span>unused recipe_ordinal<span class="Delimiter">)</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>Transform_check_insert_fragments_Ran<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
Transform_check_insert_fragments_Ran = <span class="Constant">true</span><span class="Delimiter">;</span>
for <span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> recipe>::iterator p = Before_fragments<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Before_fragments<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>Fragments_used<span class="Delimiter">.</span>find<span class="Delimiter">(</span>p<span class="Delimiter">-></span>first<span class="Delimiter">)</span> == Fragments_used<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
- raise << <span class="Constant">"could not locate insert before "</span> << p<span class="Delimiter">-></span>first << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Fragments_used<span class="Delimiter">,</span> p<span class="Delimiter">-></span>first<span class="Delimiter">))</span>
+ raise_error << <span class="Constant">"could not locate insert before "</span> << p<span class="Delimiter">-></span>first << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
for <span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> recipe>::iterator p = After_fragments<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != After_fragments<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>Fragments_used<span class="Delimiter">.</span>find<span class="Delimiter">(</span>p<span class="Delimiter">-></span>first<span class="Delimiter">)</span> == Fragments_used<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
- raise << <span class="Constant">"could not locate insert after "</span> << p<span class="Delimiter">-></span>first << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Fragments_used<span class="Delimiter">,</span> p<span class="Delimiter">-></span>first<span class="Delimiter">))</span>
+ raise_error << <span class="Constant">"could not locate insert after "</span> << p<span class="Delimiter">-></span>first << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
@@ -204,7 +206,7 @@ after <label1> [
$mem: <span class="Constant">4</span>
<span class="Delimiter">:(scenario tangle_ignores_jump_target)</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
+label1
@@ -213,7 +215,7 @@ recipe main [
before +label1 [
<span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
]
-<span class="traceContains">+warn: can't tangle before label +label1</span>
+<span class="traceContains">+error: can't tangle before label +label1</span>
<span class="traceContains">+mem: storing 0 in location 1</span>
<span class="traceContains">+mem: storing 0 in location 4</span>
<span class="Comment"># label1</span>
diff --git a/html/053continuation.cc.html b/html/053continuation.cc.html
deleted file mode 100644
index 7e3623fb..00000000
--- a/html/053continuation.cc.html
+++ /dev/null
@@ -1,278 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-<meta http-equiv="content-type" content="text/html; charset=UTF-8">
-<title>Mu - 053continuation.cc</title>
-<meta name="Generator" content="Vim/7.4">
-<meta name="plugin-version" content="vim7.4_v1">
-<meta name="syntax" content="cpp">
-<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
-<meta name="colorscheme" content="minimal">
-<style type="text/css">
-<!--
-pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
-body { font-family: monospace; color: #eeeeee; background-color: #080808; }
-* { font-size: 1.05em; }
-.cSpecial { color: #008000; }
-.SalientComment { color: #00ffff; }
-.traceAbsent { color: #c00000; }
-.traceContains { color: #008000; }
-.Constant { color: #00a0a0; }
-.Comment { color: #9090ff; }
-.Delimiter { color: #a04060; }
-.Special { color: #ff6060; }
-.Identifier { color: #804000; }
--->
-</style>
-
-<script type='text/javascript'>
-<!--
-
--->
-</script>
-</head>
-<body>
-<pre id='vimCodeElement'>
-<span class="Comment">//: Continuations are a powerful primitive for constructing advanced kinds of</span>
-<span class="Comment">//: control *policies* like back-tracking. They're usually provided using a</span>
-<span class="Comment">//: primitive called 'call-cc': <a href="http://en.wikipedia.org/wiki/Call-with-current-continuation)">http://en.wikipedia.org/wiki/Call-with-current-continuation)</a></span>
-<span class="Comment">//: But in mu 'call-cc' is constructed out of a combination of two primitives:</span>
-<span class="Comment">//: 'current-continuation', which returns a continuation, and</span>
-<span class="Comment">//: 'continue-from', which takes a continuation to switch to.</span>
-
-<span class="Comment">//: todo: implement continuations in mu's memory</span>
-<span class="Delimiter">:(before "End Globals")</span>
-map<long long int<span class="Delimiter">,</span> call_stack> Continuation<span class="Delimiter">;</span>
-long long int Next_continuation_id = <span class="Constant">0</span><span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Setup")</span>
-Continuation<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
-Next_continuation_id = <span class="Constant">0</span><span class="Delimiter">;</span>
-
-<span class="Delimiter">:(before "End Mu Types Initialization")</span>
-type_ordinal continuation = Type_ordinal[<span class="Constant">"continuation"</span>] = Next_type_ordinal++<span class="Delimiter">;</span>
-Type[continuation]<span class="Delimiter">.</span>name = <span class="Constant">"continuation"</span><span class="Delimiter">;</span>
-
-<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
-CURRENT_CONTINUATION<span class="Delimiter">,</span>
-<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"current-continuation"</span>] = CURRENT_CONTINUATION<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
-case CURRENT_CONTINUATION: <span class="Delimiter">{</span>
- <span class="Comment">// copy the current call stack</span>
- Continuation[Next_continuation_id] = Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">;</span> <span class="Comment">// deep copy because calls have no pointers</span>
- <span class="Comment">// make sure calling the copy doesn't spawn the same continuation again</span>
- ++Continuation[Next_continuation_id]<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_step_index<span class="Delimiter">;</span>
- products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
- products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>Next_continuation_id<span class="Delimiter">);</span>
- ++Next_continuation_id<span class="Delimiter">;</span>
- trace<span class="Delimiter">(</span><span class="Constant">"current-continuation"</span><span class="Delimiter">)</span> << <span class="Constant">"new continuation "</span> << Next_continuation_id << end<span class="Delimiter">();</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
-<span class="Delimiter">}</span>
-
-<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
-CONTINUE_FROM<span class="Delimiter">,</span>
-<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"continue-from"</span>] = CONTINUE_FROM<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
-case CONTINUE_FROM: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'continue-from' should be a continuation id generated by 'current-continuation', but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- long long int c = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- Current_routine<span class="Delimiter">-></span>calls = Continuation[c]<span class="Delimiter">;</span> <span class="Comment">// deep copy; calls have no pointers</span>
- <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Comment">// skip rest of this instruction</span>
-<span class="Delimiter">}</span>
-
-<span class="Delimiter">:(scenario continuation)</span>
-<span class="Comment"># simulate a loop using continuations</span>
-recipe main [
- <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
- <span class="Constant">2</span>:continuation<span class="Special"> <- </span>current-continuation
- <span class="Delimiter">{</span>
- <span class="Constant">3</span>:boolean<span class="Special"> <- </span>greater-or-equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">3</span>
- <span class="Identifier">break</span>-if <span class="Constant">3</span>:boolean
- <span class="Constant">1</span>:number<span class="Special"> <- </span>add <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">1</span>
- <span class="Identifier">continue</span>-from <span class="Constant">2</span>:continuation <span class="Comment"># loop</span>
- <span class="Delimiter">}</span>
-]
-<span class="traceContains">+mem: storing 1 in location 1</span>
-<span class="traceContains">+mem: storing 2 in location 1</span>
-<span class="traceContains">+mem: storing 3 in location 1</span>
-<span class="traceAbsent">-mem: storing 4 in location 1</span>
-<span class="Comment"># ensure every iteration doesn't copy the stack over and over</span>
-$current-continuation: <span class="Constant">1</span>
-
-<span class="Delimiter">:(scenario continuation_inside_caller)</span>
-recipe main [
- <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
- <span class="Constant">2</span>:continuation<span class="Special"> <- </span>loop-body
- <span class="Delimiter">{</span>
- <span class="Constant">3</span>:boolean<span class="Special"> <- </span>greater-or-equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">3</span>
- <span class="Identifier">break</span>-if <span class="Constant">3</span>:boolean
- <span class="Identifier">continue</span>-from <span class="Constant">2</span>:continuation <span class="Comment"># loop</span>
- <span class="Delimiter">}</span>
-]
-
-recipe loop-body [
- <span class="Constant">4</span>:continuation<span class="Special"> <- </span>current-continuation
- <span class="Constant">1</span>:number<span class="Special"> <- </span>add <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">1</span>
-]
-<span class="traceContains">+mem: storing 1 in location 1</span>
-<span class="traceContains">+mem: storing 2 in location 1</span>
-<span class="traceContains">+mem: storing 3 in location 1</span>
-<span class="traceAbsent">-mem: storing 4 in location 1</span>
-
-<span class="SalientComment">//:: A variant of continuations is the 'delimited' continuation that can be called like any other recipe.</span>
-<span class="Comment">//:</span>
-<span class="Comment">//: In mu, this is constructed out of two primitives:</span>
-<span class="Comment">//:</span>
-<span class="Comment">//: * 'create-delimited-continuation' lays down a mark on the call</span>
-<span class="Comment">//: stack and calls the provided function (it is sometimes called 'prompt')</span>
-<span class="Comment">//: * 'reply-current-continuation' copies the top of the stack until the</span>
-<span class="Comment">//: mark, and returns it as the response of create-delimited-continuation</span>
-<span class="Comment">//: (which might be a distant ancestor on the call stack; intervening calls</span>
-<span class="Comment">//: don't return)</span>
-<span class="Comment">//:</span>
-<span class="Comment">//: The resulting slice of the stack can now be called just like a regular</span>
-<span class="Comment">//: function.</span>
-
-<span class="Delimiter">:(scenario delimited_continuation)</span>
-recipe main [
- <span class="Constant">1</span>:continuation<span class="Special"> <- </span>create-delimited-continuation f:recipe <span class="Constant">12</span> <span class="Comment"># 12 is an argument to f</span>
- <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">5</span>
- <span class="Delimiter">{</span>
- <span class="Constant">2</span>:number<span class="Special"> <- </span>call <span class="Constant">1</span>:continuation<span class="Delimiter">,</span> <span class="Constant">2</span>:number <span class="Comment"># 2 is an argument to g, the 'top' of the continuation</span>
- <span class="Constant">3</span>:boolean<span class="Special"> <- </span>greater-or-equal <span class="Constant">2</span>:number<span class="Delimiter">,</span> <span class="Constant">8</span>
- <span class="Identifier">break</span>-if <span class="Constant">3</span>:boolean
- loop
- <span class="Delimiter">}</span>
-]
-
-recipe f [
- <span class="Constant">11</span>:number<span class="Special"> <- </span>next-ingredient
- <span class="Constant">12</span>:number<span class="Special"> <- </span>g <span class="Constant">11</span>:number
- reply <span class="Constant">12</span>:number
-]
-
-recipe g [
- <span class="Constant">21</span>:number<span class="Special"> <- </span>next-ingredient
- rewind-ingredients
- reply-delimited-continuation
- <span class="Comment"># calls of the continuation start from here</span>
- <span class="Constant">22</span>:number<span class="Special"> <- </span>next-ingredient
- <span class="Constant">23</span>:number<span class="Special"> <- </span>add <span class="Constant">22</span>:number<span class="Delimiter">,</span> <span class="Constant">1</span>
- reply <span class="Constant">23</span>:number
-]
-<span class="Comment"># first call of 'g' executes the part before reply-delimited-continuation</span>
-<span class="traceContains">+mem: storing 12 in location 21</span>
-<span class="traceContains">+run: 2:number <- copy 5</span>
-<span class="traceContains">+mem: storing 5 in location 2</span>
-<span class="Comment"># calls of the continuation execute the part after reply-delimited-continuation</span>
-<span class="traceContains">+run: 2:number <- call 1:continuation, 2:number</span>
-<span class="traceContains">+mem: storing 5 in location 22</span>
-<span class="traceContains">+mem: storing 6 in location 2</span>
-<span class="traceContains">+run: 2:number <- call 1:continuation, 2:number</span>
-<span class="traceContains">+mem: storing 6 in location 22</span>
-<span class="traceContains">+mem: storing 7 in location 2</span>
-<span class="traceContains">+run: 2:number <- call 1:continuation, 2:number</span>
-<span class="traceContains">+mem: storing 7 in location 22</span>
-<span class="traceContains">+mem: storing 8 in location 2</span>
-<span class="Comment"># first call of 'g' does not execute the part after reply-delimited-continuation</span>
-<span class="traceAbsent">-mem: storing 12 in location 22</span>
-<span class="Comment"># calls of the continuation don't execute the part before reply-delimited-continuation</span>
-<span class="traceAbsent">-mem: storing 5 in location 21</span>
-<span class="traceAbsent">-mem: storing 6 in location 21</span>
-<span class="traceAbsent">-mem: storing 7 in location 21</span>
-<span class="Comment"># termination</span>
-<span class="traceAbsent">-mem: storing 9 in location 2</span>
-
-<span class="Comment">//: 'create-delimited-continuation' is like 'call' except it adds a 'reset' mark to</span>
-<span class="Comment">//: the call stack</span>
-
-<span class="Delimiter">:(before "End call Fields")</span>
-bool is_reset<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End call Constructor")</span>
-is_reset = <span class="Constant">false</span><span class="Delimiter">;</span>
-
-<span class="Comment">//: like call, but mark the current call as a 'reset' call before pushing the next one on it</span>
-
-<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
-CREATE_DELIMITED_CONTINUATION<span class="Delimiter">,</span>
-<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"create-delimited-continuation"</span>] = CREATE_DELIMITED_CONTINUATION<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
-case CREATE_DELIMITED_CONTINUATION: <span class="Delimiter">{</span>
- Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>is_reset = <span class="Constant">true</span><span class="Delimiter">;</span>
- Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>push_front<span class="Delimiter">(</span>call<span class="Delimiter">(</span>Recipe_ordinal[current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name]<span class="Delimiter">));</span>
- ingredients<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>begin<span class="Delimiter">());</span> <span class="Comment">// drop the callee</span>
- <span class="Identifier">goto</span> call_housekeeping<span class="Delimiter">;</span>
-<span class="Delimiter">}</span>
-
-<span class="Comment">//: save the slice of current call stack until the 'create-delimited-continuation'</span>
-<span class="Comment">//: call, and return it as the result.</span>
-<span class="Comment">//: todo: implement delimited continuations in mu's memory</span>
-<span class="Delimiter">:(before "End Globals")</span>
-map<long long int<span class="Delimiter">,</span> call_stack> Delimited_continuation<span class="Delimiter">;</span>
-long long int Next_delimited_continuation_id = <span class="Constant">0</span><span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Setup")</span>
-Delimited_continuation<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
-Next_delimited_continuation_id = <span class="Constant">0</span><span class="Delimiter">;</span>
-
-<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
-REPLY_DELIMITED_CONTINUATION<span class="Delimiter">,</span>
-<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"reply-delimited-continuation"</span>] = REPLY_DELIMITED_CONTINUATION<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
-case REPLY_DELIMITED_CONTINUATION: <span class="Delimiter">{</span>
- <span class="Comment">// first clear any existing ingredients, to isolate the creation of the</span>
- <span class="Comment">// continuation from its calls</span>
- Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
- Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>next_ingredient_to_process = <span class="Constant">0</span><span class="Delimiter">;</span>
- <span class="Comment">// copy the current call stack until the most recent 'reset' call</span>
- call_stack::iterator find_reset<span class="Delimiter">(</span>call_stack& c<span class="Delimiter">);</span> <span class="Comment">// manual prototype containing '::'</span>
- call_stack::iterator reset = find_reset<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>reset == Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": couldn't find a 'reset' call to jump out to</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- Delimited_continuation[Next_delimited_continuation_id] = call_stack<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> reset<span class="Delimiter">);</span>
- while <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>begin<span class="Delimiter">()</span> != reset<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- --Callstack_depth<span class="Delimiter">;</span>
- Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>pop_front<span class="Delimiter">();</span>
- <span class="Delimiter">}</span>
- <span class="Comment">// return it as the result of the 'reset' call</span>
- products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
- products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>Next_delimited_continuation_id<span class="Delimiter">);</span>
- ++Next_delimited_continuation_id<span class="Delimiter">;</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Comment">// continue to process rest of 'reset' call</span>
-<span class="Delimiter">}</span>
-
-<span class="Delimiter">:(code)</span>
-call_stack::iterator find_reset<span class="Delimiter">(</span>call_stack& c<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- for <span class="Delimiter">(</span>call_stack::iterator p = c<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != c<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span>
- if <span class="Delimiter">(</span>p<span class="Delimiter">-></span>is_reset<span class="Delimiter">)</span> <span class="Identifier">return</span> p<span class="Delimiter">;</span>
- <span class="Identifier">return</span> c<span class="Delimiter">.</span>end<span class="Delimiter">();</span>
-<span class="Delimiter">}</span>
-
-<span class="Comment">//: overload 'call' for continuations</span>
-<span class="Delimiter">:(after "Begin Call")</span>
- if <span class="Delimiter">(</span>!current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>empty<span class="Delimiter">()</span>
- && !current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>empty<span class="Delimiter">()</span>
- && current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">"continuation"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- <span class="Comment">// copy multiple calls on to current call stack</span>
- assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
- if <span class="Delimiter">(</span>Delimited_continuation<span class="Delimiter">.</span>find<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> == Delimited_continuation<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": no such delimited continuation "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Delimiter">}</span>
- const call_stack& new_calls = Delimited_continuation[ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span>]<span class="Delimiter">;</span>
- for <span class="Delimiter">(</span>call_stack::const_reverse_iterator p = new_calls<span class="Delimiter">.</span>rbegin<span class="Delimiter">();</span> p != new_calls<span class="Delimiter">.</span>rend<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span>
- Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>push_front<span class="Delimiter">(</span>*p<span class="Delimiter">);</span>
- ++current_step_index<span class="Delimiter">();</span> <span class="Comment">// skip past the reply-delimited-continuation</span>
- ingredients<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>begin<span class="Delimiter">());</span> <span class="Comment">// drop the callee</span>
- <span class="Identifier">goto</span> call_housekeeping<span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
-</pre>
-</body>
-</html>
-<!-- vim: set foldmethod=manual : -->
diff --git a/html/054dilated_reagent.cc.html b/html/054dilated_reagent.cc.html
new file mode 100644
index 00000000..84086d82
--- /dev/null
+++ b/html/054dilated_reagent.cc.html
@@ -0,0 +1,140 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>Mu - 054dilated_reagent.cc</title>
+<meta name="Generator" content="Vim/7.4">
+<meta name="plugin-version" content="vim7.4_v1">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
+<meta name="colorscheme" content="minimal">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
+body { font-family: monospace; color: #eeeeee; background-color: #080808; }
+* { font-size: 1.05em; }
+.traceContains { color: #008000; }
+.cSpecial { color: #008000; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
+.Special { color: #ff6060; }
+.Identifier { color: #804000; }
+.Constant { color: #00a0a0; }
+-->
+</style>
+
+<script type='text/javascript'>
+<!--
+
+-->
+</script>
+</head>
+<body>
+<pre id='vimCodeElement'>
+<span class="Comment">//: An alternative syntax for reagents that permits whitespace in properties,</span>
+<span class="Comment">//: grouped by brackets.</span>
+
+<span class="Delimiter">:(scenarios load)</span>
+<span class="Delimiter">:(scenario dilated_reagent)</span>
+recipe main [
+ <span class="Delimiter">{</span><span class="Constant">1</span>: number<span class="Delimiter">,</span> foo: bar<span class="Delimiter">}</span><span class="Special"> <- </span>copy <span class="Constant">34</span>
+]
+<span class="traceContains">+parse: product: {"1": "number", "foo": "bar"}</span>
+
+<span class="Comment">//: First augment next_word to group balanced brackets together.</span>
+
+<span class="Delimiter">:(before "End next_word Special-cases")</span>
+ if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'('</span><span class="Delimiter">)</span>
+ <span class="Identifier">return</span> slurp_balanced_bracket<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+ <span class="Comment">// treat curlies mostly like parens, but don't mess up labels</span>
+ if <span class="Delimiter">(</span>start_of_dilated_reagent<span class="Delimiter">(</span>in<span class="Delimiter">))</span>
+ <span class="Identifier">return</span> slurp_balanced_bracket<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+
+<span class="Delimiter">:(code)</span>
+<span class="Comment">// A curly is considered a label if it's the last thing on a line. Dilated</span>
+<span class="Comment">// reagents should remain all on one line.</span>
+<span class="Comment">//</span>
+<span class="Comment">// Side-effect: This might delete some whitespace after an initial '{'.</span>
+bool start_of_dilated_reagent<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="Constant">'{'</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+ in<span class="Delimiter">.</span>get<span class="Delimiter">();</span> <span class="Comment">// slurp '{'</span>
+ skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+ char next = in<span class="Delimiter">.</span>peek<span class="Delimiter">();</span>
+ in<span class="Delimiter">.</span>putback<span class="Delimiter">(</span><span class="Constant">'{'</span><span class="Delimiter">);</span>
+ <span class="Identifier">return</span> next != <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Comment">// Assume the first letter is an open bracket, and read everything until the</span>
+<span class="Comment">// matching close bracket.</span>
+<span class="Comment">// We balance {} () and []. And we skip one character after '\'.</span>
+string slurp_balanced_bracket<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ ostringstream result<span class="Delimiter">;</span>
+ char c<span class="Delimiter">;</span>
+ list<char> open_brackets<span class="Delimiter">;</span>
+ while <span class="Delimiter">(</span>in >> c<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>c == <span class="cSpecial">'\\'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ <span class="Comment">// always silently skip the next character</span>
+ result << c<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>!<span class="Delimiter">(</span>in >> c<span class="Delimiter">))</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
+ result << c<span class="Delimiter">;</span>
+ <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>c == <span class="Constant">'('</span><span class="Delimiter">)</span> open_brackets<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>c<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>c == <span class="Constant">')'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ assert<span class="Delimiter">(</span>open_brackets<span class="Delimiter">.</span>back<span class="Delimiter">()</span> == <span class="Constant">'('</span><span class="Delimiter">);</span>
+ open_brackets<span class="Delimiter">.</span>pop_back<span class="Delimiter">();</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>c == <span class="Constant">'['</span><span class="Delimiter">)</span> open_brackets<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>c<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>c == <span class="Constant">']'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ assert<span class="Delimiter">(</span>open_brackets<span class="Delimiter">.</span>back<span class="Delimiter">()</span> == <span class="Constant">'['</span><span class="Delimiter">);</span>
+ open_brackets<span class="Delimiter">.</span>pop_back<span class="Delimiter">();</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>c == <span class="Constant">'{'</span><span class="Delimiter">)</span> open_brackets<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>c<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>c == <span class="Constant">'}'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ assert<span class="Delimiter">(</span>open_brackets<span class="Delimiter">.</span>back<span class="Delimiter">()</span> == <span class="Constant">'{'</span><span class="Delimiter">);</span>
+ open_brackets<span class="Delimiter">.</span>pop_back<span class="Delimiter">();</span>
+ <span class="Delimiter">}</span>
+ result << c<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>open_brackets<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Identifier">return</span> result<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(after "Parsing reagent(string s)")</span>
+if <span class="Delimiter">(</span>s<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">'{'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ assert<span class="Delimiter">(</span>properties<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
+ istringstream in<span class="Delimiter">(</span>s<span class="Delimiter">);</span>
+ in >> std::noskipws<span class="Delimiter">;</span>
+ in<span class="Delimiter">.</span>get<span class="Delimiter">();</span> <span class="Comment">// skip '{'</span>
+ while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+ string key = slurp_key<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>key<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>key == <span class="Constant">"}"</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ string_tree* value = new string_tree<span class="Delimiter">(</span>next_word<span class="Delimiter">(</span>in<span class="Delimiter">));</span>
+ <span class="Comment">// End Parsing Reagent Property(value)</span>
+ properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> string_tree*><span class="Delimiter">(</span>key<span class="Delimiter">,</span> value<span class="Delimiter">));</span>
+ <span class="Delimiter">}</span>
+ <span class="Comment">// structures for the first row of properties</span>
+ name = properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>first<span class="Delimiter">;</span>
+ string type_name = properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">-></span>value<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type_name<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ <span class="Comment">// this type can't be an integer literal</span>
+ put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type_name<span class="Delimiter">,</span> Next_type_ordinal++<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+ type = new type_tree<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type_name<span class="Delimiter">));</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(code)</span>
+string slurp_key<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ string result = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+ while <span class="Delimiter">(</span>!result<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && *result<span class="Delimiter">.</span>rbegin<span class="Delimiter">()</span> == <span class="Constant">':'</span><span class="Delimiter">)</span>
+ strip_last<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
+ while <span class="Delimiter">(</span>isspace<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">())</span> || in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">':'</span><span class="Delimiter">)</span>
+ in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
+ <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/html/055parse_tree.cc.html b/html/055parse_tree.cc.html
new file mode 100644
index 00000000..7d9e158f
--- /dev/null
+++ b/html/055parse_tree.cc.html
@@ -0,0 +1,117 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>Mu - 055parse_tree.cc</title>
+<meta name="Generator" content="Vim/7.4">
+<meta name="plugin-version" content="vim7.4_v1">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
+<meta name="colorscheme" content="minimal">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
+body { font-family: monospace; color: #eeeeee; background-color: #080808; }
+* { font-size: 1.05em; }
+.traceContains { color: #008000; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
+.Special { color: #ff6060; }
+.Identifier { color: #804000; }
+.Constant { color: #00a0a0; }
+-->
+</style>
+
+<script type='text/javascript'>
+<!--
+
+-->
+</script>
+</head>
+<body>
+<pre id='vimCodeElement'>
+<span class="Comment">// So far instructions can only contain linear lists of properties. Now we add</span>
+<span class="Comment">// support for more complex trees of properties in dilated reagents. This will</span>
+<span class="Comment">// come in handy later for expressing complex types, like "a dictionary from</span>
+<span class="Comment">// (address to array of charaters) to (list of numbers)".</span>
+
+<span class="Delimiter">:(scenario dilated_reagent_with_nested_brackets)</span>
+recipe main [
+ <span class="Delimiter">{</span><span class="Constant">1</span>: number<span class="Delimiter">,</span> foo: <span class="Delimiter">(</span>bar <span class="Delimiter">(</span>baz quux<span class="Delimiter">))}</span><span class="Special"> <- </span>copy <span class="Constant">34</span>
+]
+<span class="traceContains">+parse: product: {"1": "number", "foo": <"bar" : <<"baz" : <"quux" : <>>> : <>>>}</span>
+
+<span class="Delimiter">:(before "End Parsing Reagent Property(value)")</span>
+value = parse_string_tree<span class="Delimiter">(</span>value<span class="Delimiter">);</span>
+
+<span class="Delimiter">:(code)</span>
+string_tree* parse_string_tree<span class="Delimiter">(</span>string_tree* s<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ assert<span class="Delimiter">(</span>!s<span class="Delimiter">-></span>left && !s<span class="Delimiter">-></span>right<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>s<span class="Delimiter">-></span>value<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> != <span class="Constant">'('</span><span class="Delimiter">)</span> <span class="Identifier">return</span> s<span class="Delimiter">;</span>
+ string_tree* result = parse_string_tree<span class="Delimiter">(</span>s<span class="Delimiter">-></span>value<span class="Delimiter">);</span>
+ delete s<span class="Delimiter">;</span>
+ <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+string_tree* parse_string_tree<span class="Delimiter">(</span>const string& s<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ istringstream in<span class="Delimiter">(</span>s<span class="Delimiter">);</span>
+ in >> std::noskipws<span class="Delimiter">;</span>
+ <span class="Identifier">return</span> parse_string_tree<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+string_tree* parse_string_tree<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">')'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
+ <span class="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="Constant">'('</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ string_tree* result = new string_tree<span class="Delimiter">(</span>next_word<span class="Delimiter">(</span>in<span class="Delimiter">));</span>
+ <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ in<span class="Delimiter">.</span>get<span class="Delimiter">();</span> <span class="Comment">// skip '('</span>
+ string_tree* result = <span class="Constant">NULL</span><span class="Delimiter">;</span>
+ string_tree** curr = &result<span class="Delimiter">;</span>
+ while <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="Constant">')'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ assert<span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">());</span>
+ *curr = new string_tree<span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">);</span>
+ skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+ skip_ignored_characters<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'('</span><span class="Delimiter">)</span>
+ <span class="Delimiter">(</span>*curr<span class="Delimiter">)-></span>left = parse_string_tree<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+ else
+ <span class="Delimiter">(</span>*curr<span class="Delimiter">)-></span>value = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+ curr = &<span class="Delimiter">(</span>*curr<span class="Delimiter">)-></span>right<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ in<span class="Delimiter">.</span>get<span class="Delimiter">();</span> <span class="Comment">// skip ')'</span>
+ <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario dilated_reagent_with_type_tree)</span>
+<span class="Special">% Hide_errors = true; // 'map' isn't defined yet</span>
+recipe main [
+ <span class="Delimiter">{</span><span class="Constant">1</span>: <span class="Delimiter">(</span>foo <span class="Delimiter">(</span>address array character<span class="Delimiter">)</span> <span class="Delimiter">(</span>bar number<span class="Delimiter">))}</span><span class="Special"> <- </span>copy <span class="Constant">34</span>
+]
+<span class="Comment"># just to avoid errors</span>
+container foo [
+]
+container bar [
+]
+<span class="traceContains">+parse: product: {"1": <"foo" : <<"address" : <"array" : <"character" : <>>>> : <<"bar" : <"number" : <>>> : <>>>>}</span>
+
+<span class="Comment">//: an exception is 'new', which takes a type tree as its ingredient *value*</span>
+
+<span class="Delimiter">:(scenario dilated_reagent_with_new)</span>
+recipe main [
+ x:address:number<span class="Special"> <- </span>new <span class="Delimiter">{(</span>foo bar<span class="Delimiter">)</span>: type<span class="Delimiter">}</span>
+]
+<span class="Comment"># type isn't defined so size is meaningless, but at least we parse the type correctly</span>
+<span class="traceContains">+new: size of <"foo" : <"bar" : <>>> is 1</span>
+
+<span class="Delimiter">:(before "End Post-processing(type_name) When Converting 'new'")</span>
+type_name = parse_string_tree<span class="Delimiter">(</span>type_name<span class="Delimiter">);</span>
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/html/056recipe_header.cc.html b/html/056recipe_header.cc.html
new file mode 100644
index 00000000..5000a703
--- /dev/null
+++ b/html/056recipe_header.cc.html
@@ -0,0 +1,395 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>Mu - 056recipe_header.cc</title>
+<meta name="Generator" content="Vim/7.4">
+<meta name="plugin-version" content="vim7.4_v1">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
+<meta name="colorscheme" content="minimal">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
+body { font-family: monospace; color: #eeeeee; background-color: #080808; }
+* { font-size: 1.05em; }
+.traceContains { color: #008000; }
+.SalientComment { color: #00ffff; }
+.cSpecial { color: #008000; }
+.traceAbsent { color: #c00000; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
+.Special { color: #ff6060; }
+.Identifier { color: #804000; }
+.Constant { color: #00a0a0; }
+.CommentedCode { color: #6c6c6c; }
+-->
+</style>
+
+<script type='text/javascript'>
+<!--
+
+-->
+</script>
+</head>
+<body>
+<pre id='vimCodeElement'>
+<span class="Comment">//: Advanced notation for the common/easy case where a recipe takes some fixed</span>
+<span class="Comment">//: number of ingredients and yields some fixed number of products.</span>
+
+<span class="Delimiter">:(scenario recipe_with_header)</span>
+recipe main [
+ <span class="Constant">1</span>:number/<span class="Special">raw <- </span>add2 <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">5</span>
+]
+recipe add2 x:number<span class="Delimiter">,</span> y:number <span class="Delimiter">-></span> z:number [
+ local-scope
+ load-ingredients
+ z:number<span class="Special"> <- </span>add x<span class="Delimiter">,</span> y
+ reply z
+]
+<span class="traceContains">+mem: storing 8 in location 1</span>
+
+<span class="Comment">//: When loading recipes save any header.</span>
+
+<span class="Delimiter">:(before "End recipe Fields")</span>
+bool has_header<span class="Delimiter">;</span>
+vector<reagent> ingredients<span class="Delimiter">;</span>
+vector<reagent> products<span class="Delimiter">;</span>
+<span class="Delimiter">:(before "End recipe Constructor")</span>
+has_header = <span class="Constant">false</span><span class="Delimiter">;</span>
+
+<span class="Delimiter">:(before "End recipe Refinements")</span>
+skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">"recipe has a header; parsing"</span> << end<span class="Delimiter">();</span>
+ load_recipe_header<span class="Delimiter">(</span>in<span class="Delimiter">,</span> result<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(code)</span>
+void load_recipe_header<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> recipe& result<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ result<span class="Delimiter">.</span>has_header = <span class="Constant">true</span><span class="Delimiter">;</span>
+ while <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ string s = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>s == <span class="Constant">"->"</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
+ result<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span>s<span class="Delimiter">));</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">"header ingredient: "</span> << result<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>back<span class="Delimiter">().</span>original_string << end<span class="Delimiter">();</span>
+ skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+ while <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ string s = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+ result<span class="Delimiter">.</span>products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span>s<span class="Delimiter">));</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">"header product: "</span> << result<span class="Delimiter">.</span>products<span class="Delimiter">.</span>back<span class="Delimiter">().</span>original_string << end<span class="Delimiter">();</span>
+ skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+ <span class="Comment">// End Load Recipe Header(result)</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario recipe_handles_stray_comma)</span>
+recipe main [
+ <span class="Constant">1</span>:number/<span class="Special">raw <- </span>add2 <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">5</span>
+]
+recipe add2 x:number<span class="Delimiter">,</span> y:number <span class="Delimiter">-></span> z:number<span class="Delimiter">,</span> [
+ local-scope
+ load-ingredients
+ z:number<span class="Special"> <- </span>add x<span class="Delimiter">,</span> y
+ reply z
+]
+<span class="traceContains">+mem: storing 8 in location 1</span>
+
+<span class="Delimiter">:(scenario recipe_handles_stray_comma_2)</span>
+recipe main [
+ foo
+]
+recipe foo<span class="Delimiter">,</span> [
+ <span class="Constant">1</span>:number/<span class="Special">raw <- </span>add <span class="Constant">2</span><span class="Delimiter">,</span> <span class="Constant">2</span>
+]
+recipe bar [
+ <span class="Constant">1</span>:number/<span class="Special">raw <- </span>add <span class="Constant">2</span><span class="Delimiter">,</span> <span class="Constant">3</span>
+]
+<span class="traceContains">+mem: storing 4 in location 1</span>
+
+<span class="Delimiter">:(after "Begin debug_string(recipe x)")</span>
+out << <span class="Constant">"ingredients:</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span>
+for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>x<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
+ out << <span class="Constant">" "</span> << debug_string<span class="Delimiter">(</span>x<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
+out << <span class="Constant">"products:</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span>
+for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>x<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
+ out << <span class="Constant">" "</span> << debug_string<span class="Delimiter">(</span>x<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
+
+<span class="Comment">//: If a recipe never mentions any ingredients or products, assume it has a header.</span>
+
+<span class="Delimiter">:(scenario recipe_without_ingredients_or_products_has_header)</span>
+recipe test [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
+]
+<span class="traceContains">+parse: recipe test has a header</span>
+
+<span class="Delimiter">:(before "End recipe Body(result)")</span>
+if <span class="Delimiter">(</span>!result<span class="Delimiter">.</span>has_header<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ result<span class="Delimiter">.</span>has_header = <span class="Constant">true</span><span class="Delimiter">;</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>result<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ const instruction& inst = result<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> && !inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span>
+ || inst<span class="Delimiter">.</span>name == <span class="Constant">"next-ingredient"</span>
+ || inst<span class="Delimiter">.</span>name == <span class="Constant">"ingredient"</span>
+ || inst<span class="Delimiter">.</span>name == <span class="Constant">"rewind-ingredients"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ result<span class="Delimiter">.</span>has_header = <span class="Constant">false</span><span class="Delimiter">;</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+if <span class="Delimiter">(</span>result<span class="Delimiter">.</span>has_header<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">"recipe "</span> << result<span class="Delimiter">.</span>name << <span class="Constant">" has a header"</span> << end<span class="Delimiter">();</span>
+<span class="Delimiter">}</span>
+
+<span class="Comment">//: Rewrite 'load-ingredients' to instructions to create all reagents in the header.</span>
+
+<span class="Delimiter">:(before "End Rewrite Instruction(curr, recipe result)")</span>
+if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"load-ingredients"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ curr<span class="Delimiter">.</span>clear<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>result<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ curr<span class="Delimiter">.</span>operation = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"next-ingredient"</span><span class="Delimiter">);</span>
+ curr<span class="Delimiter">.</span>name = <span class="Constant">"next-ingredient"</span><span class="Delimiter">;</span>
+ curr<span class="Delimiter">.</span>products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>result<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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>
+ curr<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+<span class="SalientComment">//:: Check types going in and out of all recipes with headers.</span>
+
+<span class="Delimiter">:(scenarios transform)</span>
+<span class="Delimiter">:(scenario recipe_headers_are_checked)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe add2 x:number<span class="Delimiter">,</span> y:number <span class="Delimiter">-></span> z:number [
+ local-scope
+ load-ingredients
+ z:address:number<span class="Special"> <- </span>copy <span class="Constant">0</span>/<span class="Special">raw</span>
+ reply z
+]
+<span class="traceContains">+error: add2: replied with the wrong type at 'reply z'</span>
+
+<span class="Delimiter">:(after "Transform.push_back(check_types_by_name)")</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_reply_instructions_against_header<span class="Delimiter">);</span> <span class="Comment">// idempotent</span>
+
+<span class="Delimiter">:(code)</span>
+void check_reply_instructions_against_header<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ const recipe& caller_recipe = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"--- checking reply instructions against header for "</span> << caller_recipe<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span>
+<span class="CommentedCode">//? cerr << "--- checking reply instructions against header for " << caller_recipe.name << '\n';</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ const instruction& inst = caller_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name != <span class="Constant">"reply"</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>products<span class="Delimiter">)</span> != SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">))</span>
+ raise_error << maybe<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"tried to reply the wrong number of products in '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ 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>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario recipe_headers_check_for_duplicate_names)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe add2 x:number<span class="Delimiter">,</span> x:number <span class="Delimiter">-></span> z:number [
+ local-scope
+ load-ingredients
+ reply z
+]
+<span class="traceContains">+error: add2: x can't repeat in the ingredients</span>
+
+<span class="Delimiter">:(before "End recipe Fields")</span>
+map<string<span class="Delimiter">,</span> int> ingredient_index<span class="Delimiter">;</span>
+
+<span class="Delimiter">:(after "Transform.push_back(insert_fragments)")</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_and_update_header_reagents<span class="Delimiter">);</span> <span class="Comment">// idempotent</span>
+
+<span class="Delimiter">:(code)</span>
+void check_and_update_header_reagents<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ recipe& caller_recipe = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"--- checking reply instructions against header for "</span> << caller_recipe<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span>
+ 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>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>ingredient_index<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">))</span>
+ raise_error << maybe<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << caller_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name << <span class="Constant">" can't repeat in the ingredients</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ put<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>ingredient_index<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">,</span> i<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+<span class="Comment">//: Deduce types from the header if possible.</span>
+
+<span class="Delimiter">:(scenarios run)</span>
+<span class="Delimiter">:(scenario deduce_instruction_types_from_recipe_header)</span>
+recipe main [
+ <span class="Constant">1</span>:number/<span class="Special">raw <- </span>add2 <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">5</span>
+]
+recipe add2 x:number<span class="Delimiter">,</span> y:number <span class="Delimiter">-></span> z:number [
+ local-scope
+ load-ingredients
+ z<span class="Special"> <- </span>add x<span class="Delimiter">,</span> y <span class="Comment"># no type for z</span>
+ reply z
+]
+<span class="traceContains">+mem: storing 8 in location 1</span>
+
+<span class="Delimiter">:(before "Transform.push_back(check_reply_instructions_against_header)")</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>deduce_types_from_header<span class="Delimiter">);</span> <span class="Comment">// idempotent</span>
+
+<span class="Delimiter">:(code)</span>
+void deduce_types_from_header<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ recipe& caller_recipe = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"--- deduce types from header for "</span> << caller_recipe<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span>
+<span class="CommentedCode">//? cerr << "--- deduce types from header for " << caller_recipe.name << '\n';</span>
+ map<string<span class="Delimiter">,</span> const type_tree*> header_type<span class="Delimiter">;</span>
+ map<string<span class="Delimiter">,</span> const string_tree*> header_type_name<span class="Delimiter">;</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ put<span class="Delimiter">(</span>header_type<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">);</span>
+ put<span class="Delimiter">(</span>header_type_name<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"type of "</span> << caller_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name << <span class="Constant">" is "</span> << debug_string<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
+ <span class="Delimiter">}</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ put<span class="Delimiter">(</span>header_type<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>name<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>type<span class="Delimiter">);</span>
+ put<span class="Delimiter">(</span>header_type_name<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>name<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>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">);</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"type of "</span> << caller_recipe<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name << <span class="Constant">" is "</span> << debug_string<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>type<span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
+ <span class="Delimiter">}</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ instruction& inst = caller_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>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">"instruction: "</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << end<span class="Delimiter">();</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>header_type<span class="Delimiter">.</span>find<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">)</span> == header_type<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+ raise << maybe<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"unknown variable "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name << <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">continue</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">)</span>
+ inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type = new type_tree<span class="Delimiter">(</span>*get<span class="Delimiter">(</span>header_type<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">));</span>
+ if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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>
+ inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second = new string_tree<span class="Delimiter">(</span>*get<span class="Delimiter">(</span>header_type_name<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">));</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"type of "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name << <span class="Constant">" is "</span> << debug_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
+ <span class="Delimiter">}</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">" product: "</span> << debug_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>header_type<span class="Delimiter">.</span>find<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">)</span> == header_type<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+ raise << maybe<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"unknown variable "</span> << inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name << <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">continue</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">)</span>
+ inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type = new type_tree<span class="Delimiter">(</span>*get<span class="Delimiter">(</span>header_type<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">));</span>
+ if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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>
+ inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second = new string_tree<span class="Delimiter">(</span>*get<span class="Delimiter">(</span>header_type_name<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">));</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"type of "</span> << inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name << <span class="Constant">" is "</span> << debug_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+<span class="Comment">//: One final convenience: no need to say what to return if the information is</span>
+<span class="Comment">//: in the header.</span>
+
+<span class="Delimiter">:(scenario reply_based_on_header)</span>
+recipe main [
+ <span class="Constant">1</span>:number/<span class="Special">raw <- </span>add2 <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">5</span>
+]
+recipe add2 x:number<span class="Delimiter">,</span> y:number <span class="Delimiter">-></span> z:number [
+ local-scope
+ load-ingredients
+ z<span class="Special"> <- </span>add x<span class="Delimiter">,</span> y
+ reply
+]
+<span class="traceContains">+mem: storing 8 in location 1</span>
+
+<span class="Delimiter">:(after "Transform.push_back(check_and_update_header_reagents)")</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>fill_in_reply_ingredients<span class="Delimiter">);</span> <span class="Comment">// idempotent</span>
+
+<span class="Delimiter">:(code)</span>
+void fill_in_reply_ingredients<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>
+ if <span class="Delimiter">(</span>!caller_recipe<span class="Delimiter">.</span>has_header<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">"--- fill in reply ingredients from header for recipe "</span> << caller_recipe<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ instruction& inst = caller_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">"reply"</span> && inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span>
+ add_header_products<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+ <span class="Comment">// fall through reply</span>
+ if <span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">).</span>name != <span class="Constant">"reply"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ instruction inst<span class="Delimiter">;</span>
+ inst<span class="Delimiter">.</span>name = <span class="Constant">"reply"</span><span class="Delimiter">;</span>
+ add_header_products<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">);</span>
+ caller_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>inst<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+void add_header_products<span class="Delimiter">(</span>instruction& inst<span class="Delimiter">,</span> const recipe& caller_recipe<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ assert<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">"reply"</span><span class="Delimiter">);</span>
+ <span class="Comment">// collect any products with the same names as ingredients</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ <span class="Comment">// if the ingredient is missing, add it from the header</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> == i<span class="Delimiter">)</span>
+ inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<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>
+ <span class="Comment">// if it's missing /same_as_ingredient, try to fill it in</span>
+ if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>ingredient_index<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>name<span class="Delimiter">)</span> && !has_property<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> <span class="Constant">"same_as_ingredient"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ ostringstream same_as_ingredient<span class="Delimiter">;</span>
+ same_as_ingredient << get<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>ingredient_index<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>name<span class="Delimiter">);</span>
+ inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>properties<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<string<span class="Delimiter">,</span> string_tree*><span class="Delimiter">(</span><span class="Constant">"same-as-ingredient"</span><span class="Delimiter">,</span> new string_tree<span class="Delimiter">(</span>same_as_ingredient<span class="Delimiter">.</span>str<span class="Delimiter">())));</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario explicit_reply_ignores_header)</span>
+recipe main [
+ <span class="Constant">1</span>:number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">2</span>:number/<span class="Special">raw <- </span>add2 <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">5</span>
+]
+recipe add2 a:number<span class="Delimiter">,</span> b:number <span class="Delimiter">-></span> y:number<span class="Delimiter">,</span> z:number [
+ local-scope
+ load-ingredients
+ y<span class="Special"> <- </span>add a<span class="Delimiter">,</span> b
+ z<span class="Special"> <- </span>subtract a<span class="Delimiter">,</span> b
+ reply a<span class="Delimiter">,</span> z
+]
+<span class="traceContains">+mem: storing 3 in location 1</span>
+<span class="traceContains">+mem: storing -2 in location 2</span>
+
+<span class="Delimiter">:(scenario reply_on_fallthrough_based_on_header)</span>
+recipe main [
+ <span class="Constant">1</span>:number/<span class="Special">raw <- </span>add2 <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">5</span>
+]
+recipe add2 x:number<span class="Delimiter">,</span> y:number <span class="Delimiter">-></span> z:number [
+ local-scope
+ load-ingredients
+ z<span class="Special"> <- </span>add x<span class="Delimiter">,</span> y
+]
+<span class="traceContains">+transform: instruction: reply z:number</span>
+<span class="traceContains">+mem: storing 8 in location 1</span>
+
+<span class="Delimiter">:(scenario reply_on_fallthrough_already_exists)</span>
+recipe main [
+ <span class="Constant">1</span>:number/<span class="Special">raw <- </span>add2 <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">5</span>
+]
+recipe add2 x:number<span class="Delimiter">,</span> y:number <span class="Delimiter">-></span> z:number [
+ local-scope
+ load-ingredients
+ z<span class="Special"> <- </span>add x<span class="Delimiter">,</span> y <span class="Comment"># no type for z</span>
+ reply z
+]
+<span class="traceContains">+transform: instruction: reply z</span>
+<span class="traceAbsent">-transform: instruction: reply z:number</span>
+<span class="traceContains">+mem: storing 8 in location 1</span>
+
+<span class="Delimiter">:(scenario recipe_headers_perform_same_ingredient_check)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
+ <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
+ <span class="Constant">3</span>:number<span class="Special"> <- </span>add2 <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number
+]
+recipe add2 x:number<span class="Delimiter">,</span> y:number <span class="Delimiter">-></span> x:number [
+ local-scope
+ load-ingredients
+]
+<span class="traceContains">+error: main: '3:number <- add2 1:number, 2:number' should write to 1:number rather than 3:number</span>
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/html/057static_dispatch.cc.html b/html/057static_dispatch.cc.html
new file mode 100644
index 00000000..ec362d4a
--- /dev/null
+++ b/html/057static_dispatch.cc.html
@@ -0,0 +1,223 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>Mu - 057static_dispatch.cc</title>
+<meta name="Generator" content="Vim/7.4">
+<meta name="plugin-version" content="vim7.4_v1">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
+<meta name="colorscheme" content="minimal">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
+body { font-family: monospace; color: #eeeeee; background-color: #080808; }
+* { font-size: 1.05em; }
+.traceContains { color: #008000; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
+.Special { color: #ff6060; }
+.Identifier { color: #804000; }
+.Constant { color: #00a0a0; }
+-->
+</style>
+
+<script type='text/javascript'>
+<!--
+
+-->
+</script>
+</head>
+<body>
+<pre id='vimCodeElement'>
+<span class="Comment">//: Transform to maintain multiple variants of a recipe depending on the</span>
+<span class="Comment">//: number and types of the ingredients and products. Allows us to use nice</span>
+<span class="Comment">//: names like 'print' or 'length' in many mutually extensible ways.</span>
+
+<span class="Delimiter">:(scenario static_dispatch)</span>
+recipe main [
+ <span class="Constant">7</span>:number/<span class="Special">raw <- </span>test <span class="Constant">3</span>
+]
+recipe test a:number <span class="Delimiter">-></span> z:number [
+ z<span class="Special"> <- </span>copy <span class="Constant">1</span>
+]
+recipe test a:number<span class="Delimiter">,</span> b:number <span class="Delimiter">-></span> z:number [
+ z<span class="Special"> <- </span>copy <span class="Constant">2</span>
+]
+<span class="traceContains">+mem: storing 1 in location 7</span>
+
+<span class="Comment">//: When loading recipes, accumulate variants if headers don't collide, and</span>
+<span class="Comment">//: raise a warning if headers collide.</span>
+
+<span class="Delimiter">:(before "End Globals")</span>
+map<string<span class="Delimiter">,</span> vector<recipe_ordinal> > Recipe_variants<span class="Delimiter">;</span>
+<span class="Delimiter">:(before "End One-time Setup")</span>
+put<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> <span class="Constant">"main"</span><span class="Delimiter">,</span> vector<recipe_ordinal><span class="Delimiter">());</span> <span class="Comment">// since we manually added main to Recipe_ordinal</span>
+<span class="Delimiter">:(before "End Setup")</span>
+for <span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> vector<recipe_ordinal> >::iterator p = Recipe_variants<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Recipe_variants<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>p<span class="Delimiter">-></span>second<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>p<span class="Delimiter">-></span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> >= Reserved_for_tests<span class="Delimiter">)</span>
+ p<span class="Delimiter">-></span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> = -<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Comment">// just leave a ghost</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(before "End Load Recipe Header(result)")</span>
+if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ const recipe_ordinal r = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
+ if <span class="Delimiter">((</span>!contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">)</span> || get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>has_header<span class="Delimiter">)</span>
+ && !header_already_exists<span class="Delimiter">(</span>result<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ string new_name = next_unused_recipe_name<span class="Delimiter">(</span>result<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
+ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> new_name<span class="Delimiter">,</span> Next_recipe_ordinal++<span class="Delimiter">);</span>
+ get<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> new_name<span class="Delimiter">));</span>
+ result<span class="Delimiter">.</span>name = new_name<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+else <span class="Delimiter">{</span>
+ <span class="Comment">// save first variant</span>
+ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">,</span> Next_recipe_ordinal++<span class="Delimiter">);</span>
+ get_or_insert<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">));</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(code)</span>
+bool header_already_exists<span class="Delimiter">(</span>const recipe& rr<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ const vector<recipe_ordinal>& variants = get<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> rr<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
+ 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>Recipe<span class="Delimiter">.</span>find<span class="Delimiter">(</span>variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> != Recipe<span class="Delimiter">.</span>end<span class="Delimiter">()</span>
+ && all_reagents_match<span class="Delimiter">(</span>rr<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))))</span> <span class="Delimiter">{</span>
+ <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>
+
+bool all_reagents_match<span class="Delimiter">(</span>const recipe& r1<span class="Delimiter">,</span> const recipe& r2<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>r1<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != SIZE<span class="Delimiter">(</span>r2<span class="Delimiter">.</span>ingredients<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>r1<span class="Delimiter">.</span>products<span class="Delimiter">)</span> != SIZE<span class="Delimiter">(</span>r2<span class="Delimiter">.</span>products<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>r1<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!exact_match<span class="Delimiter">(</span>r1<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">,</span> r2<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">))</span>
+ <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>r1<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!exact_match<span class="Delimiter">(</span>r1<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">,</span> r2<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">))</span>
+ <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+bool exact_match<span class="Delimiter">(</span>type_tree* a<span class="Delimiter">,</span> type_tree* b<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>a == b<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+ <span class="Identifier">return</span> a<span class="Delimiter">-></span>value == b<span class="Delimiter">-></span>value
+ && exact_match<span class="Delimiter">(</span>a<span class="Delimiter">-></span>left<span class="Delimiter">,</span> b<span class="Delimiter">-></span>left<span class="Delimiter">)</span>
+ && exact_match<span class="Delimiter">(</span>a<span class="Delimiter">-></span>right<span class="Delimiter">,</span> b<span class="Delimiter">-></span>right<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+string next_unused_recipe_name<span class="Delimiter">(</span>const string& recipe_name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">2</span><span class="Delimiter">;</span> <span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ ostringstream out<span class="Delimiter">;</span>
+ out << recipe_name << <span class="Constant">'_'</span> << i<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">.</span>find<span class="Delimiter">(</span>out<span class="Delimiter">.</span>str<span class="Delimiter">())</span> == Recipe_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
+ <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+<span class="Comment">//: Once all the recipes are loaded, transform their bodies to replace each</span>
+<span class="Comment">//: call with the most suitable variant.</span>
+
+<span class="Delimiter">:(scenario static_dispatch_picks_most_similar_variant)</span>
+recipe main [
+ <span class="Constant">7</span>:number/<span class="Special">raw <- </span>test <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">4</span><span class="Delimiter">,</span> <span class="Constant">5</span>
+]
+recipe test a:number <span class="Delimiter">-></span> z:number [
+ z<span class="Special"> <- </span>copy <span class="Constant">1</span>
+]
+recipe test a:number<span class="Delimiter">,</span> b:number <span class="Delimiter">-></span> z:number [
+ z<span class="Special"> <- </span>copy <span class="Constant">2</span>
+]
+<span class="traceContains">+mem: storing 2 in location 7</span>
+
+<span class="Comment">//: after insert_fragments (tangle) and before computing operation ids</span>
+<span class="Comment">//: after filling in all missing types (because we'll be introducing 'blank' types in this transform in a later layer, for shape-shifting recipes)</span>
+<span class="Delimiter">:(after "Transform.push_back(deduce_types_from_header)")</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>resolve_ambiguous_calls<span class="Delimiter">);</span> <span class="Comment">// idempotent</span>
+
+<span class="Delimiter">:(code)</span>
+void resolve_ambiguous_calls<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ recipe& caller_recipe = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!caller_recipe<span class="Delimiter">.</span>has_header<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">"--- resolve ambiguous calls for recipe "</span> << caller_recipe<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span>
+ for <span class="Delimiter">(</span>long long int index = <span class="Constant">0</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ instruction& inst = caller_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>is_label<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ assert<span class="Delimiter">(</span>!get<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">).</span>empty<span class="Delimiter">());</span>
+ replace_best_variant<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+void replace_best_variant<span class="Delimiter">(</span>instruction& inst<span class="Delimiter">,</span> const recipe& caller_recipe<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"instruction "</span> << inst<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span>
+ vector<recipe_ordinal>& variants = get<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
+ 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>
+ 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>
+ long long int current_score = variant_score<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"checking variant "</span> << i << <span class="Constant">": "</span> << current_score << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>current_score > best_score<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ inst<span class="Delimiter">.</span>name = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)).</span>name<span class="Delimiter">;</span>
+ best_score = current_score<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ <span class="Comment">// End Instruction Dispatch(inst, best_score)</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>
+ if <span class="Delimiter">(</span>variant == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Comment">// ghost from a previous test</span>
+ const vector<reagent>& header_ingredients = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> < SIZE<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"too few ingredients"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"mismatch: ingredient "</span> << i << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">)</span> > SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"too few products"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ const vector<reagent>& header_products = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">;</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>header_products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"mismatch: product "</span> << i << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ <span class="Comment">// the greater the number of unused ingredients, the lower the score</span>
+ <span class="Identifier">return</span> <span class="Constant">100</span> - <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">)</span>-SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">))</span>
+ - <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span>-SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">));</span> <span class="Comment">// ok to go negative</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario static_dispatch_disabled_on_headerless_definition)</span>
+<span class="Special">% Hide_warnings = true;</span>
+recipe test a:number <span class="Delimiter">-></span> z:number [
+ z<span class="Special"> <- </span>copy <span class="Constant">1</span>
+]
+recipe test [
+ reply <span class="Constant">34</span>
+]
+<span class="traceContains">+warn: redefining recipe test</span>
+
+<span class="Delimiter">:(scenario static_dispatch_disabled_on_headerless_definition_2)</span>
+<span class="Special">% Hide_warnings = true;</span>
+recipe test [
+ reply <span class="Constant">34</span>
+]
+recipe test a:number <span class="Delimiter">-></span> z:number [
+ z<span class="Special"> <- </span>copy <span class="Constant">1</span>
+]
+<span class="traceContains">+warn: redefining recipe test</span>
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/html/058shape_shifting_container.cc.html b/html/058shape_shifting_container.cc.html
new file mode 100644
index 00000000..4425953a
--- /dev/null
+++ b/html/058shape_shifting_container.cc.html
@@ -0,0 +1,294 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>Mu - 058shape_shifting_container.cc</title>
+<meta name="Generator" content="Vim/7.4">
+<meta name="plugin-version" content="vim7.4_v1">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
+<meta name="colorscheme" content="minimal">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
+body { font-family: monospace; color: #eeeeee; background-color: #080808; }
+* { font-size: 1.05em; }
+.traceContains { color: #008000; }
+.Special { color: #ff6060; }
+.cSpecial { color: #008000; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
+.SalientComment { color: #00ffff; }
+.Identifier { color: #804000; }
+-->
+</style>
+
+<script type='text/javascript'>
+<!--
+
+-->
+</script>
+</head>
+<body>
+<pre id='vimCodeElement'>
+<span class="SalientComment">//:: Container definitions can contain type parameters.</span>
+<span class="Comment">//:</span>
+<span class="Comment">//: Extremely hacky initial implementation:</span>
+<span class="Comment">//:</span>
+<span class="Comment">//: a) We still don't support the full complexity of type trees inside</span>
+<span class="Comment">//: container definitions. So for example you can't have a container element</span>
+<span class="Comment">//: with this type:</span>
+<span class="Comment">//: (map (array address character) (list number))</span>
+<span class="Comment">//:</span>
+<span class="Comment">//: b) We also can't include type parameters anywhere except at the top of the</span>
+<span class="Comment">//: type of a container element.</span>
+
+<span class="Delimiter">:(scenario size_of_shape_shifting_container)</span>
+container foo:_t [
+ x:_t
+ y:number
+]
+recipe main [
+ <span class="Constant">1</span>:foo:number<span class="Special"> <- </span>merge <span class="Constant">12</span><span class="Delimiter">,</span> <span class="Constant">13</span>
+ <span class="Constant">3</span>:foo:point<span class="Special"> <- </span>merge <span class="Constant">14</span><span class="Delimiter">,</span> <span class="Constant">15</span><span class="Delimiter">,</span> <span class="Constant">16</span>
+]
+<span class="traceContains">+mem: storing 12 in location 1</span>
+<span class="traceContains">+mem: storing 13 in location 2</span>
+<span class="traceContains">+mem: storing 14 in location 3</span>
+<span class="traceContains">+mem: storing 15 in location 4</span>
+<span class="traceContains">+mem: storing 16 in location 5</span>
+
+<span class="Delimiter">:(before "End Globals")</span>
+<span class="Comment">// We'll use large type ordinals to mean "the following type of the variable".</span>
+const int START_TYPE_INGREDIENTS = <span class="Constant">2000</span><span class="Delimiter">;</span>
+<span class="Delimiter">:(before "End Test Run Initialization")</span>
+assert<span class="Delimiter">(</span>Next_type_ordinal < START_TYPE_INGREDIENTS<span class="Delimiter">);</span>
+
+<span class="Delimiter">:(before "End type_info Fields")</span>
+map<string<span class="Delimiter">,</span> type_ordinal> type_ingredient_names<span class="Delimiter">;</span>
+
+<span class="Comment">//: Suppress unknown type checks in shape-shifting containers.</span>
+
+<span class="Delimiter">:(before "Check Container Field Types(info)")</span>
+if <span class="Delimiter">(</span>!info<span class="Delimiter">.</span>type_ingredient_names<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+
+<span class="Delimiter">:(before "End container Name Refinements")</span>
+if <span class="Delimiter">(</span>name<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">':'</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">"container has type ingredients; parsing"</span> << end<span class="Delimiter">();</span>
+ read_type_ingredients<span class="Delimiter">(</span>name<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(code)</span>
+void read_type_ingredients<span class="Delimiter">(</span>string& name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ string save_name = name<span class="Delimiter">;</span>
+ istringstream in<span class="Delimiter">(</span>save_name<span class="Delimiter">);</span>
+ name = slurp_until<span class="Delimiter">(</span>in<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">)</span> || get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">)</span>
+ put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">,</span> Next_type_ordinal++<span class="Delimiter">);</span>
+ type_info& info = get_or_insert<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">));</span>
+ long long int next_type_ordinal = START_TYPE_INGREDIENTS<span class="Delimiter">;</span>
+ while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+ string curr = slurp_until<span class="Delimiter">(</span>in<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>info<span class="Delimiter">.</span>type_ingredient_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>curr<span class="Delimiter">)</span> != info<span class="Delimiter">.</span>type_ingredient_names<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+ raise_error << <span class="Constant">"can't repeat type ingredient names in a single container definition</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ put<span class="Delimiter">(</span>info<span class="Delimiter">.</span>type_ingredient_names<span class="Delimiter">,</span> curr<span class="Delimiter">,</span> next_type_ordinal++<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(before "End insert_container Special Uses(type_name)")</span>
+<span class="Comment">// check for use of type ingredients</span>
+if <span class="Delimiter">(</span>type_name<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">'_'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ *curr_type = new type_tree<span class="Delimiter">(</span>get<span class="Delimiter">(</span>info<span class="Delimiter">.</span>type_ingredient_names<span class="Delimiter">,</span> type_name<span class="Delimiter">));</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"parse"</span><span class="Delimiter">)</span> << <span class="Constant">" type: "</span> << get<span class="Delimiter">(</span>info<span class="Delimiter">.</span>type_ingredient_names<span class="Delimiter">,</span> type_name<span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">continue</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(before "End Container Type Checks")</span>
+if <span class="Delimiter">(</span>type<span class="Delimiter">-></span>value >= START_TYPE_INGREDIENTS
+ && <span class="Delimiter">(</span>type<span class="Delimiter">-></span>value - START_TYPE_INGREDIENTS<span class="Delimiter">)</span> < SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>type_ingredient_names<span class="Delimiter">))</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
+
+<span class="Delimiter">:(before "End size_of(type) Container Cases")</span>
+if <span class="Delimiter">(</span>t<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)-></span>value >= START_TYPE_INGREDIENTS<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"type"</span><span class="Delimiter">)</span> << <span class="Constant">"checking size of type ingredient</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ long long int size = size_of_type_ingredient<span class="Delimiter">(</span>t<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> type<span class="Delimiter">-></span>right<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!size<span class="Delimiter">)</span>
+ raise_error << <span class="Constant">"illegal type '"</span> << debug_string<span class="Delimiter">(</span>type<span class="Delimiter">)</span> << <span class="Constant">"' seems to be missing a type ingredient or three</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ result += size<span class="Delimiter">;</span>
+ <span class="Identifier">continue</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(code)</span>
+<span class="Comment">// shape-shifting version of size_of</span>
+long long int size_of_type_ingredient<span class="Delimiter">(</span>const type_tree* element_template<span class="Delimiter">,</span> const type_tree* rest_of_use<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ long long int type_ingredient_index = element_template<span class="Delimiter">-></span>value - START_TYPE_INGREDIENTS<span class="Delimiter">;</span>
+ const type_tree* curr = rest_of_use<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>!curr<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
+ while <span class="Delimiter">(</span>type_ingredient_index > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ --type_ingredient_index<span class="Delimiter">;</span>
+ curr = curr<span class="Delimiter">-></span>right<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>!curr<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ assert<span class="Delimiter">(</span>curr<span class="Delimiter">);</span>
+ assert<span class="Delimiter">(</span>!curr<span class="Delimiter">-></span>left<span class="Delimiter">);</span> <span class="Comment">// unimplemented</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> curr<span class="Delimiter">-></span>value<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ <span class="Comment">// temporarily while we're still ironing out kinks; eventually replace with a raise_error</span>
+ DUMP<span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">);</span>
+ cerr << <span class="Constant">"missing type "</span> << debug_string<span class="Delimiter">(</span>curr<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
+ exit<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+ assert<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> curr<span class="Delimiter">-></span>value<span class="Delimiter">));</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"type"</span><span class="Delimiter">)</span> << <span class="Constant">"type deduced to be "</span> << get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> curr<span class="Delimiter">-></span>value<span class="Delimiter">).</span>name << <span class="Constant">"$"</span> << end<span class="Delimiter">();</span>
+ type_tree tmp<span class="Delimiter">(</span>curr<span class="Delimiter">-></span>value<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>curr<span class="Delimiter">-></span>right<span class="Delimiter">)</span>
+ tmp<span class="Delimiter">.</span>right = new type_tree<span class="Delimiter">(</span>*curr<span class="Delimiter">-></span>right<span class="Delimiter">);</span>
+ <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>&tmp<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario get_on_shape_shifting_container)</span>
+container foo:_t [
+ x:_t
+ y:number
+]
+recipe main [
+ <span class="Constant">1</span>:foo:point<span class="Special"> <- </span>merge <span class="Constant">14</span><span class="Delimiter">,</span> <span class="Constant">15</span><span class="Delimiter">,</span> <span class="Constant">16</span>
+ <span class="Constant">2</span>:number<span class="Special"> <- </span>get <span class="Constant">1</span>:foo:point<span class="Delimiter">,</span> y:offset
+]
+<span class="traceContains">+mem: storing 16 in location 2</span>
+
+<span class="Delimiter">:(before "End GET field Cases")</span>
+const type_tree* type = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+if <span class="Delimiter">(</span>type<span class="Delimiter">-></span>value >= START_TYPE_INGREDIENTS<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ long long int size = size_of_type_ingredient<span class="Delimiter">(</span>type<span class="Delimiter">,</span> base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!size<span class="Delimiter">)</span>
+ raise_error << <span class="Constant">"illegal field type '"</span> << debug_string<span class="Delimiter">(</span>type<span class="Delimiter">)</span> << <span class="Constant">"' seems to be missing a type ingredient or three</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ src += size<span class="Delimiter">;</span>
+ <span class="Identifier">continue</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario get_on_shape_shifting_container_2)</span>
+container foo:_t [
+ x:_t
+ y:number
+]
+recipe main [
+ <span class="Constant">1</span>:foo:point<span class="Special"> <- </span>merge <span class="Constant">14</span><span class="Delimiter">,</span> <span class="Constant">15</span><span class="Delimiter">,</span> <span class="Constant">16</span>
+ <span class="Constant">2</span>:point<span class="Special"> <- </span>get <span class="Constant">1</span>:foo:point<span class="Delimiter">,</span> x:offset
+]
+<span class="traceContains">+mem: storing 14 in location 2</span>
+<span class="traceContains">+mem: storing 15 in location 3</span>
+
+<span class="Delimiter">:(scenario get_on_shape_shifting_container_3)</span>
+container foo:_t [
+ x:_t
+ y:number
+]
+recipe main [
+ <span class="Constant">1</span>:foo:address:point<span class="Special"> <- </span>merge <span class="Constant">34</span><span class="Delimiter">,</span> <span class="Constant">48</span> <span class="Comment"># unsafe</span>
+ <span class="Constant">2</span>:address:point<span class="Special"> <- </span>get <span class="Constant">1</span>:foo:address:point<span class="Delimiter">,</span> x:offset
+]
+<span class="traceContains">+mem: storing 34 in location 2</span>
+
+<span class="Delimiter">:(before "End element_type Special-cases")</span>
+if <span class="Delimiter">(</span>contains_type_ingredient<span class="Delimiter">(</span>element<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!canonized_base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">)</span>
+ raise_error << <span class="Constant">"illegal type '"</span> << debug_string<span class="Delimiter">(</span>canonized_base<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="Constant">"' seems to be missing a type ingredient or three</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ replace_type_ingredient<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">,</span> canonized_base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(code)</span>
+bool contains_type_ingredient<span class="Delimiter">(</span>const reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ <span class="Identifier">return</span> contains_type_ingredient<span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+bool contains_type_ingredient<span class="Delimiter">(</span>const type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!type<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>type<span class="Delimiter">-></span>value >= START_TYPE_INGREDIENTS<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+ <span class="Identifier">return</span> contains_type_ingredient<span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">)</span> || contains_type_ingredient<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+void replace_type_ingredient<span class="Delimiter">(</span>type_tree* element_type<span class="Delimiter">,</span> const type_tree* callsite_type<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!callsite_type<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// error but it's already been raised above</span>
+ if <span class="Delimiter">(</span>!element_type<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>element_type<span class="Delimiter">-></span>value >= START_TYPE_INGREDIENTS<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!has_nth_type<span class="Delimiter">(</span>callsite_type<span class="Delimiter">,</span> element_type<span class="Delimiter">-></span>value-START_TYPE_INGREDIENTS<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << <span class="Constant">"illegal type '"</span> << debug_string<span class="Delimiter">(</span>callsite_type<span class="Delimiter">)</span> << <span class="Constant">"' seems to be missing a type ingredient or three</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ const type_tree* replacement = nth_type<span class="Delimiter">(</span>callsite_type<span class="Delimiter">,</span> element_type<span class="Delimiter">-></span>value-START_TYPE_INGREDIENTS<span class="Delimiter">);</span>
+ element_type<span class="Delimiter">-></span>value = replacement<span class="Delimiter">-></span>value<span class="Delimiter">;</span>
+ element_type<span class="Delimiter">-></span>left = replacement<span class="Delimiter">-></span>left ? new type_tree<span class="Delimiter">(</span>*replacement<span class="Delimiter">-></span>left<span class="Delimiter">)</span> : <span class="Constant">NULL</span><span class="Delimiter">;</span>
+ element_type<span class="Delimiter">-></span>right = replacement<span class="Delimiter">-></span>right ? new type_tree<span class="Delimiter">(</span>*replacement<span class="Delimiter">-></span>right<span class="Delimiter">)</span> : <span class="Constant">NULL</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ replace_type_ingredient<span class="Delimiter">(</span>element_type<span class="Delimiter">-></span>right<span class="Delimiter">,</span> callsite_type<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+const type_tree* nth_type<span class="Delimiter">(</span>const type_tree* base<span class="Delimiter">,</span> long long int n<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ assert<span class="Delimiter">(</span>n >= <span class="Constant">0</span><span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>n == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> base<span class="Delimiter">;</span>
+ <span class="Identifier">return</span> nth_type<span class="Delimiter">(</span>base<span class="Delimiter">-></span>right<span class="Delimiter">,</span> n-<span class="Constant">1</span><span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+bool has_nth_type<span class="Delimiter">(</span>const type_tree* base<span class="Delimiter">,</span> long long int n<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ assert<span class="Delimiter">(</span>n >= <span class="Constant">0</span><span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>base == <span class="Constant">NULL</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>n == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+ <span class="Identifier">return</span> has_nth_type<span class="Delimiter">(</span>base<span class="Delimiter">-></span>right<span class="Delimiter">,</span> n-<span class="Constant">1</span><span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario get_on_shape_shifting_container_error)</span>
+<span class="Special">% Hide_errors = true;</span>
+container foo:_t [
+ x:_t
+ y:number
+]
+recipe main [
+ <span class="Constant">10</span>:foo:point<span class="Special"> <- </span>merge <span class="Constant">14</span><span class="Delimiter">,</span> <span class="Constant">15</span><span class="Delimiter">,</span> <span class="Constant">16</span>
+ <span class="Constant">1</span>:number<span class="Special"> <- </span>get <span class="Constant">10</span>:foo<span class="Delimiter">,</span> <span class="Constant">1</span>:offset
+]
+<span class="traceContains">+error: illegal type 'foo' seems to be missing a type ingredient or three</span>
+
+<span class="Comment">//: get-address similarly</span>
+
+<span class="Delimiter">:(scenario get_address_on_shape_shifting_container)</span>
+container foo:_t [
+ x:_t
+ y:number
+]
+recipe main [
+ <span class="Constant">10</span>:foo:point<span class="Special"> <- </span>merge <span class="Constant">14</span><span class="Delimiter">,</span> <span class="Constant">15</span><span class="Delimiter">,</span> <span class="Constant">16</span>
+ <span class="Constant">1</span>:address:number<span class="Special"> <- </span>get-address <span class="Constant">10</span>:foo:point<span class="Delimiter">,</span> <span class="Constant">1</span>:offset
+]
+<span class="traceContains">+mem: storing 12 in location 1</span>
+
+<span class="Delimiter">:(before "End GET_ADDRESS field Cases")</span>
+const type_tree* type = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+if <span class="Delimiter">(</span>type<span class="Delimiter">-></span>value >= START_TYPE_INGREDIENTS<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ long long int size = size_of_type_ingredient<span class="Delimiter">(</span>type<span class="Delimiter">,</span> base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!size<span class="Delimiter">)</span>
+ raise_error << <span class="Constant">"illegal type '"</span> << debug_string<span class="Delimiter">(</span>type<span class="Delimiter">)</span> << <span class="Constant">"' seems to be missing a type ingredient or three</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ result += size<span class="Delimiter">;</span>
+ <span class="Identifier">continue</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario get_on_shape_shifting_container_inside_shape_shifting_container)</span>
+container foo:_t [
+ x:_t
+ y:number
+]
+container bar [
+ x:foo:point
+ y:number
+]
+recipe main [
+ <span class="Constant">1</span>:bar<span class="Special"> <- </span>merge <span class="Constant">14</span><span class="Delimiter">,</span> <span class="Constant">15</span><span class="Delimiter">,</span> <span class="Constant">16</span><span class="Delimiter">,</span> <span class="Constant">17</span>
+ <span class="Constant">2</span>:number<span class="Special"> <- </span>get <span class="Constant">1</span>:bar<span class="Delimiter">,</span> <span class="Constant">1</span>:offset
+]
+<span class="traceContains">+mem: storing 17 in location 2</span>
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/html/059shape_shifting_recipe.cc.html b/html/059shape_shifting_recipe.cc.html
new file mode 100644
index 00000000..2df37fa3
--- /dev/null
+++ b/html/059shape_shifting_recipe.cc.html
@@ -0,0 +1,482 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>Mu - 059shape_shifting_recipe.cc</title>
+<meta name="Generator" content="Vim/7.4">
+<meta name="plugin-version" content="vim7.4_v1">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
+<meta name="colorscheme" content="minimal">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
+body { font-family: monospace; color: #eeeeee; background-color: #080808; }
+* { font-size: 1.05em; }
+.traceContains { color: #008000; }
+.Special { color: #ff6060; }
+.cSpecial { color: #008000; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
+.SalientComment { color: #00ffff; }
+.Identifier { color: #804000; }
+.Constant { color: #00a0a0; }
+-->
+</style>
+
+<script type='text/javascript'>
+<!--
+
+-->
+</script>
+</head>
+<body>
+<pre id='vimCodeElement'>
+<span class="SalientComment">//:: Like container definitions, recipes too can contain type parameters.</span>
+
+<span class="Delimiter">:(scenario shape_shifting_recipe)</span>
+recipe main [
+ <span class="Constant">10</span>:point<span class="Special"> <- </span>merge <span class="Constant">14</span><span class="Delimiter">,</span> <span class="Constant">15</span>
+ <span class="Constant">11</span>:point<span class="Special"> <- </span>foo <span class="Constant">10</span>:point
+]
+<span class="Comment"># non-matching variant</span>
+recipe foo a:number <span class="Delimiter">-></span> result:number [
+ local-scope
+ load-ingredients
+ result<span class="Special"> <- </span>copy <span class="Constant">34</span>
+]
+<span class="Comment"># matching shape-shifting variant</span>
+recipe foo a:_t <span class="Delimiter">-></span> result:_t [
+ local-scope
+ load-ingredients
+ result<span class="Special"> <- </span>copy a
+]
+<span class="traceContains">+mem: storing 14 in location 11</span>
+<span class="traceContains">+mem: storing 15 in location 12</span>
+
+<span class="Comment">//: Before anything else, disable transforms for shape-shifting recipes.</span>
+
+<span class="Delimiter">:(before "End Transform Checks")</span>
+if <span class="Delimiter">(</span>any_type_ingredient_in_header<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">recipe_ordinal</span><span class="Comment">*/</span>p<span class="Delimiter">-></span>first<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+
+<span class="Comment">//: We'll be creating recipes without loading them from anywhere by</span>
+<span class="Comment">//: *specializing* existing recipes, so make sure we don't clear any of those</span>
+<span class="Comment">//: when we start running tests.</span>
+<span class="Delimiter">:(before "End Loading .mu Files")</span>
+recently_added_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+recently_added_types<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+
+<span class="Delimiter">:(before "End Instruction Dispatch(inst, best_score)")</span>
+if <span class="Delimiter">(</span>best_score == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"no variant found; searching for variant with suitable type ingredients"</span> << end<span class="Delimiter">();</span>
+ recipe_ordinal exemplar = pick_matching_shape_shifting_variant<span class="Delimiter">(</span>variants<span class="Delimiter">,</span> inst<span class="Delimiter">,</span> best_score<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>exemplar<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"found variant to specialize: "</span> << exemplar << <span class="Constant">' '</span> << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> exemplar<span class="Delimiter">).</span>name << end<span class="Delimiter">();</span>
+ variants<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_variant<span class="Delimiter">(</span>exemplar<span class="Delimiter">,</span> inst<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">));</span>
+ inst<span class="Delimiter">.</span>name = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>back<span class="Delimiter">()).</span>name<span class="Delimiter">;</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"new specialization: "</span> << inst<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(code)</span>
+recipe_ordinal pick_matching_shape_shifting_variant<span class="Delimiter">(</span>vector<recipe_ordinal>& variants<span class="Delimiter">,</span> const instruction& inst<span class="Delimiter">,</span> long long int& best_score<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ recipe_ordinal result = <span class="Constant">0</span><span class="Delimiter">;</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>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="Comment">// ghost from a previous test</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"checking shape-shifting variant "</span> << i << end<span class="Delimiter">();</span>
+ long long int current_score = shape_shifting_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">"final score: "</span> << current_score << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>current_score > best_score<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ 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">"matches"</span> << end<span class="Delimiter">();</span>
+ result = variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ best_score = current_score<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+long long int shape_shifting_variant_score<span class="Delimiter">(</span>const instruction& inst<span class="Delimiter">,</span> recipe_ordinal variant<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!any_type_ingredient_in_header<span class="Delimiter">(</span>variant<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"no type ingredients"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ const vector<reagent>& header_ingredients = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> < SIZE<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"too few ingredients"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!non_type_ingredients_match<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"mismatch: ingredient "</span> << i << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">)</span> > SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"too few products"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ const vector<reagent>& header_products = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">;</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!non_type_ingredients_match<span class="Delimiter">(</span>header_products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"mismatch: product "</span> << i << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ <span class="Comment">// the greater the number of unused ingredients, the lower the score</span>
+ <span class="Identifier">return</span> <span class="Constant">100</span> - <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">)</span>-SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">))</span>
+ - <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span>-SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">));</span> <span class="Comment">// ok to go negative</span>
+<span class="Delimiter">}</span>
+
+bool any_type_ingredient_in_header<span class="Delimiter">(</span>recipe_ordinal variant<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>contains_type_ingredient_name<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span>
+ <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>contains_type_ingredient_name<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span>
+ <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+bool non_type_ingredients_match<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>contains_type_ingredient_name<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+ <span class="Identifier">return</span> types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">,</span> rhs<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>
+ <span class="Identifier">return</span> contains_type_ingredient_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>
+<span class="Delimiter">}</span>
+
+bool contains_type_ingredient_name<span class="Delimiter">(</span>const string_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!type<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>is_type_ingredient_name<span class="Delimiter">(</span>type<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="Identifier">return</span> contains_type_ingredient_name<span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">)</span> || contains_type_ingredient_name<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+bool is_type_ingredient_name<span class="Delimiter">(</span>const string& type<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ <span class="Identifier">return</span> !type<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && type<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">'_'</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+recipe_ordinal new_variant<span class="Delimiter">(</span>recipe_ordinal exemplar<span class="Delimiter">,</span> const instruction& inst<span class="Delimiter">,</span> const recipe& caller_recipe<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ string new_name = next_unused_recipe_name<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"switching "</span> << inst<span class="Delimiter">.</span>name << <span class="Constant">" to "</span> << new_name << end<span class="Delimiter">();</span>
+ assert<span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> new_name<span class="Delimiter">));</span>
+ recipe_ordinal new_recipe_ordinal = put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> new_name<span class="Delimiter">,</span> Next_recipe_ordinal++<span class="Delimiter">);</span>
+ <span class="Comment">// make a copy</span>
+ assert<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> exemplar<span class="Delimiter">));</span>
+ assert<span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> new_recipe_ordinal<span class="Delimiter">));</span>
+ recently_added_recipes<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_recipe_ordinal<span class="Delimiter">);</span>
+ put<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> new_recipe_ordinal<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> exemplar<span class="Delimiter">));</span>
+ recipe& new_recipe = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> new_recipe_ordinal<span class="Delimiter">);</span>
+ new_recipe<span class="Delimiter">.</span>name = new_name<span class="Delimiter">;</span>
+ <span class="Comment">// Since the exemplar never ran any transforms, we have to redo some of the</span>
+ <span class="Comment">// work of the check_types_by_name transform while supporting type-ingredients.</span>
+ compute_type_names<span class="Delimiter">(</span>new_recipe<span class="Delimiter">);</span>
+ <span class="Comment">// that gives enough information to replace type-ingredients with concrete types</span>
+ <span class="Delimiter">{</span>
+ map<string<span class="Delimiter">,</span> const string_tree*> mappings<span class="Delimiter">;</span>
+ bool error = <span class="Constant">false</span><span class="Delimiter">;</span>
+ compute_type_ingredient_mappings<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> exemplar<span class="Delimiter">),</span> inst<span class="Delimiter">,</span> mappings<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">,</span> &error<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>!error<span class="Delimiter">)</span> replace_type_ingredients<span class="Delimiter">(</span>new_recipe<span class="Delimiter">,</span> mappings<span class="Delimiter">);</span>
+ for <span class="Delimiter">(</span>map<string<span class="Delimiter">,</span> const string_tree*>::iterator p = mappings<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != mappings<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span>
+ delete p<span class="Delimiter">-></span>second<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>error<span class="Delimiter">)</span> <span class="Identifier">return</span> exemplar<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ ensure_all_concrete_types<span class="Delimiter">(</span>new_recipe<span class="Delimiter">);</span>
+ <span class="Comment">// finally, perform all transforms on the new specialization</span>
+ for <span class="Delimiter">(</span>long long int t = <span class="Constant">0</span><span class="Delimiter">;</span> t < SIZE<span class="Delimiter">(</span>Transform<span class="Delimiter">);</span> ++t<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ <span class="Delimiter">(</span>*Transform<span class="Delimiter">.</span>at<span class="Delimiter">(</span>t<span class="Delimiter">))(</span>new_recipe_ordinal<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+ new_recipe<span class="Delimiter">.</span>transformed_until = SIZE<span class="Delimiter">(</span>Transform<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">;</span>
+ <span class="Identifier">return</span> new_recipe_ordinal<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+void compute_type_names<span class="Delimiter">(</span>recipe& variant<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"compute type names: "</span> << variant<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span>
+ map<string<span class="Delimiter">,</span> string_tree*> type_names<span class="Delimiter">;</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
+ save_or_deduce_type_name<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> type_names<span class="Delimiter">);</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
+ save_or_deduce_type_name<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> type_names<span class="Delimiter">);</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ instruction& inst = variant<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">" instruction: "</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << end<span class="Delimiter">();</span>
+ for <span class="Delimiter">(</span>long long int in = <span class="Constant">0</span><span class="Delimiter">;</span> in < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++in<span class="Delimiter">)</span>
+ save_or_deduce_type_name<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">),</span> type_names<span class="Delimiter">);</span>
+ for <span class="Delimiter">(</span>long long int out = <span class="Constant">0</span><span class="Delimiter">;</span> out < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++out<span class="Delimiter">)</span>
+ save_or_deduce_type_name<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">),</span> type_names<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+void save_or_deduce_type_name<span class="Delimiter">(</span>reagent& x<span class="Delimiter">,</span> map<string<span class="Delimiter">,</span> string_tree*>& type_name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9994</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">" checking "</span> << x<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">": "</span> << debug_string<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second && contains_key<span class="Delimiter">(</span>type_name<span class="Delimiter">,</span> x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second = new string_tree<span class="Delimiter">(</span>*get<span class="Delimiter">(</span>type_name<span class="Delimiter">,</span> x<span class="Delimiter">.</span>name<span class="Delimiter">));</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9994</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">" deducing type to "</span> << debug_string<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise << <span class="Constant">"unknown type for "</span> << x<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>type_name<span class="Delimiter">,</span> x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">-></span>value == <span class="Constant">"offset"</span> || x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">-></span>value == <span class="Constant">"variant"</span><span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// special-case for container-access instructions</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>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"type of "</span> << x<span class="Delimiter">.</span>name << <span class="Constant">" is "</span> << debug_string<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
+<span class="Delimiter">}</span>
+
+void compute_type_ingredient_mappings<span class="Delimiter">(</span>const recipe& exemplar<span class="Delimiter">,</span> const instruction& inst<span class="Delimiter">,</span> map<string<span class="Delimiter">,</span> const string_tree*>& mappings<span class="Delimiter">,</span> const recipe& caller_recipe<span class="Delimiter">,</span> bool* error<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>exemplar<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ const reagent& exemplar_reagent = exemplar<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ reagent ingredient = inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ assert<span class="Delimiter">(</span>ingredient<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>
+ canonize_type<span class="Delimiter">(</span>ingredient<span class="Delimiter">);</span>
+ accumulate_type_ingredients<span class="Delimiter">(</span>exemplar_reagent<span class="Delimiter">,</span> ingredient<span class="Delimiter">,</span> mappings<span class="Delimiter">,</span> exemplar<span class="Delimiter">,</span> inst<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">,</span> error<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>exemplar<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ const reagent& exemplar_reagent = exemplar<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ reagent product = inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ assert<span class="Delimiter">(</span>product<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">);</span>
+ canonize_type<span class="Delimiter">(</span>product<span class="Delimiter">);</span>
+ accumulate_type_ingredients<span class="Delimiter">(</span>exemplar_reagent<span class="Delimiter">,</span> product<span class="Delimiter">,</span> mappings<span class="Delimiter">,</span> exemplar<span class="Delimiter">,</span> inst<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">,</span> error<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+void accumulate_type_ingredients<span class="Delimiter">(</span>const reagent& exemplar_reagent<span class="Delimiter">,</span> reagent& refinement<span class="Delimiter">,</span> map<string<span class="Delimiter">,</span> const string_tree*>& mappings<span class="Delimiter">,</span> const recipe& exemplar<span class="Delimiter">,</span> const instruction& call_instruction<span class="Delimiter">,</span> const recipe& caller_recipe<span class="Delimiter">,</span> bool* error<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ assert<span class="Delimiter">(</span>refinement<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>
+ accumulate_type_ingredients<span class="Delimiter">(</span>exemplar_reagent<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> refinement<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">,</span> mappings<span class="Delimiter">,</span> exemplar<span class="Delimiter">,</span> exemplar_reagent<span class="Delimiter">,</span> call_instruction<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">,</span> error<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+void accumulate_type_ingredients<span class="Delimiter">(</span>const string_tree* exemplar_type<span class="Delimiter">,</span> const string_tree* refinement_type<span class="Delimiter">,</span> map<string<span class="Delimiter">,</span> const string_tree*>& mappings<span class="Delimiter">,</span> const recipe& exemplar<span class="Delimiter">,</span> const reagent& exemplar_reagent<span class="Delimiter">,</span> const instruction& call_instruction<span class="Delimiter">,</span> const recipe& caller_recipe<span class="Delimiter">,</span> bool* error<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!exemplar_type<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>!refinement_type<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>exemplar<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"missing type ingredient in "</span> << exemplar_reagent<span class="Delimiter">.</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>!exemplar_type<span class="Delimiter">-></span>value<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && exemplar_type<span class="Delimiter">-></span>value<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">'_'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ assert<span class="Delimiter">(</span>!refinement_type<span class="Delimiter">-></span>value<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
+ if <span class="Delimiter">(</span>exemplar_type<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << <span class="Constant">"type_ingredients in non-last position not currently supported</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-></span>value<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"adding mapping from "</span> << exemplar_type<span class="Delimiter">-></span>value << <span class="Constant">" to "</span> << debug_string<span class="Delimiter">(</span>refinement_type<span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
+ put<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-></span>value<span class="Delimiter">,</span> new string_tree<span class="Delimiter">(</span>*refinement_type<span class="Delimiter">));</span>
+ <span class="Delimiter">}</span>
+ else <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!deeply_equal<span class="Delimiter">(</span>get<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-></span>value<span class="Delimiter">),</span> refinement_type<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"no call found for '"</span> << call_instruction<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ *error = <span class="Constant">true</span><span class="Delimiter">;</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ else <span class="Delimiter">{</span>
+ accumulate_type_ingredients<span class="Delimiter">(</span>exemplar_type<span class="Delimiter">-></span>left<span class="Delimiter">,</span> refinement_type<span class="Delimiter">-></span>left<span class="Delimiter">,</span> mappings<span class="Delimiter">,</span> exemplar<span class="Delimiter">,</span> exemplar_reagent<span class="Delimiter">,</span> call_instruction<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">,</span> error<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+ accumulate_type_ingredients<span class="Delimiter">(</span>exemplar_type<span class="Delimiter">-></span>right<span class="Delimiter">,</span> refinement_type<span class="Delimiter">-></span>right<span class="Delimiter">,</span> mappings<span class="Delimiter">,</span> exemplar<span class="Delimiter">,</span> exemplar_reagent<span class="Delimiter">,</span> call_instruction<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">,</span> error<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+void replace_type_ingredients<span class="Delimiter">(</span>recipe& new_recipe<span class="Delimiter">,</span> const map<string<span class="Delimiter">,</span> const string_tree*>& mappings<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ <span class="Comment">// update its header</span>
+ if <span class="Delimiter">(</span>mappings<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"replacing in recipe header ingredients"</span> << end<span class="Delimiter">();</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
+ replace_type_ingredients<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> mappings<span class="Delimiter">);</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"replacing in recipe header products"</span> << end<span class="Delimiter">();</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
+ replace_type_ingredients<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> mappings<span class="Delimiter">);</span>
+ <span class="Comment">// update its body</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ instruction& inst = new_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"replacing in instruction '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"'"</span> << end<span class="Delimiter">();</span>
+ for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span>
+ replace_type_ingredients<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">),</span> mappings<span class="Delimiter">);</span>
+ for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span>
+ replace_type_ingredients<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">),</span> mappings<span class="Delimiter">);</span>
+ <span class="Comment">// special-case for new: replace type ingredient in first ingredient *value*</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">"new"</span> && inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> != <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ string_tree* type_name = parse_string_tree<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">);</span>
+ replace_type_ingredients<span class="Delimiter">(</span>type_name<span class="Delimiter">,</span> mappings<span class="Delimiter">);</span>
+ inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name = type_name<span class="Delimiter">-></span>to_string<span class="Delimiter">();</span>
+ delete type_name<span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+void replace_type_ingredients<span class="Delimiter">(</span>reagent& x<span class="Delimiter">,</span> const map<string<span class="Delimiter">,</span> const string_tree*>& mappings<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"replacing in ingredient "</span> << x<span class="Delimiter">.</span>original_string << end<span class="Delimiter">();</span>
+ <span class="Comment">// replace properties</span>
+ assert<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">);</span>
+ replace_type_ingredients<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">,</span> mappings<span class="Delimiter">);</span>
+ <span class="Comment">// refresh types from properties</span>
+ delete x<span class="Delimiter">.</span>type<span class="Delimiter">;</span>
+ x<span class="Delimiter">.</span>type = new_type_tree<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">)</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">" after: "</span> << debug_string<span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
+<span class="Delimiter">}</span>
+
+void replace_type_ingredients<span class="Delimiter">(</span>string_tree* type<span class="Delimiter">,</span> const map<string<span class="Delimiter">,</span> const string_tree*>& mappings<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!type<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>is_type_ingredient_name<span class="Delimiter">(</span>type<span class="Delimiter">-></span>value<span class="Delimiter">)</span> && contains_key<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ const string_tree* replacement = get<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">);</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << type<span class="Delimiter">-></span>value << <span class="Constant">" => "</span> << debug_string<span class="Delimiter">(</span>replacement<span class="Delimiter">)</span> << end<span class="Delimiter">();</span>
+ type<span class="Delimiter">-></span>value = replacement<span class="Delimiter">-></span>value<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>replacement<span class="Delimiter">-></span>left<span class="Delimiter">)</span> type<span class="Delimiter">-></span>left = new string_tree<span class="Delimiter">(</span>*replacement<span class="Delimiter">-></span>left<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>replacement<span class="Delimiter">-></span>right<span class="Delimiter">)</span> type<span class="Delimiter">-></span>right = new string_tree<span class="Delimiter">(</span>*replacement<span class="Delimiter">-></span>right<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+ replace_type_ingredients<span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">,</span> mappings<span class="Delimiter">);</span>
+ replace_type_ingredients<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">,</span> mappings<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+void ensure_all_concrete_types<span class="Delimiter">(</span>const recipe& new_recipe<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
+ ensure_all_concrete_types<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">);</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
+ ensure_all_concrete_types<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">);</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ const instruction& inst = new_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span>
+ ensure_all_concrete_types<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>type<span class="Delimiter">);</span>
+ for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span>
+ ensure_all_concrete_types<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>type<span class="Delimiter">);</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+void ensure_all_concrete_types<span class="Delimiter">(</span>const type_tree* x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise << <span class="Constant">"null type</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>x<span class="Delimiter">-></span>value == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise << <span class="Constant">"unknown type</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario shape_shifting_recipe_2)</span>
+recipe main [
+ <span class="Constant">10</span>:point<span class="Special"> <- </span>merge <span class="Constant">14</span><span class="Delimiter">,</span> <span class="Constant">15</span>
+ <span class="Constant">11</span>:point<span class="Special"> <- </span>foo <span class="Constant">10</span>:point
+]
+<span class="Comment"># non-matching shape-shifting variant</span>
+recipe foo a:_t<span class="Delimiter">,</span> b:_t <span class="Delimiter">-></span> result:number [
+ local-scope
+ load-ingredients
+ result<span class="Special"> <- </span>copy <span class="Constant">34</span>
+]
+<span class="Comment"># matching shape-shifting variant</span>
+recipe foo a:_t <span class="Delimiter">-></span> result:_t [
+ local-scope
+ load-ingredients
+ result<span class="Special"> <- </span>copy a
+]
+<span class="traceContains">+mem: storing 14 in location 11</span>
+<span class="traceContains">+mem: storing 15 in location 12</span>
+
+<span class="Delimiter">:(scenario shape_shifting_recipe_nonroot)</span>
+recipe main [
+ <span class="Constant">10</span>:foo:point<span class="Special"> <- </span>merge <span class="Constant">14</span><span class="Delimiter">,</span> <span class="Constant">15</span><span class="Delimiter">,</span> <span class="Constant">16</span>
+ <span class="Constant">20</span>:point/<span class="Special">raw <- </span>bar <span class="Constant">10</span>:foo:point
+]
+<span class="Comment"># shape-shifting recipe with type ingredient following some other type</span>
+recipe bar a:foo:_t <span class="Delimiter">-></span> result:_t [
+ local-scope
+ load-ingredients
+ result<span class="Special"> <- </span>get a<span class="Delimiter">,</span> x:offset
+]
+container foo:_t [
+ x:_t
+ y:number
+]
+<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_type_deduction_ignores_offsets)</span>
+recipe main [
+ <span class="Constant">10</span>:foo:point<span class="Special"> <- </span>merge <span class="Constant">14</span><span class="Delimiter">,</span> <span class="Constant">15</span><span class="Delimiter">,</span> <span class="Constant">16</span>
+ <span class="Constant">20</span>:point/<span class="Special">raw <- </span>bar <span class="Constant">10</span>:foo:point
+]
+recipe bar a:foo:_t <span class="Delimiter">-></span> result:_t [
+ local-scope
+ load-ingredients
+ x:number<span class="Special"> <- </span>copy <span class="Constant">1</span>
+ result<span class="Special"> <- </span>get a<span class="Delimiter">,</span> x:offset <span class="Comment"># shouldn't collide with other variable</span>
+]
+container foo:_t [
+ x:_t
+ y:number
+]
+<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_handles_shape_shifting_new_ingredient)</span>
+recipe main [
+ <span class="Constant">1</span>:address:foo:point<span class="Special"> <- </span>bar <span class="Constant">3</span>
+ <span class="Constant">11</span>:foo:point<span class="Special"> <- </span>copy *<span class="Constant">1</span>:address:foo:point
+]
+container foo:_t [
+ x:_t
+ y:number
+]
+recipe bar x:number <span class="Delimiter">-></span> result:address:foo:_t [
+ local-scope
+ load-ingredients
+ <span class="Comment"># new refers to _t in its ingredient *value*</span>
+ result<span class="Special"> <- </span>new <span class="Delimiter">{(</span>foo _t<span class="Delimiter">)</span> : type<span class="Delimiter">}</span>
+]
+<span class="traceContains">+mem: storing 0 in location 11</span>
+<span class="traceContains">+mem: storing 0 in location 12</span>
+<span class="traceContains">+mem: storing 0 in location 13</span>
+
+<span class="Delimiter">:(scenario shape_shifting_recipe_handles_shape_shifting_new_ingredient_2)</span>
+recipe main [
+ <span class="Constant">1</span>:address:foo:point<span class="Special"> <- </span>bar <span class="Constant">3</span>
+ <span class="Constant">11</span>:foo:point<span class="Special"> <- </span>copy *<span class="Constant">1</span>:address:foo:point
+]
+recipe bar x:number <span class="Delimiter">-></span> result:address:foo:_t [
+ local-scope
+ load-ingredients
+ <span class="Comment"># new refers to _t in its ingredient *value*</span>
+ result<span class="Special"> <- </span>new <span class="Delimiter">{(</span>foo _t<span class="Delimiter">)</span> : type<span class="Delimiter">}</span>
+]
+<span class="Comment"># container defined after use</span>
+container foo:_t [
+ x:_t
+ y:number
+]
+<span class="traceContains">+mem: storing 0 in location 11</span>
+<span class="traceContains">+mem: storing 0 in location 12</span>
+<span class="traceContains">+mem: storing 0 in location 13</span>
+
+<span class="Delimiter">:(scenario shape_shifting_recipe_supports_compound_types)</span>
+recipe main [
+ <span class="Constant">1</span>:address:point<span class="Special"> <- </span>new point:type
+ <span class="Constant">2</span>:address:number<span class="Special"> <- </span>get-address *<span class="Constant">1</span>:address:point<span class="Delimiter">,</span> y:offset
+ *<span class="Constant">2</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
+ <span class="Constant">3</span>:address:point<span class="Special"> <- </span>bar <span class="Constant">1</span>:address:point <span class="Comment"># specialize _t to address:point</span>
+ <span class="Constant">4</span>:point<span class="Special"> <- </span>copy *<span class="Constant">3</span>:address:point
+]
+recipe bar a:_t <span class="Delimiter">-></span> result:_t [
+ local-scope
+ load-ingredients
+ result<span class="Special"> <- </span>copy a
+]
+<span class="traceContains">+mem: storing 34 in location 5</span>
+
+<span class="Delimiter">:(scenario shape_shifting_recipe_error)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+ a:number<span class="Special"> <- </span>copy <span class="Constant">3</span>
+ b:address:number<span class="Special"> <- </span>foo a
+]
+recipe foo a:_t <span class="Delimiter">-></span> b:_t [
+ load-ingredients
+ b<span class="Special"> <- </span>copy a
+]
+<span class="traceContains">+error: main: no call found for 'b:address:number <- foo a'</span>
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/html/060string.mu.html b/html/060string.mu.html
index a5cf9f7a..ae7a3e01 100644
--- a/html/060string.mu.html
+++ b/html/060string.mu.html
@@ -13,14 +13,14 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
.muRecipe { color: #ff8700; }
-.muData { color: #ffff00; }
.muScenario { color: #00af00; }
+.muData { color: #ffff00; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.Special { color: #ff6060; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
-->
</style>
@@ -447,7 +447,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
s:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
oldc:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
newc:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- from:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ from:number, _<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># default to 0</span>
len:number<span class="Special"> <- </span>length *s
i:number<span class="Special"> <- </span>find-next s, oldc, from
done?:boolean<span class="Special"> <- </span>greater-or-equal i, len
@@ -625,62 +625,60 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
c:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
<span class="Comment"># most common case first</span>
result:boolean<span class="Special"> <- </span>equal c, <span class="Constant">32/space</span>
- <span class="muControl">jump-if</span> result <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">10/newline</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">9/tab</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">13/carriage-return</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
<span class="Comment"># remaining uncommon cases in sorted order</span>
<span class="Comment"># <a href="http://unicode.org">http://unicode.org</a> code-points in unicode-set Z and Pattern_White_Space</span>
result<span class="Special"> <- </span>equal c, <span class="Constant">11/ctrl-k</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">12/ctrl-l</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">133/ctrl-0085</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">160/no-break-space</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">5760/ogham-space-mark</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">8192/en-quad</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">8193/em-quad</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">8194/en-space</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">8195/em-space</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">8196/three-per-em-space</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">8197/four-per-em-space</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">8198/six-per-em-space</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">8199/figure-space</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">8200/punctuation-space</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">8201/thin-space</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">8202/hair-space</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">8206/left-to-right</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">8207/right-to-left</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">8232/line-separator</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">8233/paragraph-separator</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">8239/narrow-no-break-space</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">8287/medium-mathematical-space</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
+ <span class="muControl">reply-if</span> result, result
result<span class="Special"> <- </span>equal c, <span class="Constant">12288/ideographic-space</span>
- <span class="muControl">jump-if</span> result, <span class="Constant">+reply:label</span>
-<span class="Constant"> +reply</span>
<span class="muControl">reply</span> result
]
diff --git a/html/061channel.mu.html b/html/061channel.mu.html
index a52d34f3..47a11e0f 100644
--- a/html/061channel.mu.html
+++ b/html/061channel.mu.html
@@ -13,15 +13,15 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
+.muRecipe { color: #ff8700; }
.muScenario { color: #00af00; }
.muData { color: #ffff00; }
.SalientComment { color: #00ffff; }
-.muRecipe { color: #ff8700; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.Special { color: #ff6060; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
-->
</style>
@@ -47,7 +47,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
run [
<span class="Constant">1</span>:address:channel<span class="Special"> <- </span>new-channel <span class="Constant">3/capacity</span>
<span class="Constant">1</span>:address:channel<span class="Special"> <- </span>write <span class="Constant">1</span>:address:channel, <span class="Constant">34</span>
- <span class="Constant">2</span>:number, <span class="Constant">1</span>:address:channel<span class="Special"> <- </span>read <span class="Constant">1</span>:address:channel
+ <span class="Constant">2</span>:character, <span class="Constant">1</span>:address:channel<span class="Special"> <- </span>read <span class="Constant">1</span>:address:channel
]
memory-should-contain [
<span class="Constant">2</span><span class="Special"> <- </span><span class="Constant">34</span>
@@ -63,7 +63,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># A circular buffer contains values from index first-full up to (but not</span>
<span class="Comment"># including) index first-empty. The reader always modifies it at first-full,</span>
<span class="Comment"># while the writer always modifies it at first-empty.</span>
- data:address:array:location
+ data:address:array:character
]
<span class="Comment"># result:address:channel <- new-channel capacity:number</span>
@@ -80,16 +80,16 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># result.data = new location[ingredient+1]</span>
capacity:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
capacity<span class="Special"> <- </span>add capacity, <span class="Constant">1</span> <span class="Comment"># unused slot for 'full?' below</span>
- dest:address:address:array:location<span class="Special"> <- </span>get-address *result, <span class="Constant">data:offset</span>
- *dest<span class="Special"> <- </span>new <span class="Constant">location:type</span>, capacity
+ dest:address:address:array:character<span class="Special"> <- </span>get-address *result, <span class="Constant">data:offset</span>
+ *dest<span class="Special"> <- </span>new <span class="Constant">character:type</span>, capacity
<span class="muControl">reply</span> result
]
-<span class="Comment"># chan <- write chan:address:channel, val:location</span>
+<span class="Comment"># chan <- write chan:address:channel, val:character</span>
<span class="muRecipe">recipe</span> write [
<span class="Constant">local-scope</span>
chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- val:location<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ val:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
<span class="Delimiter">{</span>
<span class="Comment"># block if chan is full</span>
full:boolean<span class="Special"> <- </span>channel-full? chan
@@ -98,9 +98,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
wait-for-location *full-address
<span class="Delimiter">}</span>
<span class="Comment"># store val</span>
- circular-buffer:address:array:location<span class="Special"> <- </span>get *chan, <span class="Constant">data:offset</span>
+ circular-buffer:address:array:character<span class="Special"> <- </span>get *chan, <span class="Constant">data:offset</span>
free:address:number<span class="Special"> <- </span>get-address *chan, <span class="Constant">first-free:offset</span>
- dest:address:location<span class="Special"> <- </span>index-address *circular-buffer, *free
+ dest:address:character<span class="Special"> <- </span>index-address *circular-buffer, *free
*dest<span class="Special"> <- </span>copy val
<span class="Comment"># mark its slot as filled</span>
*free<span class="Special"> <- </span>add *free, <span class="Constant">1</span>
@@ -114,7 +114,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">reply</span> chan/same-as-ingredient:<span class="Constant">0</span>
]
-<span class="Comment"># result:location, chan <- read chan:address:channel</span>
+<span class="Comment"># result:character, chan <- read chan:address:channel</span>
<span class="muRecipe">recipe</span> read [
<span class="Constant">local-scope</span>
chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
@@ -127,8 +127,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">}</span>
<span class="Comment"># read result</span>
full:address:number<span class="Special"> <- </span>get-address *chan, <span class="Constant">first-full:offset</span>
- circular-buffer:address:array:location<span class="Special"> <- </span>get *chan, <span class="Constant">data:offset</span>
- result:location<span class="Special"> <- </span>index *circular-buffer, *full
+ circular-buffer:address:array:character<span class="Special"> <- </span>get *chan, <span class="Constant">data:offset</span>
+ result:character<span class="Special"> <- </span>index *circular-buffer, *full
<span class="Comment"># mark its slot as empty</span>
*full<span class="Special"> <- </span>add *full, <span class="Constant">1</span>
<span class="Delimiter">{</span>
@@ -254,7 +254,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muRecipe">recipe</span> channel-capacity [
<span class="Constant">local-scope</span>
chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- q:address:array:location<span class="Special"> <- </span>get *chan, <span class="Constant">data:offset</span>
+ q:address:array:character<span class="Special"> <- </span>get *chan, <span class="Constant">data:offset</span>
result:number<span class="Special"> <- </span>length *q
<span class="muControl">reply</span> result
]
diff --git a/html/062array.mu.html b/html/062array.mu.html
index b65da102..4f800098 100644
--- a/html/062array.mu.html
+++ b/html/062array.mu.html
@@ -13,13 +13,13 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
-.muScenario { color: #00af00; }
+.muControl { color: #c0a020; }
.muRecipe { color: #ff8700; }
+.muScenario { color: #00af00; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.Special { color: #ff6060; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
-->
</style>
@@ -33,8 +33,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<pre id='vimCodeElement'>
<span class="muScenario">scenario</span> array-from-args [
run [
- <span class="Constant">1</span>:address:array:location<span class="Special"> <- </span>new-array <span class="Constant">0</span>, <span class="Constant">1</span>, <span class="Constant">2</span>
- <span class="Constant">2</span>:array:location<span class="Special"> <- </span>copy *<span class="Constant">1</span>:address:array:location
+ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new-array <span class="Constant">0</span>, <span class="Constant">1</span>, <span class="Constant">2</span>
+ <span class="Constant">2</span>:array:character<span class="Special"> <- </span>copy *<span class="Constant">1</span>:address:array:character
]
memory-should-contain [
<span class="Constant">2</span><span class="Special"> <- </span><span class="Constant">3</span> <span class="Comment"># array length</span>
@@ -50,21 +50,21 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
capacity:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
<span class="Delimiter">{</span>
<span class="Comment"># while read curr-value</span>
- curr-value:location, exists?:boolean<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ curr-value:character, exists?:boolean<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
<span class="muControl">break-unless</span> exists?
capacity<span class="Special"> <- </span>add capacity, <span class="Constant">1</span>
<span class="muControl">loop</span>
<span class="Delimiter">}</span>
- result:address:array:location<span class="Special"> <- </span>new <span class="Constant">location:type</span>, capacity
+ result:address:array:character<span class="Special"> <- </span>new <span class="Constant">character:type</span>, capacity
rewind-ingredients
i:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
<span class="Delimiter">{</span>
<span class="Comment"># while read curr-value</span>
done?:boolean<span class="Special"> <- </span>greater-or-equal i, capacity
<span class="muControl">break-if</span> done?
- curr-value:location, exists?:boolean<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ curr-value:character, exists?:boolean<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
assert exists?, <span class="Constant">[error in rewinding ingredients to new-array]</span>
- tmp:address:location<span class="Special"> <- </span>index-address *result, i
+ tmp:address:character<span class="Special"> <- </span>index-address *result, i
*tmp<span class="Special"> <- </span>copy curr-value
i<span class="Special"> <- </span>add i, <span class="Constant">1</span>
<span class="muControl">loop</span>
diff --git a/html/063list.mu.html b/html/063list.mu.html
index a4c4e02e..a3122c41 100644
--- a/html/063list.mu.html
+++ b/html/063list.mu.html
@@ -13,13 +13,14 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
.muRecipe { color: #ff8700; }
-.muData { color: #ffff00; }
.muScenario { color: #00af00; }
+.muData { color: #ffff00; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.Special { color: #ff6060; }
-.muControl { color: #c0a020; }
+.Delimiter { color: #a04060; }
-->
</style>
@@ -33,55 +34,58 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<pre id='vimCodeElement'>
<span class="Comment"># A list links up multiple objects together to make them easier to manage.</span>
<span class="Comment">#</span>
-<span class="Comment"># Try to make all objects in a single list of the same type, it'll help avoid bugs.</span>
-<span class="Comment"># If you want to store multiple types in a single list, use an exclusive-container.</span>
+<span class="Comment"># The objects must be of the same type. If you want to store multiple types in</span>
+<span class="Comment"># a single list, use an exclusive-container.</span>
-<span class="muData">container</span> list [
- value:location
- next:address:list
+<span class="muData">container</span> list:_elem [
+ value:_elem
+ next:address:list:_elem
]
-<span class="Comment"># result:address:list <- push x:location, in:address:list</span>
-<span class="muRecipe">recipe</span> push [
+<span class="muRecipe">recipe</span> push x:_elem, in:address:list:_elem<span class="muRecipe"> -> </span>result:address:list:_elem [
<span class="Constant">local-scope</span>
- x:location<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- in:address:list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- result:address:list<span class="Special"> <- </span>new <span class="Constant">list:type</span>
- val:address:location<span class="Special"> <- </span>get-address *result, <span class="Constant">value:offset</span>
+ <span class="Constant">load-ingredients</span>
+ result<span class="Special"> <- </span>new <span class="Delimiter">{</span>(list _elem): type<span class="Delimiter">}</span>
+ val:address:_elem<span class="Special"> <- </span>get-address *result, <span class="Constant">value:offset</span>
*val<span class="Special"> <- </span>copy x
- next:address:address:list<span class="Special"> <- </span>get-address *result, <span class="Constant">next:offset</span>
+ next:address:address:list:_elem<span class="Special"> <- </span>get-address *result, <span class="Constant">next:offset</span>
*next<span class="Special"> <- </span>copy in
<span class="muControl">reply</span> result
]
-<span class="Comment"># result:location <- first in:address:list</span>
-<span class="muRecipe">recipe</span> first [
+<span class="muRecipe">recipe</span> first in:address:list:_elem<span class="muRecipe"> -> </span>result:_elem [
<span class="Constant">local-scope</span>
- in:address:list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- result:location<span class="Special"> <- </span>get *in, <span class="Constant">value:offset</span>
- <span class="muControl">reply</span> result
+ <span class="Constant">load-ingredients</span>
+ result<span class="Special"> <- </span>get *in, <span class="Constant">value:offset</span>
]
<span class="Comment"># result:address:list <- rest in:address:list</span>
-<span class="muRecipe">recipe</span> rest [
+<span class="muRecipe">recipe</span> rest in:address:list:_elem<span class="muRecipe"> -> </span>result:address:list:_elem [
<span class="Constant">local-scope</span>
- in:address:list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- result:address:list<span class="Special"> <- </span>get *in, <span class="Constant">next:offset</span>
- <span class="muControl">reply</span> result
+ <span class="Constant">load-ingredients</span>
+ result<span class="Special"> <- </span>get *in, <span class="Constant">next:offset</span>
+]
+
+<span class="muRecipe">recipe</span> force-specialization-list-number [
+ <span class="Constant">1</span>:address:list:number<span class="Special"> <- </span>push <span class="Constant">2</span>:number, <span class="Constant">1</span>:address:list:number
+ <span class="Constant">2</span>:number<span class="Special"> <- </span>first <span class="Constant">1</span>:address:list:number
+ <span class="Constant">1</span>:address:list:number<span class="Special"> <- </span>rest <span class="Constant">1</span>:address:list:number
]
+<span class="Comment"># todo: automatically specialize code in scenarios</span>
<span class="muScenario">scenario</span> list-handling [
run [
- <span class="Constant">1</span>:address:list<span class="Special"> <- </span>copy <span class="Constant">0</span>
- <span class="Constant">1</span>:address:list<span class="Special"> <- </span>push <span class="Constant">3</span>, <span class="Constant">1</span>:address:list
- <span class="Constant">1</span>:address:list<span class="Special"> <- </span>push <span class="Constant">4</span>, <span class="Constant">1</span>:address:list
- <span class="Constant">1</span>:address:list<span class="Special"> <- </span>push <span class="Constant">5</span>, <span class="Constant">1</span>:address:list
- <span class="Constant">2</span>:number<span class="Special"> <- </span>first <span class="Constant">1</span>:address:list
- <span class="Constant">1</span>:address:list<span class="Special"> <- </span>rest <span class="Constant">1</span>:address:list
- <span class="Constant">3</span>:number<span class="Special"> <- </span>first <span class="Constant">1</span>:address:list
- <span class="Constant">1</span>:address:list<span class="Special"> <- </span>rest <span class="Constant">1</span>:address:list
- <span class="Constant">4</span>:number<span class="Special"> <- </span>first <span class="Constant">1</span>:address:list
- <span class="Constant">1</span>:address:list<span class="Special"> <- </span>rest <span class="Constant">1</span>:address:list
+ <span class="Constant">1</span>:address:list:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
+ <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">3</span>
+ <span class="Constant">1</span>:address:list:number<span class="Special"> <- </span>push <span class="Constant">2</span>:number, <span class="Constant">1</span>:address:list:number
+ <span class="Constant">1</span>:address:list:number<span class="Special"> <- </span>push <span class="Constant">4</span>, <span class="Constant">1</span>:address:list:number
+ <span class="Constant">1</span>:address:list:number<span class="Special"> <- </span>push <span class="Constant">5</span>, <span class="Constant">1</span>:address:list:number
+ <span class="Constant">2</span>:number<span class="Special"> <- </span>first <span class="Constant">1</span>:address:list:number
+ <span class="Constant">1</span>:address:list:number<span class="Special"> <- </span>rest <span class="Constant">1</span>:address:list:number
+ <span class="Constant">3</span>:number<span class="Special"> <- </span>first <span class="Constant">1</span>:address:list:number
+ <span class="Constant">1</span>:address:list:number<span class="Special"> <- </span>rest <span class="Constant">1</span>:address:list:number
+ <span class="Constant">4</span>:number<span class="Special"> <- </span>first <span class="Constant">1</span>:address:list:number
+ <span class="Constant">1</span>:address:list:number<span class="Special"> <- </span>rest <span class="Constant">1</span>:address:list:number
]
memory-should-contain [
<span class="Constant">1</span><span class="Special"> <- </span><span class="Constant">0</span> <span class="Comment"># empty to empty, dust to dust..</span>
diff --git a/html/064random.cc.html b/html/064random.cc.html
index e8a75626..bd176af3 100644
--- a/html/064random.cc.html
+++ b/html/064random.cc.html
@@ -13,8 +13,8 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
-.cSpecial { color: #008000; }
.traceContains { color: #008000; }
+.cSpecial { color: #008000; }
.PreProc { color: #c000c0; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
@@ -35,7 +35,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
RANDOM<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"random"</span>] = RANDOM<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"random"</span><span class="Delimiter">,</span> RANDOM<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case RANDOM: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case RANDOM: <span class="Delimiter">{</span>
<span class="Comment">// todo: limited range of numbers, might be imperfectly random</span>
@@ -48,7 +52,11 @@ case RANDOM: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
MAKE_RANDOM_NONDETERMINISTIC<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"make-random-nondeterministic"</span>] = MAKE_RANDOM_NONDETERMINISTIC<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"make-random-nondeterministic"</span><span class="Delimiter">,</span> MAKE_RANDOM_NONDETERMINISTIC<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case MAKE_RANDOM_NONDETERMINISTIC: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case MAKE_RANDOM_NONDETERMINISTIC: <span class="Delimiter">{</span>
srand<span class="Delimiter">(</span>time<span class="Delimiter">(</span><span class="Constant">NULL</span><span class="Delimiter">));</span>
@@ -58,17 +66,21 @@ case MAKE_RANDOM_NONDETERMINISTIC: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
ROUND<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"round"</span>] = ROUND<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"round"</span><span class="Delimiter">,</span> ROUND<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case ROUND: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'round' requires exactly one ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ 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>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'round' requires exactly one ingredient, but got "</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>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'round' should be a number, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'round' should be a number, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="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">:(before "End Primitive Recipe Implementations")</span>
+case ROUND: <span class="Delimiter">{</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>rint<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
diff --git a/html/065duplex_list.mu.html b/html/065duplex_list.mu.html
index bf7634a0..4a9437ce 100644
--- a/html/065duplex_list.mu.html
+++ b/html/065duplex_list.mu.html
@@ -13,14 +13,14 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
.muRecipe { color: #ff8700; }
-.muData { color: #ffff00; }
.muScenario { color: #00af00; }
+.muData { color: #ffff00; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.Special { color: #ff6060; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
-->
</style>
@@ -34,52 +34,44 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<pre id='vimCodeElement'>
<span class="Comment"># A doubly linked list permits bidirectional traversal.</span>
-<span class="muData">container</span> duplex-list [
- value:location
- next:address:duplex-list
- prev:address:duplex-list
+<span class="muData">container</span> duplex-list:_elem [
+ value:_elem
+ next:address:duplex-list:_elem
+ prev:address:duplex-list:_elem
]
-<span class="Comment"># result:address:duplex-list <- push-duplex x:location, in:address:duplex-list</span>
-<span class="muRecipe">recipe</span> push-duplex [
+<span class="muRecipe">recipe</span> push-duplex x:_elem, in:address:duplex-list:_elem<span class="muRecipe"> -> </span>result:address:duplex-list:_elem [
<span class="Constant">local-scope</span>
- x:location<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- in:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- result:address:duplex-list<span class="Special"> <- </span>new <span class="Constant">duplex-list:type</span>
- val:address:location<span class="Special"> <- </span>get-address *result, <span class="Constant">value:offset</span>
+ <span class="Constant">load-ingredients</span>
+ result<span class="Special"> <- </span>new <span class="Delimiter">{</span>(duplex-list _elem): type<span class="Delimiter">}</span>
+ val:address:_elem<span class="Special"> <- </span>get-address *result, <span class="Constant">value:offset</span>
*val<span class="Special"> <- </span>copy x
- next:address:address:duplex-list<span class="Special"> <- </span>get-address *result, <span class="Constant">next:offset</span>
+ next:address:address:duplex-list:_elem<span class="Special"> <- </span>get-address *result, <span class="Constant">next:offset</span>
*next<span class="Special"> <- </span>copy in
- <span class="muControl">reply-unless</span> in, result
- prev:address:address:duplex-list<span class="Special"> <- </span>get-address *in, <span class="Constant">prev:offset</span>
+ <span class="muControl">reply-unless</span> in
+ prev:address:address:duplex-list:_elem<span class="Special"> <- </span>get-address *in, <span class="Constant">prev:offset</span>
*prev<span class="Special"> <- </span>copy result
- <span class="muControl">reply</span> result
]
-<span class="Comment"># result:location <- first-duplex in:address:duplex-list</span>
-<span class="muRecipe">recipe</span> first-duplex [
+<span class="muRecipe">recipe</span> first-duplex in:address:duplex-list:_elem<span class="muRecipe"> -> </span>result:_elem [
<span class="Constant">local-scope</span>
- in:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
<span class="muControl">reply-unless</span> in, <span class="Constant">0</span>
- result:location<span class="Special"> <- </span>get *in, <span class="Constant">value:offset</span>
- <span class="muControl">reply</span> result
+ result<span class="Special"> <- </span>get *in, <span class="Constant">value:offset</span>
]
-<span class="Comment"># result:address:duplex-list <- next-duplex in:address:duplex-list</span>
-<span class="muRecipe">recipe</span> next-duplex [
+<span class="muRecipe">recipe</span> next-duplex in:address:duplex-list:_elem<span class="muRecipe"> -> </span>result:address:duplex-list:_elem [
<span class="Constant">local-scope</span>
- in:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
<span class="muControl">reply-unless</span> in, <span class="Constant">0</span>
- result:address:duplex-list<span class="Special"> <- </span>get *in, <span class="Constant">next:offset</span>
- <span class="muControl">reply</span> result
+ result<span class="Special"> <- </span>get *in, <span class="Constant">next:offset</span>
]
-<span class="Comment"># result:address:duplex-list <- prev-duplex in:address:duplex-list</span>
-<span class="muRecipe">recipe</span> prev-duplex [
+<span class="muRecipe">recipe</span> prev-duplex in:address:duplex-list:_elem<span class="muRecipe"> -> </span>result:address:duplex-list:_elem [
<span class="Constant">local-scope</span>
- in:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
<span class="muControl">reply-unless</span> in, <span class="Constant">0</span>
- result:address:duplex-list<span class="Special"> <- </span>get *in, <span class="Constant">prev:offset</span>
+ result<span class="Special"> <- </span>get *in, <span class="Constant">prev:offset</span>
<span class="muControl">reply</span> result
]
@@ -88,25 +80,25 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># reserve locations 0, 1 and 2 to check for missing null check</span>
<span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
<span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">35</span>
- <span class="Constant">3</span>:address:duplex-list<span class="Special"> <- </span>copy <span class="Constant">0</span>
- <span class="Constant">3</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">3</span>, <span class="Constant">3</span>:address:duplex-list
- <span class="Constant">3</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">4</span>, <span class="Constant">3</span>:address:duplex-list
- <span class="Constant">3</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">5</span>, <span class="Constant">3</span>:address:duplex-list
- <span class="Constant">4</span>:address:duplex-list<span class="Special"> <- </span>copy <span class="Constant">3</span>:address:duplex-list
- <span class="Constant">5</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">4</span>:address:duplex-list
- <span class="Constant">4</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">4</span>:address:duplex-list
- <span class="Constant">6</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">4</span>:address:duplex-list
- <span class="Constant">4</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">4</span>:address:duplex-list
- <span class="Constant">7</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">4</span>:address:duplex-list
- <span class="Constant">8</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">4</span>:address:duplex-list
- <span class="Constant">9</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">8</span>:address:duplex-list
- <span class="Constant">10</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">8</span>:address:duplex-list
- <span class="Constant">11</span>:address:duplex-list<span class="Special"> <- </span>prev-duplex <span class="Constant">8</span>:address:duplex-list
- <span class="Constant">4</span>:address:duplex-list<span class="Special"> <- </span>prev-duplex <span class="Constant">4</span>:address:duplex-list
- <span class="Constant">12</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">4</span>:address:duplex-list
- <span class="Constant">4</span>:address:duplex-list<span class="Special"> <- </span>prev-duplex <span class="Constant">4</span>:address:duplex-list
- <span class="Constant">13</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">4</span>:address:duplex-list
- <span class="Constant">14</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">3</span>:address:duplex-list, <span class="Constant">4</span>:address:duplex-list
+ <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> <- </span>copy <span class="Constant">0</span>
+ <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">3</span>, <span class="Constant">3</span>:address:duplex-list:character
+ <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">4</span>, <span class="Constant">3</span>:address:duplex-list:character
+ <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">5</span>, <span class="Constant">3</span>:address:duplex-list:character
+ <span class="Constant">4</span>:address:duplex-list:character<span class="Special"> <- </span>copy <span class="Constant">3</span>:address:duplex-list:character
+ <span class="Constant">5</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">4</span>:address:duplex-list:character
+ <span class="Constant">4</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">4</span>:address:duplex-list:character
+ <span class="Constant">6</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">4</span>:address:duplex-list:character
+ <span class="Constant">4</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">4</span>:address:duplex-list:character
+ <span class="Constant">7</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">4</span>:address:duplex-list:character
+ <span class="Constant">8</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">4</span>:address:duplex-list:character
+ <span class="Constant">9</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">8</span>:address:duplex-list:character
+ <span class="Constant">10</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">8</span>:address:duplex-list:character
+ <span class="Constant">11</span>:address:duplex-list:character<span class="Special"> <- </span>prev-duplex <span class="Constant">8</span>:address:duplex-list:character
+ <span class="Constant">4</span>:address:duplex-list:character<span class="Special"> <- </span>prev-duplex <span class="Constant">4</span>:address:duplex-list:character
+ <span class="Constant">12</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">4</span>:address:duplex-list:character
+ <span class="Constant">4</span>:address:duplex-list:character<span class="Special"> <- </span>prev-duplex <span class="Constant">4</span>:address:duplex-list:character
+ <span class="Constant">13</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">4</span>:address:duplex-list:character
+ <span class="Constant">14</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">3</span>:address:duplex-list:character, <span class="Constant">4</span>:address:duplex-list:character
]
memory-should-contain [
<span class="Constant">0</span><span class="Special"> <- </span><span class="Constant">0</span> <span class="Comment"># no modifications to null pointers</span>
@@ -125,18 +117,16 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
]
-<span class="Comment"># l:address:duplex-list <- insert-duplex x:location, in:address:duplex-list</span>
<span class="Comment"># Inserts 'x' after 'in'. Returns some pointer into the list.</span>
-<span class="muRecipe">recipe</span> insert-duplex [
+<span class="muRecipe">recipe</span> insert-duplex x:_elem, in:address:duplex-list:_elem<span class="muRecipe"> -> </span>new-node:address:duplex-list:_elem [
<span class="Constant">local-scope</span>
- x:location<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- in:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- new-node:address:duplex-list<span class="Special"> <- </span>new <span class="Constant">duplex-list:type</span>
- val:address:location<span class="Special"> <- </span>get-address *new-node, <span class="Constant">value:offset</span>
+ <span class="Constant">load-ingredients</span>
+ new-node<span class="Special"> <- </span>new <span class="Delimiter">{</span>(duplex-list _elem): type<span class="Delimiter">}</span>
+ val:address:_elem<span class="Special"> <- </span>get-address *new-node, <span class="Constant">value:offset</span>
*val<span class="Special"> <- </span>copy x
- next-node:address:duplex-list<span class="Special"> <- </span>get *in, <span class="Constant">next:offset</span>
+ next-node:address:duplex-list:_elem<span class="Special"> <- </span>get *in, <span class="Constant">next:offset</span>
<span class="Comment"># in.next = new-node</span>
- y:address:address:duplex-list<span class="Special"> <- </span>get-address *in, <span class="Constant">next:offset</span>
+ y:address:address:duplex-list:_elem<span class="Special"> <- </span>get-address *in, <span class="Constant">next:offset</span>
*y<span class="Special"> <- </span>copy new-node
<span class="Comment"># new-node.prev = in</span>
y<span class="Special"> <- </span>get-address *new-node, <span class="Constant">prev:offset</span>
@@ -154,28 +144,28 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> inserting-into-duplex-list [
run [
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># 1 points to head of list</span>
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">3</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">4</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">5</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list <span class="Comment"># 2 points inside list</span>
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>insert-duplex <span class="Constant">6</span>, <span class="Constant">2</span>:address:duplex-list
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># 1 points to head of list</span>
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">3</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">4</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">5</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list:character <span class="Comment"># 2 points inside list</span>
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>insert-duplex <span class="Constant">6</span>, <span class="Constant">2</span>:address:duplex-list:character
<span class="Comment"># check structure like before</span>
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>copy <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">3</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">4</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">5</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">6</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">7</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">8</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">9</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">10</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">1</span>:address:duplex-list, <span class="Constant">2</span>:address:duplex-list
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>copy <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">3</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">4</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">5</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">6</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">7</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">8</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">9</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">10</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">2</span>:address:duplex-list:character
]
memory-should-contain [
<span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">5</span> <span class="Comment"># scanning next</span>
@@ -191,29 +181,29 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> inserting-at-end-of-duplex-list [
run [
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># 1 points to head of list</span>
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">3</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">4</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">5</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list <span class="Comment"># 2 points inside list</span>
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list <span class="Comment"># now at end of list</span>
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>insert-duplex <span class="Constant">6</span>, <span class="Constant">2</span>:address:duplex-list
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># 1 points to head of list</span>
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">3</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">4</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">5</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list:character <span class="Comment"># 2 points inside list</span>
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character <span class="Comment"># now at end of list</span>
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>insert-duplex <span class="Constant">6</span>, <span class="Constant">2</span>:address:duplex-list:character
<span class="Comment"># check structure like before</span>
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>copy <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">3</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">4</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">5</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">6</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">7</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">8</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">9</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">10</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">1</span>:address:duplex-list, <span class="Constant">2</span>:address:duplex-list
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>copy <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">3</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">4</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">5</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">6</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">7</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">8</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">9</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">10</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">2</span>:address:duplex-list:character
]
memory-should-contain [
<span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">5</span> <span class="Comment"># scanning next</span>
@@ -229,27 +219,27 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> inserting-after-start-of-duplex-list [
run [
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># 1 points to head of list</span>
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">3</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">4</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">5</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>insert-duplex <span class="Constant">6</span>, <span class="Constant">1</span>:address:duplex-list
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># 1 points to head of list</span>
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">3</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">4</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">5</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>insert-duplex <span class="Constant">6</span>, <span class="Constant">1</span>:address:duplex-list:character
<span class="Comment"># check structure like before</span>
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>copy <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">3</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">4</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">5</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">6</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">7</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">8</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">9</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">10</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">1</span>:address:duplex-list, <span class="Constant">2</span>:address:duplex-list
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>copy <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">3</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">4</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">5</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">6</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">7</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">8</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">9</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">10</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">2</span>:address:duplex-list:character
]
memory-should-contain [
<span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">5</span> <span class="Comment"># scanning next</span>
@@ -263,21 +253,20 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
]
-<span class="Comment"># l:address:duplex-list <- remove-duplex in:address:duplex-list</span>
<span class="Comment"># Removes 'in' from its surrounding list. Returns some valid pointer into the</span>
<span class="Comment"># rest of the list.</span>
<span class="Comment">#</span>
<span class="Comment"># Returns null if and only if list is empty. Beware: in that case any pointers</span>
<span class="Comment"># to the head are now invalid.</span>
-<span class="muRecipe">recipe</span> remove-duplex [
+<span class="muRecipe">recipe</span> remove-duplex in:address:duplex-list:_elem<span class="muRecipe"> -> </span>next-node:address:duplex-list:_elem [
<span class="Constant">local-scope</span>
- in:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
<span class="Comment"># if 'in' is null, return</span>
<span class="muControl">reply-unless</span> in, in
- next-node:address:duplex-list<span class="Special"> <- </span>get *in, <span class="Constant">next:offset</span>
- prev-node:address:duplex-list<span class="Special"> <- </span>get *in, <span class="Constant">prev:offset</span>
+ next-node:address:duplex-list:_elem<span class="Special"> <- </span>get *in, <span class="Constant">next:offset</span>
+ prev-node:address:duplex-list:_elem<span class="Special"> <- </span>get *in, <span class="Constant">prev:offset</span>
<span class="Comment"># null in's pointers</span>
- x:address:address:duplex-list<span class="Special"> <- </span>get-address *in, <span class="Constant">next:offset</span>
+ x:address:address:duplex-list:_elem<span class="Special"> <- </span>get-address *in, <span class="Constant">next:offset</span>
*x<span class="Special"> <- </span>copy <span class="Constant">0</span>
x<span class="Special"> <- </span>get-address *in, <span class="Constant">prev:offset</span>
*x<span class="Special"> <- </span>copy <span class="Constant">0</span>
@@ -301,22 +290,22 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> removing-from-duplex-list [
run [
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># 1 points to head of list</span>
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">3</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">4</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">5</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list <span class="Comment"># 2 points at second element</span>
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>remove-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">3</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">2</span>:address:duplex-list, <span class="Constant">0</span>
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># 1 points to head of list</span>
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">3</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">4</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">5</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list:character <span class="Comment"># 2 points at second element</span>
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>remove-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">3</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">2</span>:address:duplex-list:character, <span class="Constant">0</span>
<span class="Comment"># check structure like before</span>
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>copy <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">4</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">5</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">6</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">7</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">8</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">1</span>:address:duplex-list, <span class="Constant">2</span>:address:duplex-list
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>copy <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">4</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">5</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">6</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">7</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">8</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">2</span>:address:duplex-list:character
]
memory-should-contain [
<span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">0</span> <span class="Comment"># remove returned non-null</span>
@@ -330,21 +319,21 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> removing-from-start-of-duplex-list [
run [
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># 1 points to head of list</span>
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">3</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">4</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">5</span>, <span class="Constant">1</span>:address:duplex-list
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># 1 points to head of list</span>
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">3</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">4</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">5</span>, <span class="Constant">1</span>:address:duplex-list:character
<span class="Comment"># removing from head? return value matters.</span>
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>remove-duplex <span class="Constant">1</span>:address:duplex-list
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>remove-duplex <span class="Constant">1</span>:address:duplex-list:character
<span class="Comment"># check structure like before</span>
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>copy <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">3</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">4</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">5</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">6</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">7</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">1</span>:address:duplex-list, <span class="Constant">2</span>:address:duplex-list
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>copy <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">3</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">4</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">5</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">6</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">7</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">2</span>:address:duplex-list:character
]
memory-should-contain [
<span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">4</span> <span class="Comment"># scanning next, skipping deleted element</span>
@@ -357,24 +346,24 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> removing-from-end-of-duplex-list [
run [
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># 1 points to head of list</span>
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">3</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">4</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">5</span>, <span class="Constant">1</span>:address:duplex-list
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># 1 points to head of list</span>
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">3</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">4</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">5</span>, <span class="Constant">1</span>:address:duplex-list:character
<span class="Comment"># delete last element</span>
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>remove-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">3</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">2</span>:address:duplex-list, <span class="Constant">0</span>
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>remove-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">3</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">2</span>:address:duplex-list:character, <span class="Constant">0</span>
<span class="Comment"># check structure like before</span>
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>copy <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">4</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">5</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">6</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">7</span>:number<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">8</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">1</span>:address:duplex-list, <span class="Constant">2</span>:address:duplex-list
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>copy <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">4</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">5</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">6</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">7</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">8</span>:boolean<span class="Special"> <- </span>equal <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">2</span>:address:duplex-list:character
]
memory-should-contain [
<span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">0</span> <span class="Comment"># remove returned non-null</span>
@@ -388,11 +377,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> removing-from-singleton-list [
run [
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># 1 points to singleton list</span>
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">3</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>remove-duplex <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">3</span>:address:duplex-list<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:duplex-list, <span class="Constant">next:offset</span>
- <span class="Constant">4</span>:address:duplex-list<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:duplex-list, <span class="Constant">prev:offset</span>
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># 1 points to singleton list</span>
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">3</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>remove-duplex <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">next:offset</span>
+ <span class="Constant">4</span>:address:duplex-list:character<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">prev:offset</span>
]
memory-should-contain [
<span class="Constant">2</span><span class="Special"> <- </span><span class="Constant">0</span> <span class="Comment"># remove returned null</span>
@@ -405,51 +394,49 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># Remove values between 'start' and 'end' (both exclusive). Returns some valid</span>
<span class="Comment"># pointer into the rest of the list.</span>
<span class="Comment"># Also clear pointers back out from start/end for hygiene.</span>
-<span class="muRecipe">recipe</span> remove-duplex-between [
+<span class="muRecipe">recipe</span> remove-duplex-between start:address:duplex-list:_elem, end:address:duplex-list:_elem<span class="muRecipe"> -> </span>start:address:duplex-list:_elem [
<span class="Constant">local-scope</span>
- start:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- end:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- <span class="muControl">reply-unless</span> start, start
+ <span class="Constant">load-ingredients</span>
+ <span class="muControl">reply-unless</span> start
<span class="Comment"># start->next->prev = 0</span>
<span class="Comment"># start->next = end</span>
- next:address:address:duplex-list<span class="Special"> <- </span>get-address *start, <span class="Constant">next:offset</span>
+ next:address:address:duplex-list:_elem<span class="Special"> <- </span>get-address *start, <span class="Constant">next:offset</span>
nothing-to-delete?:boolean<span class="Special"> <- </span>equal *next, end
- <span class="muControl">reply-if</span> nothing-to-delete?, start
- prev:address:address:duplex-list<span class="Special"> <- </span>get-address **next, <span class="Constant">prev:offset</span>
+ <span class="muControl">reply-if</span> nothing-to-delete?
+ prev:address:address:duplex-list:_elem<span class="Special"> <- </span>get-address **next, <span class="Constant">prev:offset</span>
*prev<span class="Special"> <- </span>copy <span class="Constant">0</span>
*next<span class="Special"> <- </span>copy end
- <span class="muControl">reply-unless</span> end, start
+ <span class="muControl">reply-unless</span> end
<span class="Comment"># end->prev->next = 0</span>
<span class="Comment"># end->prev = start</span>
prev<span class="Special"> <- </span>get-address *end, <span class="Constant">prev:offset</span>
next<span class="Special"> <- </span>get-address **prev, <span class="Constant">next:offset</span>
*next<span class="Special"> <- </span>copy <span class="Constant">0</span>
*prev<span class="Special"> <- </span>copy start
- <span class="muControl">reply</span> start
]
<span class="muScenario">scenario</span> remove-range [
<span class="Comment"># construct a duplex list with six elements [13, 14, 15, 16, 17, 18]</span>
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># 1 points to singleton list</span>
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">18</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">17</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">16</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">15</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">14</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">13</span>, <span class="Constant">1</span>:address:duplex-list
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># 1 points to singleton list</span>
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">18</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">17</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">16</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">15</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">14</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">13</span>, <span class="Constant">1</span>:address:duplex-list:character
run [
<span class="Comment"># delete 16 onwards</span>
<span class="Comment"># first pointer: to the third element</span>
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list
- remove-duplex-between <span class="Constant">2</span>:address:duplex-list, <span class="Constant">0</span>
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>remove-duplex-between <span class="Constant">2</span>:address:duplex-list:character, <span class="Constant">0</span>
<span class="Comment"># now check the list</span>
- <span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:duplex-list, <span class="Constant">value:offset</span>
- <span class="Constant">5</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">6</span>:number<span class="Special"> <- </span>get *<span class="Constant">5</span>:address:duplex-list, <span class="Constant">value:offset</span>
- <span class="Constant">7</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">5</span>:address:duplex-list
- <span class="Constant">8</span>:number<span class="Special"> <- </span>get *<span class="Constant">7</span>:address:duplex-list, <span class="Constant">value:offset</span>
- <span class="Constant">9</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">7</span>:address:duplex-list
+ <span class="Constant">4</span>:character<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">value:offset</span>
+ <span class="Constant">5</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">6</span>:character<span class="Special"> <- </span>get *<span class="Constant">5</span>:address:duplex-list:character, <span class="Constant">value:offset</span>
+ <span class="Constant">7</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">5</span>:address:duplex-list:character
+ <span class="Constant">8</span>:character<span class="Special"> <- </span>get *<span class="Constant">7</span>:address:duplex-list:character, <span class="Constant">value:offset</span>
+ <span class="Constant">9</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">7</span>:address:duplex-list:character
]
memory-should-contain [
<span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">13</span>
@@ -461,30 +448,30 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> remove-range-to-end [
<span class="Comment"># construct a duplex list with six elements [13, 14, 15, 16, 17, 18]</span>
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># 1 points to singleton list</span>
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">18</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">17</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">16</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">15</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">14</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">13</span>, <span class="Constant">1</span>:address:duplex-list
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># 1 points to singleton list</span>
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">18</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">17</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">16</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">15</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">14</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">13</span>, <span class="Constant">1</span>:address:duplex-list:character
run [
<span class="Comment"># delete 15, 16 and 17</span>
<span class="Comment"># first pointer: to the third element</span>
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list:character
<span class="Comment"># second pointer: to the fifth element</span>
- <span class="Constant">3</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list
- <span class="Constant">3</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">3</span>:address:duplex-list
- <span class="Constant">3</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">3</span>:address:duplex-list
- <span class="Constant">3</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">3</span>:address:duplex-list
- remove-duplex-between <span class="Constant">2</span>:address:duplex-list, <span class="Constant">3</span>:address:duplex-list
+ <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
+ <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">3</span>:address:duplex-list:character
+ <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">3</span>:address:duplex-list:character
+ <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">3</span>:address:duplex-list:character
+ remove-duplex-between <span class="Constant">2</span>:address:duplex-list:character, <span class="Constant">3</span>:address:duplex-list:character
<span class="Comment"># now check the list</span>
- <span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:duplex-list, <span class="Constant">value:offset</span>
- <span class="Constant">5</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">6</span>:number<span class="Special"> <- </span>get *<span class="Constant">5</span>:address:duplex-list, <span class="Constant">value:offset</span>
- <span class="Constant">7</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">5</span>:address:duplex-list
- <span class="Constant">8</span>:number<span class="Special"> <- </span>get *<span class="Constant">7</span>:address:duplex-list, <span class="Constant">value:offset</span>
- <span class="Constant">9</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">7</span>:address:duplex-list
+ <span class="Constant">4</span>:character<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">value:offset</span>
+ <span class="Constant">5</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">6</span>:character<span class="Special"> <- </span>get *<span class="Constant">5</span>:address:duplex-list:character, <span class="Constant">value:offset</span>
+ <span class="Constant">7</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">5</span>:address:duplex-list:character
+ <span class="Constant">8</span>:character<span class="Special"> <- </span>get *<span class="Constant">7</span>:address:duplex-list:character, <span class="Constant">value:offset</span>
+ <span class="Constant">9</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">7</span>:address:duplex-list:character
]
memory-should-contain [
<span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">13</span>
@@ -496,19 +483,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> remove-range-empty [
<span class="Comment"># construct a duplex list with six elements [13, 14, 15, 16, 17, 18]</span>
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># 1 points to singleton list</span>
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">14</span>, <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">1</span>:address:duplex-list<span class="Special"> <- </span>push-duplex <span class="Constant">13</span>, <span class="Constant">1</span>:address:duplex-list
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># 1 points to singleton list</span>
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">14</span>, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">13</span>, <span class="Constant">1</span>:address:duplex-list:character
run [
<span class="Comment"># delete 16 onwards</span>
<span class="Comment"># first pointer: to the third element</span>
- <span class="Constant">2</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list
- remove-duplex-between <span class="Constant">1</span>:address:duplex-list, <span class="Constant">2</span>:address:duplex-list
+ <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list:character
+ remove-duplex-between <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">2</span>:address:duplex-list:character
<span class="Comment"># now check the list</span>
- <span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:duplex-list, <span class="Constant">value:offset</span>
- <span class="Constant">5</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list
- <span class="Constant">6</span>:number<span class="Special"> <- </span>get *<span class="Constant">5</span>:address:duplex-list, <span class="Constant">value:offset</span>
- <span class="Constant">7</span>:address:duplex-list<span class="Special"> <- </span>next-duplex <span class="Constant">5</span>:address:duplex-list
+ <span class="Constant">4</span>:character<span class="Special"> <- </span>get *<span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">value:offset</span>
+ <span class="Constant">5</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">6</span>:character<span class="Special"> <- </span>get *<span class="Constant">5</span>:address:duplex-list:character, <span class="Constant">value:offset</span>
+ <span class="Constant">7</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">5</span>:address:duplex-list:character
]
memory-should-contain [
<span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">13</span>
@@ -517,23 +504,21 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
]
-<span class="Comment"># l:address:duplex-list <- insert-duplex-range in:address:duplex-list, new:address:duplex-list</span>
<span class="Comment"># Inserts list beginning at 'new' after 'in'. Returns some pointer into the list.</span>
-<span class="muRecipe">recipe</span> insert-duplex-range [
+<span class="muRecipe">recipe</span> insert-duplex-range in:address:duplex-list:_elem, start:address:duplex-list:_elem<span class="muRecipe"> -> </span>in:address:duplex-list:_elem [
<span class="Constant">local-scope</span>
- in:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- start:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- <span class="muControl">reply-unless</span> in, in
- <span class="muControl">reply-unless</span> start, in
- end:address:duplex-list<span class="Special"> <- </span>copy start
+ <span class="Constant">load-ingredients</span>
+ <span class="muControl">reply-unless</span> in
+ <span class="muControl">reply-unless</span> start
+ end:address:duplex-list:_elem<span class="Special"> <- </span>copy start
<span class="Delimiter">{</span>
- next:address:duplex-list<span class="Special"> <- </span>next-duplex end
+ next:address:duplex-list:_elem<span class="Special"> <- </span>next-duplex end/insert-range
<span class="muControl">break-unless</span> next
end<span class="Special"> <- </span>copy next
<span class="muControl">loop</span>
<span class="Delimiter">}</span>
- next:address:duplex-list<span class="Special"> <- </span>next-duplex in
- dest:address:address:duplex-list<span class="Special"> <- </span>get-address *end, <span class="Constant">next:offset</span>
+ next:address:duplex-list:_elem<span class="Special"> <- </span>next-duplex in
+ dest:address:address:duplex-list:_elem<span class="Special"> <- </span>get-address *end, <span class="Constant">next:offset</span>
*dest<span class="Special"> <- </span>copy next
<span class="Delimiter">{</span>
<span class="muControl">break-unless</span> next
@@ -544,43 +529,39 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
*dest<span class="Special"> <- </span>copy start
dest<span class="Special"> <- </span>get-address *start, <span class="Constant">prev:offset</span>
*dest<span class="Special"> <- </span>copy in
- <span class="muControl">reply</span> in
]
-<span class="muRecipe">recipe</span> append-duplex [
+<span class="muRecipe">recipe</span> append-duplex in:address:duplex-list:_elem, new:address:duplex-list:_elem<span class="muRecipe"> -> </span>in:address:duplex-list:_elem [
<span class="Constant">local-scope</span>
- in:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- new:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- last:address:duplex-list<span class="Special"> <- </span>last-duplex in
- dest:address:address:duplex-list<span class="Special"> <- </span>get-address *last, <span class="Constant">next:offset</span>
+ <span class="Constant">load-ingredients</span>
+ last:address:duplex-list:_elem<span class="Special"> <- </span>last-duplex in
+ dest:address:address:duplex-list:_elem<span class="Special"> <- </span>get-address *last, <span class="Constant">next:offset</span>
*dest<span class="Special"> <- </span>copy new
- <span class="muControl">reply-unless</span> new, in/same-as-ingredient:<span class="Constant">0</span>
+ <span class="muControl">reply-unless</span> new
dest<span class="Special"> <- </span>get-address *new, <span class="Constant">prev:offset</span>
*dest<span class="Special"> <- </span>copy last
- <span class="muControl">reply</span> in/same-as-ingredient:<span class="Constant">0</span>
]
-<span class="muRecipe">recipe</span> last-duplex [
+<span class="muRecipe">recipe</span> last-duplex in:address:duplex-list:_elem<span class="muRecipe"> -> </span>result:address:duplex-list:_elem [
<span class="Constant">local-scope</span>
- in:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- result:address:duplex-list<span class="Special"> <- </span>copy in
+ <span class="Constant">load-ingredients</span>
+ result<span class="Special"> <- </span>copy in
<span class="Delimiter">{</span>
- next:address:duplex-list<span class="Special"> <- </span>next-duplex result
+ next:address:duplex-list:_elem<span class="Special"> <- </span>next-duplex result
<span class="muControl">break-unless</span> next
result<span class="Special"> <- </span>copy next
<span class="muControl">loop</span>
<span class="Delimiter">}</span>
- <span class="muControl">reply</span> result
]
<span class="Comment"># helper for debugging</span>
-<span class="muRecipe">recipe</span> dump-duplex-from [
+<span class="muRecipe">recipe</span> dump-duplex-from x:address:duplex-list:_elem [
<span class="Constant">local-scope</span>
- x:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
$print x, <span class="Constant">[: ]</span>
<span class="Delimiter">{</span>
<span class="muControl">break-unless</span> x
- c:character<span class="Special"> <- </span>get *x, <span class="Constant">value:offset</span>
+ c:_elem<span class="Special"> <- </span>get *x, <span class="Constant">value:offset</span>
$print c, <span class="Constant">[ ]</span>
x<span class="Special"> <- </span>next-duplex x
<span class="Delimiter">{</span>
@@ -593,6 +574,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">}</span>
$print <span class="Constant">10/newline</span>, <span class="Constant">[---]</span>, <span class="Constant">10/newline</span>
]
+
+<span class="muRecipe">recipe</span> force-specialization-duplex-list-character [
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>push-duplex <span class="Constant">2</span>:character, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">2</span>:character<span class="Special"> <- </span>first-duplex <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>next-duplex <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>prev-duplex <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>insert-duplex <span class="Constant">2</span>:character, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>remove-duplex <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>remove-duplex-between <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>insert-duplex-range <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>append-duplex <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">1</span>:address:duplex-list:character
+ <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> <- </span>last-duplex <span class="Constant">1</span>:address:duplex-list:character
+]
</pre>
</body>
</html>
diff --git a/html/066stream.mu.html b/html/066stream.mu.html
index 23a019f6..54e65159 100644
--- a/html/066stream.mu.html
+++ b/html/066stream.mu.html
@@ -13,12 +13,12 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
.muRecipe { color: #ff8700; }
.muData { color: #ffff00; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.Special { color: #ff6060; }
-.muControl { color: #c0a020; }
-->
</style>
@@ -68,7 +68,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muRecipe">recipe</span> end-of-stream? [
<span class="Constant">local-scope</span>
in:address:stream<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- idx:address:number<span class="Special"> <- </span>get *in, <span class="Constant">index:offset</span>
+ idx:number<span class="Special"> <- </span>get *in, <span class="Constant">index:offset</span>
s:address:array:character<span class="Special"> <- </span>get *in, <span class="Constant">data:offset</span>
len:number<span class="Special"> <- </span>length *s
result:boolean<span class="Special"> <- </span>greater-or-equal idx, len
diff --git a/html/070display.cc.html b/html/070display.cc.html
index 61a6395e..8fb46c4d 100644
--- a/html/070display.cc.html
+++ b/html/070display.cc.html
@@ -41,7 +41,11 @@ bool Autodisplay = <span class="Constant">true</span><span class="Delimiter">;</
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
OPEN_CONSOLE<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"open-console"</span>] = OPEN_CONSOLE<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"open-console"</span><span class="Delimiter">,</span> OPEN_CONSOLE<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case OPEN_CONSOLE: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case OPEN_CONSOLE: <span class="Delimiter">{</span>
tb_init<span class="Delimiter">();</span>
@@ -50,16 +54,20 @@ case OPEN_CONSOLE: <span class="Delimiter">{</span>
long long int height = tb_height<span class="Delimiter">();</span>
if <span class="Delimiter">(</span>width > <span class="Constant">222</span> || height > <span class="Constant">222</span><span class="Delimiter">)</span> tb_shutdown<span class="Delimiter">();</span>
if <span class="Delimiter">(</span>width > <span class="Constant">222</span><span class="Delimiter">)</span>
- raise << <span class="Constant">"sorry, mu doesn't support windows wider than 222 characters. Please resize your window.</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"sorry, mu doesn't support windows wider than 222 characters. Please resize your window.</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
if <span class="Delimiter">(</span>height > <span class="Constant">222</span><span class="Delimiter">)</span>
- raise << <span class="Constant">"sorry, mu doesn't support windows taller than 222 characters. Please resize your window.</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"sorry, mu doesn't support windows taller than 222 characters. Please resize your window.</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
CLOSE_CONSOLE<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"close-console"</span>] = CLOSE_CONSOLE<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"close-console"</span><span class="Delimiter">,</span> CLOSE_CONSOLE<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case CLOSE_CONSOLE: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case CLOSE_CONSOLE: <span class="Delimiter">{</span>
tb_shutdown<span class="Delimiter">();</span>
@@ -72,7 +80,11 @@ tb_shutdown<span class="Delimiter">();</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
CLEAR_DISPLAY<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"clear-display"</span>] = CLEAR_DISPLAY<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"clear-display"</span><span class="Delimiter">,</span> CLEAR_DISPLAY<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case CLEAR_DISPLAY: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case CLEAR_DISPLAY: <span class="Delimiter">{</span>
tb_clear<span class="Delimiter">();</span>
@@ -83,7 +95,11 @@ case CLEAR_DISPLAY: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
SYNC_DISPLAY<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"sync-display"</span>] = SYNC_DISPLAY<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"sync-display"</span><span class="Delimiter">,</span> SYNC_DISPLAY<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case SYNC_DISPLAY: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case SYNC_DISPLAY: <span class="Delimiter">{</span>
tb_sync<span class="Delimiter">();</span>
@@ -93,7 +109,11 @@ case SYNC_DISPLAY: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
CLEAR_LINE_ON_DISPLAY<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"clear-line-on-display"</span>] = CLEAR_LINE_ON_DISPLAY<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"clear-line-on-display"</span><span class="Delimiter">,</span> CLEAR_LINE_ON_DISPLAY<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case CLEAR_LINE_ON_DISPLAY: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case CLEAR_LINE_ON_DISPLAY: <span class="Delimiter">{</span>
long long int width = tb_width<span class="Delimiter">();</span>
@@ -108,35 +128,43 @@ case CLEAR_LINE_ON_DISPLAY: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
PRINT_CHARACTER_TO_DISPLAY<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"print-character-to-display"</span>] = PRINT_CHARACTER_TO_DISPLAY<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"print-character-to-display"</span><span class="Delimiter">,</span> PRINT_CHARACTER_TO_DISPLAY<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case PRINT_CHARACTER_TO_DISPLAY: <span class="Delimiter">{</span>
- int h=tb_height<span class="Delimiter">(),</span> w=tb_width<span class="Delimiter">();</span>
- long long int height = <span class="Delimiter">(</span>h >= <span class="Constant">0</span><span class="Delimiter">)</span> ? h : <span class="Constant">0</span><span class="Delimiter">;</span>
- long long int width = <span class="Delimiter">(</span>w >= <span class="Constant">0</span><span class="Delimiter">)</span> ? w : <span class="Constant">0</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'print-character-to-display' requires at least one ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'print-character-to-display' requires at least one ingredient, but got "</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>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'print-character-to-display' should be a character, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'print-character-to-display' should be a character, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"second ingredient of 'print-character-to-display' should be a foreground color number, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"third ingredient of 'print-character-to-display' should be a background color number, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case PRINT_CHARACTER_TO_DISPLAY: <span class="Delimiter">{</span>
+ int h=tb_height<span class="Delimiter">(),</span> w=tb_width<span class="Delimiter">();</span>
+ long long int height = <span class="Delimiter">(</span>h >= <span class="Constant">0</span><span class="Delimiter">)</span> ? h : <span class="Constant">0</span><span class="Delimiter">;</span>
+ long long int width = <span class="Delimiter">(</span>w >= <span class="Constant">0</span><span class="Delimiter">)</span> ? w : <span class="Constant">0</span><span class="Delimiter">;</span>
long long int c = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
int color = TB_BLACK<span class="Delimiter">;</span>
if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": second ingredient of 'print-character-to-display' should be a foreground color number, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
color = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
<span class="Delimiter">}</span>
int bg_color = TB_BLACK<span class="Delimiter">;</span>
if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": third ingredient of 'print-character-to-display' should be a background color number, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
bg_color = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
if <span class="Delimiter">(</span>bg_color == <span class="Constant">0</span><span class="Delimiter">)</span> bg_color = TB_BLACK<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -170,7 +198,11 @@ case PRINT_CHARACTER_TO_DISPLAY: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
CURSOR_POSITION_ON_DISPLAY<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"cursor-position-on-display"</span>] = CURSOR_POSITION_ON_DISPLAY<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"cursor-position-on-display"</span><span class="Delimiter">,</span> CURSOR_POSITION_ON_DISPLAY<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case CURSOR_POSITION_ON_DISPLAY: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case CURSOR_POSITION_ON_DISPLAY: <span class="Delimiter">{</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">);</span>
@@ -182,22 +214,26 @@ case CURSOR_POSITION_ON_DISPLAY: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
MOVE_CURSOR_ON_DISPLAY<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"move-cursor-on-display"</span>] = MOVE_CURSOR_ON_DISPLAY<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"move-cursor-on-display"</span><span class="Delimiter">,</span> MOVE_CURSOR_ON_DISPLAY<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case MOVE_CURSOR_ON_DISPLAY: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'move-cursor-on-display' requires two ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'move-cursor-on-display' requires two ingredients, but got "</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>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'move-cursor-on-display' should be a row number, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'move-cursor-on-display' should be a row number, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- Display_row = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": second ingredient of 'move-cursor-on-display' should be a column number, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_number<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"second ingredient of 'move-cursor-on-display' should be a column number, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="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">:(before "End Primitive Recipe Implementations")</span>
+case MOVE_CURSOR_ON_DISPLAY: <span class="Delimiter">{</span>
+ Display_row = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
Display_column = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
tb_set_cursor<span class="Delimiter">(</span>Display_column<span class="Delimiter">,</span> Display_row<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>Autodisplay<span class="Delimiter">)</span> tb_present<span class="Delimiter">();</span>
@@ -207,7 +243,11 @@ case MOVE_CURSOR_ON_DISPLAY: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
MOVE_CURSOR_DOWN_ON_DISPLAY<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"move-cursor-down-on-display"</span>] = MOVE_CURSOR_DOWN_ON_DISPLAY<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"move-cursor-down-on-display"</span><span class="Delimiter">,</span> MOVE_CURSOR_DOWN_ON_DISPLAY<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case MOVE_CURSOR_DOWN_ON_DISPLAY: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case MOVE_CURSOR_DOWN_ON_DISPLAY: <span class="Delimiter">{</span>
int h=tb_height<span class="Delimiter">();</span>
@@ -223,7 +263,11 @@ case MOVE_CURSOR_DOWN_ON_DISPLAY: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
MOVE_CURSOR_UP_ON_DISPLAY<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"move-cursor-up-on-display"</span>] = MOVE_CURSOR_UP_ON_DISPLAY<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"move-cursor-up-on-display"</span><span class="Delimiter">,</span> MOVE_CURSOR_UP_ON_DISPLAY<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case MOVE_CURSOR_UP_ON_DISPLAY: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case MOVE_CURSOR_UP_ON_DISPLAY: <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>Display_row > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -237,7 +281,11 @@ case MOVE_CURSOR_UP_ON_DISPLAY: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
MOVE_CURSOR_RIGHT_ON_DISPLAY<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"move-cursor-right-on-display"</span>] = MOVE_CURSOR_RIGHT_ON_DISPLAY<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"move-cursor-right-on-display"</span><span class="Delimiter">,</span> MOVE_CURSOR_RIGHT_ON_DISPLAY<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case MOVE_CURSOR_RIGHT_ON_DISPLAY: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case MOVE_CURSOR_RIGHT_ON_DISPLAY: <span class="Delimiter">{</span>
int w=tb_width<span class="Delimiter">();</span>
@@ -253,7 +301,11 @@ case MOVE_CURSOR_RIGHT_ON_DISPLAY: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
MOVE_CURSOR_LEFT_ON_DISPLAY<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"move-cursor-left-on-display"</span>] = MOVE_CURSOR_LEFT_ON_DISPLAY<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"move-cursor-left-on-display"</span><span class="Delimiter">,</span> MOVE_CURSOR_LEFT_ON_DISPLAY<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case MOVE_CURSOR_LEFT_ON_DISPLAY: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case MOVE_CURSOR_LEFT_ON_DISPLAY: <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>Display_column > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -267,7 +319,11 @@ case MOVE_CURSOR_LEFT_ON_DISPLAY: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
DISPLAY_WIDTH<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"display-width"</span>] = DISPLAY_WIDTH<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"display-width"</span><span class="Delimiter">,</span> DISPLAY_WIDTH<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case DISPLAY_WIDTH: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case DISPLAY_WIDTH: <span class="Delimiter">{</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
@@ -278,7 +334,11 @@ case DISPLAY_WIDTH: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
DISPLAY_HEIGHT<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"display-height"</span>] = DISPLAY_HEIGHT<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"display-height"</span><span class="Delimiter">,</span> DISPLAY_HEIGHT<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case DISPLAY_HEIGHT: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case DISPLAY_HEIGHT: <span class="Delimiter">{</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
@@ -289,7 +349,11 @@ case DISPLAY_HEIGHT: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
HIDE_CURSOR_ON_DISPLAY<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"hide-cursor-on-display"</span>] = HIDE_CURSOR_ON_DISPLAY<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"hide-cursor-on-display"</span><span class="Delimiter">,</span> HIDE_CURSOR_ON_DISPLAY<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case HIDE_CURSOR_ON_DISPLAY: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case HIDE_CURSOR_ON_DISPLAY: <span class="Delimiter">{</span>
tb_set_cursor<span class="Delimiter">(</span>TB_HIDE_CURSOR<span class="Delimiter">,</span> TB_HIDE_CURSOR<span class="Delimiter">);</span>
@@ -299,7 +363,11 @@ case HIDE_CURSOR_ON_DISPLAY: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
SHOW_CURSOR_ON_DISPLAY<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"show-cursor-on-display"</span>] = SHOW_CURSOR_ON_DISPLAY<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"show-cursor-on-display"</span><span class="Delimiter">,</span> SHOW_CURSOR_ON_DISPLAY<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case SHOW_CURSOR_ON_DISPLAY: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case SHOW_CURSOR_ON_DISPLAY: <span class="Delimiter">{</span>
tb_set_cursor<span class="Delimiter">(</span>Display_row<span class="Delimiter">,</span> Display_column<span class="Delimiter">);</span>
@@ -309,7 +377,11 @@ case SHOW_CURSOR_ON_DISPLAY: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
HIDE_DISPLAY<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"hide-display"</span>] = HIDE_DISPLAY<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"hide-display"</span><span class="Delimiter">,</span> HIDE_DISPLAY<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case HIDE_DISPLAY: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case HIDE_DISPLAY: <span class="Delimiter">{</span>
Autodisplay = <span class="Constant">false</span><span class="Delimiter">;</span>
@@ -319,7 +391,11 @@ case HIDE_DISPLAY: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
SHOW_DISPLAY<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"show-display"</span>] = SHOW_DISPLAY<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"show-display"</span><span class="Delimiter">,</span> SHOW_DISPLAY<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case SHOW_DISPLAY: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case SHOW_DISPLAY: <span class="Delimiter">{</span>
Autodisplay = <span class="Constant">true</span><span class="Delimiter">;</span>
@@ -332,7 +408,11 @@ case SHOW_DISPLAY: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
WAIT_FOR_SOME_INTERACTION<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"wait-for-some-interaction"</span>] = WAIT_FOR_SOME_INTERACTION<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"wait-for-some-interaction"</span><span class="Delimiter">,</span> WAIT_FOR_SOME_INTERACTION<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case WAIT_FOR_SOME_INTERACTION: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case WAIT_FOR_SOME_INTERACTION: <span class="Delimiter">{</span>
tb_event event<span class="Delimiter">;</span>
@@ -343,7 +423,11 @@ case WAIT_FOR_SOME_INTERACTION: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
CHECK_FOR_INTERACTION<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"check-for-interaction"</span>] = CHECK_FOR_INTERACTION<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"check-for-interaction"</span><span class="Delimiter">,</span> CHECK_FOR_INTERACTION<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case CHECK_FOR_INTERACTION: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case CHECK_FOR_INTERACTION: <span class="Delimiter">{</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">);</span> <span class="Comment">// result and status</span>
@@ -406,7 +490,11 @@ case CHECK_FOR_INTERACTION: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
INTERACTIONS_LEFT<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"interactions-left?"</span>] = INTERACTIONS_LEFT<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"interactions-left?"</span><span class="Delimiter">,</span> INTERACTIONS_LEFT<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case INTERACTIONS_LEFT: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case INTERACTIONS_LEFT: <span class="Delimiter">{</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
@@ -419,7 +507,11 @@ case INTERACTIONS_LEFT: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
CLEAR_DISPLAY_FROM<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"clear-display-from"</span>] = CLEAR_DISPLAY_FROM<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"clear-display-from"</span><span class="Delimiter">,</span> CLEAR_DISPLAY_FROM<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case CLEAR_DISPLAY_FROM: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case CLEAR_DISPLAY_FROM: <span class="Delimiter">{</span>
<span class="Comment">// todo: error checking</span>
diff --git a/html/071print.mu.html b/html/071print.mu.html
index c4334f55..444a8359 100644
--- a/html/071print.mu.html
+++ b/html/071print.mu.html
@@ -13,14 +13,14 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
.muRecipe { color: #ff8700; }
-.muData { color: #ffff00; }
.muScenario { color: #00af00; }
+.muData { color: #ffff00; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.Special { color: #ff6060; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
-->
</style>
@@ -81,8 +81,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">break-if</span> done?
curr:address:screen-cell<span class="Special"> <- </span>index-address *buf, i
curr-content:address:character<span class="Special"> <- </span>get-address *curr, <span class="Constant">contents:offset</span>
- *curr-content<span class="Special"> <- </span>copy <span class="Constant">[ ]</span>
- curr-color:address:character<span class="Special"> <- </span>get-address *curr, <span class="Constant">color:offset</span>
+ *curr-content<span class="Special"> <- </span>copy <span class="Constant">0/empty</span>
+ curr-color:address:number<span class="Special"> <- </span>get-address *curr, <span class="Constant">color:offset</span>
*curr-color<span class="Special"> <- </span>copy <span class="Constant">7/white</span>
i<span class="Special"> <- </span>add i, <span class="Constant">1</span>
<span class="muControl">loop</span>
@@ -558,7 +558,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muRecipe">recipe</span> cursor-to-next-line [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
screen<span class="Special"> <- </span>cursor-down screen
screen<span class="Special"> <- </span>cursor-to-start-of-line screen
<span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>
@@ -594,7 +594,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muRecipe">recipe</span> hide-cursor [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
<span class="Comment"># if x exists (not real display), do nothing</span>
<span class="Delimiter">{</span>
<span class="muControl">break-unless</span> screen
@@ -607,7 +607,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muRecipe">recipe</span> show-cursor [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
<span class="Comment"># if x exists (not real display), do nothing</span>
<span class="Delimiter">{</span>
<span class="muControl">break-unless</span> screen
@@ -620,7 +620,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muRecipe">recipe</span> hide-screen [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
<span class="Comment"># if x exists (not real display), do nothing</span>
<span class="Comment"># todo: help test this</span>
<span class="Delimiter">{</span>
@@ -634,7 +634,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muRecipe">recipe</span> show-screen [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
<span class="Comment"># if x exists (not real display), do nothing</span>
<span class="Comment"># todo: help test this</span>
<span class="Delimiter">{</span>
@@ -648,7 +648,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muRecipe">recipe</span> print-string [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
s:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
color:number, color-found?:boolean<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
<span class="Delimiter">{</span>
@@ -697,7 +697,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muRecipe">recipe</span> print-integer [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
n:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
color:number, color-found?:boolean<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
<span class="Delimiter">{</span>
diff --git a/html/072scenario_screen.cc.html b/html/072scenario_screen.cc.html
index 5100c44c..ade20fff 100644
--- a/html/072scenario_screen.cc.html
+++ b/html/072scenario_screen.cc.html
@@ -13,8 +13,8 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
-.traceAbsent { color: #c00000; }
.traceContains { color: #008000; }
+.traceAbsent { color: #c00000; }
.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
@@ -43,7 +43,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
scenario screen-in-scenario [
assume-screen <span class="Constant">5</span>/width<span class="Delimiter">,</span> <span class="Constant">3</span>/height
run [
- screen:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">97</span> <span class="Comment"># 'a'</span>
+ screen:address:screen<span class="Special"> <- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span> <span class="Comment"># 'a'</span>
]
screen-should-contain [
<span class="Comment"># 01234</span>
@@ -57,8 +57,8 @@ scenario screen-in-scenario [
scenario screen-in-scenario-unicode-color [
assume-screen <span class="Constant">5</span>/width<span class="Delimiter">,</span> <span class="Constant">3</span>/height
run [
- screen:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">955</span>/greek-small-lambda<span class="Delimiter">,</span> <span class="Constant">1</span>/red
- screen:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">97</span>/a
+ screen:address:screen<span class="Special"> <- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">955</span>/greek-small-lambda<span class="Delimiter">,</span> <span class="Constant">1</span>/red
+ screen:address:screen<span class="Special"> <- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span>/a
]
screen-should-contain [
<span class="Comment"># 01234</span>
@@ -73,8 +73,8 @@ scenario screen-in-scenario-unicode-color [
scenario screen-in-scenario-color [
assume-screen <span class="Constant">5</span>/width<span class="Delimiter">,</span> <span class="Constant">3</span>/height
run [
- screen:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">955</span>/greek-small-lambda<span class="Delimiter">,</span> <span class="Constant">1</span>/red
- screen:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">97</span>/a<span class="Delimiter">,</span> <span class="Constant">7</span>/white
+ screen:address:screen<span class="Special"> <- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">955</span>/greek-small-lambda<span class="Delimiter">,</span> <span class="Constant">1</span>/red
+ screen:address:screen<span class="Special"> <- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span>/a<span class="Delimiter">,</span> <span class="Constant">7</span>/white
]
<span class="Comment"># screen-should-contain shows everything</span>
screen-should-contain [
@@ -102,11 +102,11 @@ scenario screen-in-scenario-color [
<span class="Delimiter">:(scenario screen_in_scenario_error)</span>
<span class="Special">% Scenario_testing_scenario = true;</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
scenario screen-in-scenario-error [
assume-screen <span class="Constant">5</span>/width<span class="Delimiter">,</span> <span class="Constant">3</span>/height
run [
- screen:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">97</span> <span class="Comment"># 'a'</span>
+ screen:address:screen<span class="Special"> <- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span> <span class="Comment"># 'a'</span>
]
screen-should-contain [
<span class="Comment"># 01234</span>
@@ -115,16 +115,16 @@ scenario screen-in-scenario-error [
<span class="Delimiter">.</span> <span class="Delimiter">.</span>
]
]
-<span class="traceContains">+warn: expected screen location (0, 0) to contain 98 ('b') instead of 97 ('a')</span>
+<span class="traceContains">+error: expected screen location (0, 0) to contain 98 ('b') instead of 97 ('a')</span>
<span class="Delimiter">:(scenario screen_in_scenario_color_error)</span>
<span class="Special">% Scenario_testing_scenario = true;</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
<span class="Comment"># screen-should-contain can check unicode characters in the fake screen</span>
scenario screen-in-scenario-color [
assume-screen <span class="Constant">5</span>/width<span class="Delimiter">,</span> <span class="Constant">3</span>/height
run [
- screen:address<span class="Special"> <- </span>print-character screen:address<span class="Delimiter">,</span> <span class="Constant">97</span>/a<span class="Delimiter">,</span> <span class="Constant">1</span>/red
+ screen:address:screen<span class="Special"> <- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span>/a<span class="Delimiter">,</span> <span class="Constant">1</span>/red
]
screen-should-contain-in-color <span class="Constant">2</span>/green<span class="Delimiter">,</span> [
<span class="Comment"># 01234</span>
@@ -133,21 +133,21 @@ scenario screen-in-scenario-color [
<span class="Delimiter">.</span> <span class="Delimiter">.</span>
]
]
-<span class="traceContains">+warn: expected screen location (0, 0) to be in color 2 instead of 1</span>
+<span class="traceContains">+error: expected screen location (0, 0) to be in color 2 instead of 1</span>
<span class="Comment">//: allow naming just for 'screen'</span>
<span class="Delimiter">:(before "End is_special_name Cases")</span>
if <span class="Delimiter">(</span>s == <span class="Constant">"screen"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
<span class="Delimiter">:(scenarios run)</span>
-<span class="Delimiter">:(scenario convert_names_does_not_warn_when_mixing_special_names_and_numeric_locations)</span>
+<span class="Delimiter">:(scenario convert_names_does_not_fail_when_mixing_special_names_and_numeric_locations)</span>
<span class="Special">% Scenario_testing_scenario = true;</span>
-<span class="Special">% Hide_warnings = true;</span>
+<span class="Special">% Hide_errors = true;</span>
recipe main [
screen:number<span class="Special"> <- </span>copy <span class="Constant">1</span>:number
]
-<span class="traceAbsent">-warn: mixing variable names and numeric addresses in main</span>
-$warn: <span class="Constant">0</span>
+<span class="traceAbsent">-error: mixing variable names and numeric addresses in main</span>
+$error: <span class="Constant">0</span>
<span class="Delimiter">:(scenarios run_mu_scenario)</span>
<span class="Delimiter">:(before "End Globals")</span>
@@ -171,15 +171,13 @@ const long long int SCREEN = Next_predefined_global_for_scenarios++<span class="
<span class="Delimiter">:(before "End Special Scenario Variable Names(r)")</span>
Name[r][<span class="Constant">"screen"</span>] = SCREEN<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Rewrite Instruction(curr)")</span>
+<span class="Delimiter">:(before "End Rewrite Instruction(curr, recipe result)")</span>
<span class="Comment">// rewrite `assume-screen width, height` to</span>
-<span class="Comment">// `screen:address <- new-fake-screen width, height`</span>
+<span class="Comment">// `screen:address:screen <- new-fake-screen width, height`</span>
if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"assume-screen"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- curr<span class="Delimiter">.</span>operation = Recipe_ordinal[<span class="Constant">"new-fake-screen"</span>]<span class="Delimiter">;</span>
curr<span class="Delimiter">.</span>name = <span class="Constant">"new-fake-screen"</span><span class="Delimiter">;</span>
- assert<span class="Delimiter">(</span>curr<span class="Delimiter">.</span>operation<span class="Delimiter">);</span>
assert<span class="Delimiter">(</span>curr<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<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">"screen:address"</span><span class="Delimiter">));</span>
+ curr<span class="Delimiter">.</span>products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span><span class="Constant">"screen:address:screen"</span><span class="Delimiter">));</span>
curr<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>set_value<span class="Delimiter">(</span>SCREEN<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
@@ -187,7 +185,11 @@ if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
SCREEN_SHOULD_CONTAIN<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"screen-should-contain"</span>] = SCREEN_SHOULD_CONTAIN<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"screen-should-contain"</span><span class="Delimiter">,</span> SCREEN_SHOULD_CONTAIN<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case SCREEN_SHOULD_CONTAIN: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case SCREEN_SHOULD_CONTAIN: <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
@@ -198,7 +200,11 @@ case SCREEN_SHOULD_CONTAIN: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
SCREEN_SHOULD_CONTAIN_IN_COLOR<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"screen-should-contain-in-color"</span>] = SCREEN_SHOULD_CONTAIN_IN_COLOR<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"screen-should-contain-in-color"</span><span class="Delimiter">,</span> SCREEN_SHOULD_CONTAIN_IN_COLOR<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case SCREEN_SHOULD_CONTAIN_IN_COLOR: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case SCREEN_SHOULD_CONTAIN_IN_COLOR: <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
@@ -223,16 +229,16 @@ struct raw_string_stream <span class="Delimiter">{</span>
<span class="Delimiter">:(code)</span>
void check_screen<span class="Delimiter">(</span>const string& expected_contents<span class="Delimiter">,</span> const int color<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- assert<span class="Delimiter">(</span>!Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>default_space<span class="Delimiter">);</span> <span class="Comment">// not supported</span>
- long long int screen_location = Memory[SCREEN]<span class="Delimiter">;</span>
- int data_offset = find_element_name<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"screen"</span>]<span class="Delimiter">,</span> <span class="Constant">"data"</span><span class="Delimiter">);</span>
+ assert<span class="Delimiter">(</span>!current_call<span class="Delimiter">().</span>default_space<span class="Delimiter">);</span> <span class="Comment">// not supported</span>
+ long long int screen_location = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> SCREEN<span class="Delimiter">);</span>
+ int data_offset = find_element_name<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"screen"</span><span class="Delimiter">),</span> <span class="Constant">"data"</span><span class="Delimiter">,</span> <span class="Constant">""</span><span class="Delimiter">);</span>
assert<span class="Delimiter">(</span>data_offset >= <span class="Constant">0</span><span class="Delimiter">);</span>
long long int screen_data_location = screen_location+data_offset<span class="Delimiter">;</span> <span class="Comment">// type: address:array:character</span>
- long long int screen_data_start = Memory[screen_data_location]<span class="Delimiter">;</span> <span class="Comment">// type: array:character</span>
- int width_offset = find_element_name<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"screen"</span>]<span class="Delimiter">,</span> <span class="Constant">"num-columns"</span><span class="Delimiter">);</span>
- long long int screen_width = Memory[screen_location+width_offset]<span class="Delimiter">;</span>
- int height_offset = find_element_name<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"screen"</span>]<span class="Delimiter">,</span> <span class="Constant">"num-rows"</span><span class="Delimiter">);</span>
- long long int screen_height = Memory[screen_location+height_offset]<span class="Delimiter">;</span>
+ long long int screen_data_start = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> screen_data_location<span class="Delimiter">);</span> <span class="Comment">// type: array:character</span>
+ int width_offset = find_element_name<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"screen"</span><span class="Delimiter">),</span> <span class="Constant">"num-columns"</span><span class="Delimiter">,</span> <span class="Constant">""</span><span class="Delimiter">);</span>
+ long long int screen_width = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> screen_location+width_offset<span class="Delimiter">);</span>
+ int height_offset = find_element_name<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"screen"</span><span class="Delimiter">),</span> <span class="Constant">"num-rows"</span><span class="Delimiter">,</span> <span class="Constant">""</span><span class="Delimiter">);</span>
+ long long int screen_height = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> screen_location+height_offset<span class="Delimiter">);</span>
raw_string_stream cursor<span class="Delimiter">(</span>expected_contents<span class="Delimiter">);</span>
<span class="Comment">// todo: too-long expected_contents should fail</span>
long long int addr = screen_data_start+<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Comment">// skip length</span>
@@ -243,21 +249,21 @@ void check_screen<span class="Delimiter">(</span>const string& expected_cont
for <span class="Delimiter">(</span>long long int column = <span class="Constant">0</span><span class="Delimiter">;</span> column < screen_width<span class="Delimiter">;</span> ++column<span class="Delimiter">,</span> addr+= <span class="Comment">/*</span><span class="Comment">size of screen-cell</span><span class="Comment">*/</span><span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
const int cell_color_offset = <span class="Constant">1</span><span class="Delimiter">;</span>
uint32_t curr = cursor<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
- if <span class="Delimiter">(</span>Memory[addr] == <span class="Constant">0</span> && isspace<span class="Delimiter">(</span>curr<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>curr == <span class="Constant">' '</span> && color != -<span class="Constant">1</span> && color != Memory[addr+cell_color_offset]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr<span class="Delimiter">)</span> == <span class="Constant">0</span> && isspace<span class="Delimiter">(</span>curr<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>curr == <span class="Constant">' '</span> && color != -<span class="Constant">1</span> && color != get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr+cell_color_offset<span class="Delimiter">))</span> <span class="Delimiter">{</span>
<span class="Comment">// filter out other colors</span>
<span class="Identifier">continue</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>Memory[addr] != <span class="Constant">0</span> && Memory[addr] == curr<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>color == -<span class="Constant">1</span> || color == Memory[addr+cell_color_offset]<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr<span class="Delimiter">)</span> != <span class="Constant">0</span> && Memory[addr] == curr<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>color == -<span class="Constant">1</span> || color == get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr+cell_color_offset<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
<span class="Comment">// contents match but color is off</span>
if <span class="Delimiter">(</span>Current_scenario && !Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Comment">// genuine test in a mu file</span>
- raise << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span> << Current_scenario<span class="Delimiter">-></span>name << <span class="Constant">": expected screen location ("</span> << row << <span class="Constant">", "</span> << column << <span class="Constant">", address "</span> << addr << <span class="Constant">", value "</span> << Memory[addr] << <span class="Constant">") to be in color "</span> << color << <span class="Constant">" instead of "</span> << Memory[addr+cell_color_offset] << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span> << Current_scenario<span class="Delimiter">-></span>name << <span class="Constant">": expected screen location ("</span> << row << <span class="Constant">", "</span> << column << <span class="Constant">", address "</span> << addr << <span class="Constant">", value "</span> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr<span class="Delimiter">))</span> << <span class="Constant">") to be in color "</span> << color << <span class="Constant">" instead of "</span> << no_scientific<span class="Delimiter">(</span>Memory[addr+cell_color_offset]<span class="Delimiter">)</span> << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
else <span class="Delimiter">{</span>
<span class="Comment">// just testing check_screen</span>
- raise << <span class="Constant">"expected screen location ("</span> << row << <span class="Constant">", "</span> << column << <span class="Constant">") to be in color "</span> << color << <span class="Constant">" instead of "</span> << Memory[addr+cell_color_offset] << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"expected screen location ("</span> << row << <span class="Constant">", "</span> << column << <span class="Constant">") to be in color "</span> << color << <span class="Constant">" instead of "</span> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr+cell_color_offset<span class="Delimiter">))</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
if <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span>
Passed = <span class="Constant">false</span><span class="Delimiter">;</span>
@@ -267,26 +273,28 @@ void check_screen<span class="Delimiter">(</span>const string& expected_cont
<span class="Delimiter">}</span>
<span class="Comment">// really a mismatch</span>
- <span class="Comment">// can't print multi-byte unicode characters in warnings just yet. not very useful for debugging anyway.</span>
+ <span class="Comment">// can't print multi-byte unicode characters in errors just yet. not very useful for debugging anyway.</span>
char expected_pretty[<span class="Constant">10</span>] = <span class="Delimiter">{</span><span class="Constant">0</span><span class="Delimiter">};</span>
if <span class="Delimiter">(</span>curr < <span class="Constant">256</span> && !iscntrl<span class="Delimiter">(</span>curr<span class="Delimiter">))</span> <span class="Delimiter">{</span>
<span class="Comment">// " ('<curr>')"</span>
expected_pretty[<span class="Constant">0</span>] = <span class="Constant">' '</span><span class="Delimiter">,</span> expected_pretty[<span class="Constant">1</span>] = <span class="Constant">'('</span><span class="Delimiter">,</span> expected_pretty[<span class="Constant">2</span>] = <span class="cSpecial">'\''</span><span class="Delimiter">,</span> expected_pretty[<span class="Constant">3</span>] = static_cast<unsigned char><span class="Delimiter">(</span>curr<span class="Delimiter">),</span> expected_pretty[<span class="Constant">4</span>] = <span class="cSpecial">'\''</span><span class="Delimiter">,</span> expected_pretty[<span class="Constant">5</span>] = <span class="Constant">')'</span><span class="Delimiter">,</span> expected_pretty[<span class="Constant">6</span>] = <span class="cSpecial">'\0'</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
char actual_pretty[<span class="Constant">10</span>] = <span class="Delimiter">{</span><span class="Constant">0</span><span class="Delimiter">};</span>
- if <span class="Delimiter">(</span>Memory[addr] < <span class="Constant">256</span> && !iscntrl<span class="Delimiter">(</span>Memory[addr]<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr<span class="Delimiter">)</span> < <span class="Constant">256</span> && !iscntrl<span class="Delimiter">(</span>Memory[addr]<span class="Delimiter">))</span> <span class="Delimiter">{</span>
<span class="Comment">// " ('<curr>')"</span>
- actual_pretty[<span class="Constant">0</span>] = <span class="Constant">' '</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">1</span>] = <span class="Constant">'('</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">2</span>] = <span class="cSpecial">'\''</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">3</span>] = static_cast<unsigned char><span class="Delimiter">(</span>Memory[addr]<span class="Delimiter">),</span> actual_pretty[<span class="Constant">4</span>] = <span class="cSpecial">'\''</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">5</span>] = <span class="Constant">')'</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">6</span>] = <span class="cSpecial">'\0'</span><span class="Delimiter">;</span>
+ actual_pretty[<span class="Constant">0</span>] = <span class="Constant">' '</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">1</span>] = <span class="Constant">'('</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">2</span>] = <span class="cSpecial">'\''</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">3</span>] = static_cast<unsigned char><span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr<span class="Delimiter">)),</span> actual_pretty[<span class="Constant">4</span>] = <span class="cSpecial">'\''</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">5</span>] = <span class="Constant">')'</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">6</span>] = <span class="cSpecial">'\0'</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+ ostringstream color_phrase<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>color != -<span class="Constant">1</span><span class="Delimiter">)</span> color_phrase << <span class="Constant">" in color "</span> << color<span class="Delimiter">;</span>
if <span class="Delimiter">(</span>Current_scenario && !Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Comment">// genuine test in a mu file</span>
- raise << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span> << Current_scenario<span class="Delimiter">-></span>name << <span class="Constant">": expected screen location ("</span> << row << <span class="Constant">", "</span> << column << <span class="Constant">") to contain "</span> << curr << expected_pretty << <span class="Constant">" instead of "</span> << Memory[addr] << actual_pretty << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span> << Current_scenario<span class="Delimiter">-></span>name << <span class="Constant">": expected screen location ("</span> << row << <span class="Constant">", "</span> << column << <span class="Constant">") to contain "</span> << curr << expected_pretty << color_phrase<span class="Delimiter">.</span>str<span class="Delimiter">()</span> << <span class="Constant">" instead of "</span> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr<span class="Delimiter">))</span> << actual_pretty << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
dump_screen<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
else <span class="Delimiter">{</span>
<span class="Comment">// just testing check_screen</span>
- raise << <span class="Constant">"expected screen location ("</span> << row << <span class="Constant">", "</span> << column << <span class="Constant">") to contain "</span> << curr << expected_pretty << <span class="Constant">" instead of "</span> << Memory[addr] << actual_pretty << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"expected screen location ("</span> << row << <span class="Constant">", "</span> << column << <span class="Constant">") to contain "</span> << curr << expected_pretty << color_phrase<span class="Delimiter">.</span>str<span class="Delimiter">()</span> << <span class="Constant">" instead of "</span> << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr<span class="Delimiter">))</span> << actual_pretty << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
if <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span>
Passed = <span class="Constant">false</span><span class="Delimiter">;</span>
@@ -305,7 +313,7 @@ raw_string_stream::raw_string_stream<span class="Delimiter">(</span>const string
bool raw_string_stream::at_end<span class="Delimiter">()</span> const <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>index >= max<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
if <span class="Delimiter">(</span>tb_utf8_char_length<span class="Delimiter">(</span>buf[index]<span class="Delimiter">)</span> > max-index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"unicode string seems corrupted at index "</span><< index << <span class="Constant">" character "</span> << static_cast<int><span class="Delimiter">(</span>buf[index]<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"unicode string seems corrupted at index "</span><< index << <span class="Constant">" character "</span> << static_cast<int><span class="Delimiter">(</span>buf[index]<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
@@ -343,7 +351,11 @@ void raw_string_stream::skip_whitespace_and_comments<span class="Delimiter">()</
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
_DUMP_SCREEN<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"$dump-screen"</span>] = _DUMP_SCREEN<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"$dump-screen"</span><span class="Delimiter">,</span> _DUMP_SCREEN<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case _DUMP_SCREEN: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case _DUMP_SCREEN: <span class="Delimiter">{</span>
dump_screen<span class="Delimiter">();</span>
@@ -352,23 +364,23 @@ case _DUMP_SCREEN: <span class="Delimiter">{</span>
<span class="Delimiter">:(code)</span>
void dump_screen<span class="Delimiter">()</span> <span class="Delimiter">{</span>
- assert<span class="Delimiter">(</span>!Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>default_space<span class="Delimiter">);</span> <span class="Comment">// not supported</span>
- long long int screen_location = Memory[SCREEN]<span class="Delimiter">;</span>
- int width_offset = find_element_name<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"screen"</span>]<span class="Delimiter">,</span> <span class="Constant">"num-columns"</span><span class="Delimiter">);</span>
- long long int screen_width = Memory[screen_location+width_offset]<span class="Delimiter">;</span>
- int height_offset = find_element_name<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"screen"</span>]<span class="Delimiter">,</span> <span class="Constant">"num-rows"</span><span class="Delimiter">);</span>
- long long int screen_height = Memory[screen_location+height_offset]<span class="Delimiter">;</span>
- int data_offset = find_element_name<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"screen"</span>]<span class="Delimiter">,</span> <span class="Constant">"data"</span><span class="Delimiter">);</span>
+ assert<span class="Delimiter">(</span>!current_call<span class="Delimiter">().</span>default_space<span class="Delimiter">);</span> <span class="Comment">// not supported</span>
+ long long int screen_location = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> SCREEN<span class="Delimiter">);</span>
+ int width_offset = find_element_name<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"screen"</span><span class="Delimiter">),</span> <span class="Constant">"num-columns"</span><span class="Delimiter">,</span> <span class="Constant">""</span><span class="Delimiter">);</span>
+ long long int screen_width = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> screen_location+width_offset<span class="Delimiter">);</span>
+ int height_offset = find_element_name<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"screen"</span><span class="Delimiter">),</span> <span class="Constant">"num-rows"</span><span class="Delimiter">,</span> <span class="Constant">""</span><span class="Delimiter">);</span>
+ long long int screen_height = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> screen_location+height_offset<span class="Delimiter">);</span>
+ int data_offset = find_element_name<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"screen"</span><span class="Delimiter">),</span> <span class="Constant">"data"</span><span class="Delimiter">,</span> <span class="Constant">""</span><span class="Delimiter">);</span>
assert<span class="Delimiter">(</span>data_offset >= <span class="Constant">0</span><span class="Delimiter">);</span>
long long int screen_data_location = screen_location+data_offset<span class="Delimiter">;</span> <span class="Comment">// type: address:array:character</span>
- long long int screen_data_start = Memory[screen_data_location]<span class="Delimiter">;</span> <span class="Comment">// type: array:character</span>
- assert<span class="Delimiter">(</span>Memory[screen_data_start] == screen_width*screen_height<span class="Delimiter">);</span>
+ long long int screen_data_start = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> screen_data_location<span class="Delimiter">);</span> <span class="Comment">// type: array:character</span>
+ assert<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> screen_data_start<span class="Delimiter">)</span> == screen_width*screen_height<span class="Delimiter">);</span>
long long int curr = screen_data_start+<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Comment">// skip length</span>
for <span class="Delimiter">(</span>long long int row = <span class="Constant">0</span><span class="Delimiter">;</span> row < screen_height<span class="Delimiter">;</span> ++row<span class="Delimiter">)</span> <span class="Delimiter">{</span>
cerr << <span class="Constant">'.'</span><span class="Delimiter">;</span>
for <span class="Delimiter">(</span>long long int col = <span class="Constant">0</span><span class="Delimiter">;</span> col < screen_width<span class="Delimiter">;</span> ++col<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>Memory[curr]<span class="Delimiter">)</span>
- cerr << to_unicode<span class="Delimiter">(</span>Memory[curr]<span class="Delimiter">);</span>
+ if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> curr<span class="Delimiter">))</span>
+ cerr << to_unicode<span class="Delimiter">(</span>static_cast<uint32_t><span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> curr<span class="Delimiter">)));</span>
else
cerr << <span class="Constant">' '</span><span class="Delimiter">;</span>
curr += <span class="Comment">/*</span><span class="Comment">size of screen-cell</span><span class="Comment">*/</span><span class="Constant">2</span><span class="Delimiter">;</span>
diff --git a/html/073scenario_screen_test.mu.html b/html/073scenario_screen_test.mu.html
index aa6f42b9..ba50c80e 100644
--- a/html/073scenario_screen_test.mu.html
+++ b/html/073scenario_screen_test.mu.html
@@ -33,7 +33,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> print-character-at-top-left-2 [
assume-screen <span class="Constant">3/width</span>, <span class="Constant">2/height</span>
run [
- screen:address<span class="Special"> <- </span>print-character screen:address, <span class="Constant">97/a</span>
+ screen:address:screen<span class="Special"> <- </span>print-character screen:address:screen, <span class="Constant">97/a</span>
]
screen-should-contain [
<span class="Constant"> .a .</span>
@@ -45,11 +45,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-screen <span class="Constant">5/width</span>, <span class="Constant">3/height</span>
run [
<span class="Comment"># print a character</span>
- screen:address<span class="Special"> <- </span>print-character screen:address, <span class="Constant">97/a</span>
+ screen:address:screen<span class="Special"> <- </span>print-character screen:address:screen, <span class="Constant">97/a</span>
<span class="Comment"># move cursor to start of line</span>
- screen:address<span class="Special"> <- </span>move-cursor screen:address, <span class="Constant">0/row</span>, <span class="Constant">0/column</span>
+ screen:address:screen<span class="Special"> <- </span>move-cursor screen:address:screen, <span class="Constant">0/row</span>, <span class="Constant">0/column</span>
<span class="Comment"># clear line</span>
- screen:address<span class="Special"> <- </span>clear-line screen:address
+ screen:address:screen<span class="Special"> <- </span>clear-line screen:address:screen
]
screen-should-contain [
<span class="Constant"> . .</span>
diff --git a/html/074console.mu.html b/html/074console.mu.html
index 191c33e8..62f88c3a 100644
--- a/html/074console.mu.html
+++ b/html/074console.mu.html
@@ -13,13 +13,13 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
.muRecipe { color: #ff8700; }
.muData { color: #ffff00; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.Special { color: #ff6060; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
-->
</style>
@@ -61,7 +61,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muRecipe">recipe</span> new-fake-console [
<span class="Constant">local-scope</span>
result:address:console<span class="Special"> <- </span>new <span class="Constant">console:type</span>
- buf:address:address:array:character<span class="Special"> <- </span>get-address *result, <span class="Constant">data:offset</span>
+ buf:address:address:array:event<span class="Special"> <- </span>get-address *result, <span class="Constant">data:offset</span>
*buf<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
idx:address:number<span class="Special"> <- </span>get-address *result, <span class="Constant">index:offset</span>
*idx<span class="Special"> <- </span>copy <span class="Constant">0</span>
@@ -96,7 +96,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># newlines, tabs, ctrl-d..</span>
<span class="muRecipe">recipe</span> read-key [
<span class="Constant">local-scope</span>
- console:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ console:address:console<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
x:event, console, found?:boolean, quit?:boolean<span class="Special"> <- </span>read-event console
<span class="muControl">reply-if</span> quit?, <span class="Constant">0</span>, console/same-as-ingredient:<span class="Constant">0</span>, found?, quit?
<span class="muControl">reply-unless</span> found?, <span class="Constant">0</span>, console/same-as-ingredient:<span class="Constant">0</span>, found?, quit?
@@ -107,9 +107,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muRecipe">recipe</span> send-keys-to-channel [
<span class="Constant">local-scope</span>
- console:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ console:address:console<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
<span class="Delimiter">{</span>
c:character, console, found?:boolean, quit?:boolean<span class="Special"> <- </span>read-key console
<span class="muControl">loop-unless</span> found?
@@ -124,7 +124,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muRecipe">recipe</span> wait-for-event [
<span class="Constant">local-scope</span>
- console:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ console:address:console<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
<span class="Delimiter">{</span>
_, console, found?:boolean<span class="Special"> <- </span>read-event console
<span class="muControl">loop-unless</span> found?
@@ -135,7 +135,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># use this helper to skip rendering if there's lots of other events queued up</span>
<span class="muRecipe">recipe</span> has-more-events? [
<span class="Constant">local-scope</span>
- console:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ console:address:console<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
<span class="Delimiter">{</span>
<span class="muControl">break-unless</span> console
<span class="Comment"># fake consoles should be plenty fast; never skip</span>
diff --git a/html/075scenario_console.cc.html b/html/075scenario_console.cc.html
index c578c2a8..6ef48e09 100644
--- a/html/075scenario_console.cc.html
+++ b/html/075scenario_console.cc.html
@@ -43,10 +43,10 @@ scenario keyboard-in-scenario [
type [abc]
]
run [
- <span class="Constant">1</span>:character<span class="Delimiter">,</span> console:address<span class="Delimiter">,</span> <span class="Constant">2</span>:boolean<span class="Special"> <- </span>read-key console:address
- <span class="Constant">3</span>:character<span class="Delimiter">,</span> console:address<span class="Delimiter">,</span> <span class="Constant">4</span>:boolean<span class="Special"> <- </span>read-key console:address
- <span class="Constant">5</span>:character<span class="Delimiter">,</span> console:address<span class="Delimiter">,</span> <span class="Constant">6</span>:boolean<span class="Special"> <- </span>read-key console:address
- <span class="Constant">7</span>:character<span class="Delimiter">,</span> console:address<span class="Delimiter">,</span> <span class="Constant">8</span>:boolean<span class="Delimiter">,</span> <span class="Constant">9</span>:boolean<span class="Special"> <- </span>read-key console:address
+ <span class="Constant">1</span>:character<span class="Delimiter">,</span> console:address:console<span class="Delimiter">,</span> <span class="Constant">2</span>:boolean<span class="Special"> <- </span>read-key console:address:console
+ <span class="Constant">3</span>:character<span class="Delimiter">,</span> console:address:console<span class="Delimiter">,</span> <span class="Constant">4</span>:boolean<span class="Special"> <- </span>read-key console:address:console
+ <span class="Constant">5</span>:character<span class="Delimiter">,</span> console:address:console<span class="Delimiter">,</span> <span class="Constant">6</span>:boolean<span class="Special"> <- </span>read-key console:address:console
+ <span class="Constant">7</span>:character<span class="Delimiter">,</span> console:address:console<span class="Delimiter">,</span> <span class="Constant">8</span>:boolean<span class="Delimiter">,</span> <span class="Constant">9</span>:boolean<span class="Special"> <- </span>read-key console:address:console
]
memory-should-contain [
<span class="Constant">1</span><span class="Special"> <- </span><span class="Constant">97</span> <span class="Comment"># 'a'</span>
@@ -70,47 +70,50 @@ Name[r][<span class="Constant">"console"</span>] = CONSOLE<span class=
<span class="Delimiter">:(before "End is_special_name Cases")</span>
if <span class="Delimiter">(</span>s == <span class="Constant">"console"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
-<span class="Comment">//: Unlike assume-keyboard, assume-console is easiest to implement as just a</span>
-<span class="Comment">//: primitive recipe.</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
ASSUME_CONSOLE<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"assume-console"</span>] = ASSUME_CONSOLE<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"assume-console"</span><span class="Delimiter">,</span> ASSUME_CONSOLE<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case ASSUME_CONSOLE: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case ASSUME_CONSOLE: <span class="Delimiter">{</span>
<span class="Comment">// create a temporary recipe just for parsing; it won't contain valid instructions</span>
istringstream in<span class="Delimiter">(</span><span class="Constant">"["</span> + current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name + <span class="Constant">"]"</span><span class="Delimiter">);</span>
- recipe r = slurp_body<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+ recipe r<span class="Delimiter">;</span>
+ slurp_body<span class="Delimiter">(</span>in<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
long long int num_events = count_events<span class="Delimiter">(</span>r<span class="Delimiter">);</span>
- <span class="Comment">// initialize the events</span>
+ <span class="Comment">// initialize the events like in new-fake-console</span>
long long int size = num_events*size_of_event<span class="Delimiter">()</span> + <span class="Comment">/*</span><span class="Comment">space for length</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span>
ensure_space<span class="Delimiter">(</span>size<span class="Delimiter">);</span>
long long int event_data_address = Current_routine<span class="Delimiter">-></span>alloc<span class="Delimiter">;</span>
- Memory[event_data_address] = num_events<span class="Delimiter">;</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> event_data_address<span class="Delimiter">,</span> num_events<span class="Delimiter">);</span>
++Current_routine<span class="Delimiter">-></span>alloc<span class="Delimiter">;</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
const instruction& curr = r<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"left-click"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- Memory[Current_routine<span class="Delimiter">-></span>alloc] = <span class="Comment">/*</span><span class="Comment">tag for 'touch-event' variant of 'event' exclusive-container</span><span class="Comment">*/</span><span class="Constant">2</span><span class="Delimiter">;</span>
- Memory[Current_routine<span class="Delimiter">-></span>alloc+<span class="Constant">1</span>+<span class="Comment">/*</span><span class="Comment">offset of 'type' in 'mouse-event'</span><span class="Comment">*/</span><span class="Constant">0</span>] = TB_KEY_MOUSE_LEFT<span class="Delimiter">;</span>
- Memory[Current_routine<span class="Delimiter">-></span>alloc+<span class="Constant">1</span>+<span class="Comment">/*</span><span class="Comment">offset of 'row' in 'mouse-event'</span><span class="Comment">*/</span><span class="Constant">1</span>] = to_integer<span class="Delimiter">(</span>curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">);</span>
- Memory[Current_routine<span class="Delimiter">-></span>alloc+<span class="Constant">1</span>+<span class="Comment">/*</span><span class="Comment">offset of 'column' in 'mouse-event'</span><span class="Comment">*/</span><span class="Constant">2</span>] = to_integer<span class="Delimiter">(</span>curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">);</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> Current_routine<span class="Delimiter">-></span>alloc<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">tag for 'touch-event' variant of 'event' exclusive-container</span><span class="Comment">*/</span><span class="Constant">2</span><span class="Delimiter">);</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> Current_routine<span class="Delimiter">-></span>alloc+<span class="Constant">1</span>+<span class="Comment">/*</span><span class="Comment">offset of 'type' in 'mouse-event'</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">,</span> TB_KEY_MOUSE_LEFT<span class="Delimiter">);</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> Current_routine<span class="Delimiter">-></span>alloc+<span class="Constant">1</span>+<span class="Comment">/*</span><span class="Comment">offset of 'row' in 'mouse-event'</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">,</span> to_integer<span class="Delimiter">(</span>curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">));</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> Current_routine<span class="Delimiter">-></span>alloc+<span class="Constant">1</span>+<span class="Comment">/*</span><span class="Comment">offset of 'column' in 'mouse-event'</span><span class="Comment">*/</span><span class="Constant">2</span><span class="Delimiter">,</span> to_integer<span class="Delimiter">(</span>curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">));</span>
Current_routine<span class="Delimiter">-></span>alloc += size_of_event<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
else if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <span class="Constant">"press"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
string key = curr<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">;</span>
if <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>key<span class="Delimiter">))</span>
- Memory[Current_routine<span class="Delimiter">-></span>alloc+<span class="Constant">1</span>] = to_integer<span class="Delimiter">(</span>key<span class="Delimiter">);</span>
- else if <span class="Delimiter">(</span>Key<span class="Delimiter">.</span>find<span class="Delimiter">(</span>key<span class="Delimiter">)</span> != Key<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
- Memory[Current_routine<span class="Delimiter">-></span>alloc+<span class="Constant">1</span>] = Key[key]<span class="Delimiter">;</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> Current_routine<span class="Delimiter">-></span>alloc+<span class="Constant">1</span><span class="Delimiter">,</span> to_integer<span class="Delimiter">(</span>key<span class="Delimiter">));</span>
+ else if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Key<span class="Delimiter">,</span> key<span class="Delimiter">))</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> Current_routine<span class="Delimiter">-></span>alloc+<span class="Constant">1</span><span class="Delimiter">,</span> Key[key]<span class="Delimiter">);</span>
else
- raise << <span class="Constant">"assume-console: can't press "</span> << key << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- if <span class="Delimiter">(</span>Memory[Current_routine<span class="Delimiter">-></span>alloc+<span class="Constant">1</span>] < <span class="Constant">256</span><span class="Delimiter">)</span>
+ raise_error << <span class="Constant">"assume-console: can't press "</span> << key << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> Current_routine<span class="Delimiter">-></span>alloc+<span class="Constant">1</span><span class="Delimiter">)</span> < <span class="Constant">256</span><span class="Delimiter">)</span>
<span class="Comment">// these keys are in ascii</span>
- Memory[Current_routine<span class="Delimiter">-></span>alloc] = <span class="Comment">/*</span><span class="Comment">tag for 'text' variant of 'event' exclusive-container</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">;</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> Current_routine<span class="Delimiter">-></span>alloc<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">tag for 'text' variant of 'event' exclusive-container</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">);</span>
else <span class="Delimiter">{</span>
<span class="Comment">// distinguish from unicode</span>
- Memory[Current_routine<span class="Delimiter">-></span>alloc] = <span class="Comment">/*</span><span class="Comment">tag for 'keycode' variant of 'event' exclusive-container</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> Current_routine<span class="Delimiter">-></span>alloc<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">tag for 'keycode' variant of 'event' exclusive-container</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">);</span>
<span class="Delimiter">}</span>
Current_routine<span class="Delimiter">-></span>alloc += size_of_event<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
@@ -123,22 +126,23 @@ case ASSUME_CONSOLE: <span class="Delimiter">{</span>
long long int num_keyboard_events = unicode_length<span class="Delimiter">(</span>contents<span class="Delimiter">);</span>
long long int curr = <span class="Constant">0</span><span class="Delimiter">;</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < num_keyboard_events<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- Memory[Current_routine<span class="Delimiter">-></span>alloc] = <span class="Comment">/*</span><span class="Comment">tag for 'text' variant of 'event' exclusive-container</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">;</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> Current_routine<span class="Delimiter">-></span>alloc<span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">tag for 'text' variant of 'event' exclusive-container</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">);</span>
uint32_t curr_character<span class="Delimiter">;</span>
assert<span class="Delimiter">(</span>curr < SIZE<span class="Delimiter">(</span>contents<span class="Delimiter">));</span>
tb_utf8_char_to_unicode<span class="Delimiter">(</span>&curr_character<span class="Delimiter">,</span> &raw_contents[curr]<span class="Delimiter">);</span>
- Memory[Current_routine<span class="Delimiter">-></span>alloc+<span class="Comment">/*</span><span class="Comment">skip exclusive container tag</span><span class="Comment">*/</span><span class="Constant">1</span>] = curr_character<span class="Delimiter">;</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> Current_routine<span class="Delimiter">-></span>alloc+<span class="Comment">/*</span><span class="Comment">skip exclusive container tag</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">,</span> curr_character<span class="Delimiter">);</span>
curr += tb_utf8_char_length<span class="Delimiter">(</span>raw_contents[curr]<span class="Delimiter">);</span>
Current_routine<span class="Delimiter">-></span>alloc += size_of_event<span class="Delimiter">();</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
assert<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>alloc == event_data_address+size<span class="Delimiter">);</span>
- <span class="Comment">// wrap the array of events in an event object</span>
- ensure_space<span class="Delimiter">(</span>size_of_events<span class="Delimiter">());</span>
- Memory[CONSOLE] = Current_routine<span class="Delimiter">-></span>alloc<span class="Delimiter">;</span>
- Current_routine<span class="Delimiter">-></span>alloc += size_of_events<span class="Delimiter">();</span>
- Memory[Memory[CONSOLE]+<span class="Comment">/*</span><span class="Comment">offset of 'data' in container 'events'</span><span class="Comment">*/</span><span class="Constant">1</span>] = event_data_address<span class="Delimiter">;</span>
+ <span class="Comment">// wrap the array of events in a console object</span>
+ ensure_space<span class="Delimiter">(</span>size_of_console<span class="Delimiter">());</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> CONSOLE<span class="Delimiter">,</span> Current_routine<span class="Delimiter">-></span>alloc<span class="Delimiter">);</span>
+ Current_routine<span class="Delimiter">-></span>alloc += size_of_console<span class="Delimiter">();</span>
+ long long int console_address = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> CONSOLE<span class="Delimiter">);</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> console_address+<span class="Comment">/*</span><span class="Comment">offset of 'data' in container 'events'</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">,</span> event_data_address<span class="Delimiter">);</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -212,15 +216,15 @@ scenario events-in-scenario [
]
run [
<span class="Comment"># 3 keyboard events; each event occupies 4 locations</span>
- <span class="Constant">1</span>:event<span class="Special"> <- </span>read-event console:address
- <span class="Constant">5</span>:event<span class="Special"> <- </span>read-event console:address
- <span class="Constant">9</span>:event<span class="Special"> <- </span>read-event console:address
+ <span class="Constant">1</span>:event<span class="Special"> <- </span>read-event console:address:console
+ <span class="Constant">5</span>:event<span class="Special"> <- </span>read-event console:address:console
+ <span class="Constant">9</span>:event<span class="Special"> <- </span>read-event console:address:console
<span class="Comment"># mouse click</span>
- <span class="Constant">13</span>:event<span class="Special"> <- </span>read-event console:address
+ <span class="Constant">13</span>:event<span class="Special"> <- </span>read-event console:address:console
<span class="Comment"># non-character keycode</span>
- <span class="Constant">17</span>:event<span class="Special"> <- </span>read-event console:address
+ <span class="Constant">17</span>:event<span class="Special"> <- </span>read-event console:address:console
<span class="Comment"># final keyboard event</span>
- <span class="Constant">21</span>:event<span class="Special"> <- </span>read-event console:address
+ <span class="Constant">21</span>:event<span class="Special"> <- </span>read-event console:address:console
]
memory-should-contain [
<span class="Constant">1</span><span class="Special"> <- </span><span class="Constant">0</span> <span class="Comment"># 'text'</span>
@@ -256,21 +260,26 @@ scenario events-in-scenario [
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
REPLACE_IN_CONSOLE<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"replace-in-console"</span>] = REPLACE_IN_CONSOLE<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"replace-in-console"</span><span class="Delimiter">,</span> REPLACE_IN_CONSOLE<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case REPLACE_IN_CONSOLE: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case REPLACE_IN_CONSOLE: <span class="Delimiter">{</span>
assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
- if <span class="Delimiter">(</span>!Memory[CONSOLE]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << <span class="Constant">"console not initialized</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> CONSOLE<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+ raise_error << <span class="Constant">"console not initialized</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- long long int console_data = Memory[Memory[CONSOLE]+<span class="Constant">1</span>]<span class="Delimiter">;</span>
- long long int size = Memory[console_data]<span class="Delimiter">;</span> <span class="Comment">// array size</span>
+ long long int console_address = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> CONSOLE<span class="Delimiter">);</span>
+ long long int console_data = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> console_address+<span class="Constant">1</span><span class="Delimiter">);</span>
+ long long int size = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> console_data<span class="Delimiter">);</span> <span class="Comment">// array size</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">,</span> curr = console_data+<span class="Constant">1</span><span class="Delimiter">;</span> i < size<span class="Delimiter">;</span> ++i<span class="Delimiter">,</span> curr+=size_of_event<span class="Delimiter">())</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>Memory[curr] != <span class="Comment">/*</span><span class="Comment">text</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>Memory[curr+<span class="Constant">1</span>] != ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> curr<span class="Delimiter">)</span> != <span class="Comment">/*</span><span class="Comment">text</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> curr+<span class="Constant">1</span><span class="Delimiter">)</span> != ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
for <span class="Delimiter">(</span>long long int n = <span class="Constant">0</span><span class="Delimiter">;</span> n < size_of_event<span class="Delimiter">();</span> ++n<span class="Delimiter">)</span>
- Memory[curr+n] = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span>n<span class="Delimiter">);</span>
+ put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> curr+n<span class="Delimiter">,</span> ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span>n<span class="Delimiter">));</span>
<span class="Delimiter">}</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -292,20 +301,20 @@ long long int size_of_event<span class="Delimiter">()</span> <span class="Delimi
<span class="Comment">// memoize result if already computed</span>
static long long int result = <span class="Constant">0</span><span class="Delimiter">;</span>
if <span class="Delimiter">(</span>result<span class="Delimiter">)</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span>
- vector<type_ordinal> type<span class="Delimiter">;</span>
- type<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"event"</span>]<span class="Delimiter">);</span>
+ type_tree* type = new type_tree<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"event"</span><span class="Delimiter">));</span>
result = size_of<span class="Delimiter">(</span>type<span class="Delimiter">);</span>
+ delete type<span class="Delimiter">;</span>
<span class="Identifier">return</span> result<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
-long long int size_of_events<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+long long int size_of_console<span class="Delimiter">()</span> <span class="Delimiter">{</span>
<span class="Comment">// memoize result if already computed</span>
static long long int result = <span class="Constant">0</span><span class="Delimiter">;</span>
if <span class="Delimiter">(</span>result<span class="Delimiter">)</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span>
- vector<type_ordinal> type<span class="Delimiter">;</span>
- assert<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"console"</span>]<span class="Delimiter">);</span>
- type<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>Type_ordinal[<span class="Constant">"console"</span>]<span class="Delimiter">);</span>
+ assert<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"console"</span><span class="Delimiter">));</span>
+ type_tree* type = new type_tree<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"console"</span><span class="Delimiter">));</span>
result = size_of<span class="Delimiter">(</span>type<span class="Delimiter">);</span>
+ delete type<span class="Delimiter">;</span>
<span class="Identifier">return</span> result<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
</pre>
diff --git a/html/076scenario_console_test.mu.html b/html/076scenario_console_test.mu.html
index b33cb4cd..bc0f6688 100644
--- a/html/076scenario_console_test.mu.html
+++ b/html/076scenario_console_test.mu.html
@@ -37,10 +37,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[abc]</span>
]
run [
- <span class="Constant">1</span>:character, console:address, <span class="Constant">2</span>:boolean<span class="Special"> <- </span>read-key console:address
- <span class="Constant">3</span>:character, console:address, <span class="Constant">4</span>:boolean<span class="Special"> <- </span>read-key console:address
- <span class="Constant">5</span>:character, console:address, <span class="Constant">6</span>:boolean<span class="Special"> <- </span>read-key console:address
- <span class="Constant">7</span>:character, console:address, <span class="Constant">8</span>:boolean<span class="Special"> <- </span>read-key console:address
+ <span class="Constant">1</span>:character, console:address:console, <span class="Constant">2</span>:boolean<span class="Special"> <- </span>read-key console:address:console
+ <span class="Constant">3</span>:character, console:address:console, <span class="Constant">4</span>:boolean<span class="Special"> <- </span>read-key console:address:console
+ <span class="Constant">5</span>:character, console:address:console, <span class="Constant">6</span>:boolean<span class="Special"> <- </span>read-key console:address:console
+ <span class="Constant">7</span>:character, console:address:console, <span class="Constant">8</span>:boolean<span class="Special"> <- </span>read-key console:address:console
]
memory-should-contain [
<span class="Constant">1</span><span class="Special"> <- </span><span class="Constant">97</span> <span class="Comment"># 'a'</span>
diff --git a/html/080trace_browser.cc.html b/html/080trace_browser.cc.html
index 9ac50591..d209225b 100644
--- a/html/080trace_browser.cc.html
+++ b/html/080trace_browser.cc.html
@@ -32,7 +32,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
_BROWSE_TRACE<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"$browse-trace"</span>] = _BROWSE_TRACE<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"$browse-trace"</span><span class="Delimiter">,</span> _BROWSE_TRACE<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case _BROWSE_TRACE: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case _BROWSE_TRACE: <span class="Delimiter">{</span>
start_trace_browser<span class="Delimiter">();</span>
@@ -105,7 +109,7 @@ void start_trace_browser<span class="Delimiter">()</span> <span class="Delimiter
for <span class="Delimiter">(</span>int screen_row = tb_height<span class="Delimiter">();</span> screen_row > <span class="Constant">0</span> && Top_of_screen > <span class="Constant">0</span><span class="Delimiter">;</span> --screen_row<span class="Delimiter">)</span> <span class="Delimiter">{</span>
--Top_of_screen<span class="Delimiter">;</span>
if <span class="Delimiter">(</span>Top_of_screen <= <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
- while <span class="Delimiter">(</span>Top_of_screen > <span class="Constant">0</span> && Visible<span class="Delimiter">.</span>find<span class="Delimiter">(</span>Top_of_screen<span class="Delimiter">)</span> == Visible<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
+ while <span class="Delimiter">(</span>Top_of_screen > <span class="Constant">0</span> && !contains_key<span class="Delimiter">(</span>Visible<span class="Delimiter">,</span> Top_of_screen<span class="Delimiter">))</span>
--Top_of_screen<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
if <span class="Delimiter">(</span>Top_of_screen > <span class="Constant">0</span><span class="Delimiter">)</span>
@@ -117,7 +121,7 @@ void start_trace_browser<span class="Delimiter">()</span> <span class="Delimiter
for <span class="Delimiter">(</span>int screen_row = tb_height<span class="Delimiter">();</span> screen_row > <span class="Constant">0</span> && Top_of_screen > <span class="Constant">0</span><span class="Delimiter">;</span> --screen_row<span class="Delimiter">)</span> <span class="Delimiter">{</span>
--Top_of_screen<span class="Delimiter">;</span>
if <span class="Delimiter">(</span>Top_of_screen <= <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
- while <span class="Delimiter">(</span>Top_of_screen > <span class="Constant">0</span> && Visible<span class="Delimiter">.</span>find<span class="Delimiter">(</span>Top_of_screen<span class="Delimiter">)</span> == Visible<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
+ while <span class="Delimiter">(</span>Top_of_screen > <span class="Constant">0</span> && !contains_key<span class="Delimiter">(</span>Visible<span class="Delimiter">,</span> Top_of_screen<span class="Delimiter">))</span>
--Top_of_screen<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
refresh_screen_rows<span class="Delimiter">();</span>
@@ -127,13 +131,13 @@ void start_trace_browser<span class="Delimiter">()</span> <span class="Delimiter
<span class="Delimiter">}</span>
if <span class="Delimiter">(</span>key == TB_KEY_CARRIAGE_RETURN<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Comment">// expand lines under current by one level</span>
- assert<span class="Delimiter">(</span>Trace_index<span class="Delimiter">.</span>find<span class="Delimiter">(</span>Display_row<span class="Delimiter">)</span> != Trace_index<span class="Delimiter">.</span>end<span class="Delimiter">());</span>
+ assert<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Trace_index<span class="Delimiter">,</span> Display_row<span class="Delimiter">));</span>
long long int start_index = Trace_index[Display_row]<span class="Delimiter">;</span>
long long int index = <span class="Constant">0</span><span class="Delimiter">;</span>
<span class="Comment">// simultaneously compute end_index and min_depth</span>
int min_depth = <span class="Constant">9999</span><span class="Delimiter">;</span>
for <span class="Delimiter">(</span>index = start_index+<span class="Constant">1</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>Visible<span class="Delimiter">.</span>find<span class="Delimiter">(</span>index<span class="Delimiter">)</span> != Visible<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Visible<span class="Delimiter">,</span> index<span class="Delimiter">))</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
trace_line& curr_line = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
assert<span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth > Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>start_index<span class="Delimiter">).</span>depth<span class="Delimiter">);</span>
@@ -151,13 +155,13 @@ void start_trace_browser<span class="Delimiter">()</span> <span class="Delimiter
<span class="Delimiter">}</span>
if <span class="Delimiter">(</span>key == TB_KEY_BACKSPACE || key == TB_KEY_BACKSPACE2<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Comment">// collapse all lines under current</span>
- assert<span class="Delimiter">(</span>Trace_index<span class="Delimiter">.</span>find<span class="Delimiter">(</span>Display_row<span class="Delimiter">)</span> != Trace_index<span class="Delimiter">.</span>end<span class="Delimiter">());</span>
+ assert<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Trace_index<span class="Delimiter">,</span> Display_row<span class="Delimiter">));</span>
long long int start_index = Trace_index[Display_row]<span class="Delimiter">;</span>
long long int index = <span class="Constant">0</span><span class="Delimiter">;</span>
<span class="Comment">// end_index is the next line at a depth same as or lower than start_index</span>
int initial_depth = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>start_index<span class="Delimiter">).</span>depth<span class="Delimiter">;</span>
for <span class="Delimiter">(</span>index = start_index+<span class="Constant">1</span><span class="Delimiter">;</span> index < SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>Visible<span class="Delimiter">.</span>find<span class="Delimiter">(</span>index<span class="Delimiter">)</span> == Visible<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Visible<span class="Delimiter">,</span> index<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
trace_line& curr_line = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span>
if <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
if <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth <= initial_depth<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
@@ -179,7 +183,7 @@ void refresh_screen_rows<span class="Delimiter">()</span> <span class="Delimiter
Trace_index<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
for <span class="Delimiter">(</span>screen_row = <span class="Constant">0</span><span class="Delimiter">,</span> index = Top_of_screen<span class="Delimiter">;</span> screen_row < tb_height<span class="Delimiter">()</span> && index < SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">);</span> ++screen_row<span class="Delimiter">,</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Comment">// skip lines without depth for now</span>
- while <span class="Delimiter">(</span>Visible<span class="Delimiter">.</span>find<span class="Delimiter">(</span>index<span class="Delimiter">)</span> == Visible<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+ while <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Visible<span class="Delimiter">,</span> index<span class="Delimiter">))</span> <span class="Delimiter">{</span>
++index<span class="Delimiter">;</span>
if <span class="Delimiter">(</span>index >= SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">))</span> <span class="Identifier">goto</span> done<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -192,7 +196,7 @@ done:<span class="Delimiter">;</span>
void render<span class="Delimiter">()</span> <span class="Delimiter">{</span>
long long int screen_row = <span class="Constant">0</span><span class="Delimiter">;</span>
for <span class="Delimiter">(</span>screen_row = <span class="Constant">0</span><span class="Delimiter">;</span> screen_row < tb_height<span class="Delimiter">();</span> ++screen_row<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>Trace_index<span class="Delimiter">.</span>find<span class="Delimiter">(</span>screen_row<span class="Delimiter">)</span> == Trace_index<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Trace_index<span class="Delimiter">,</span> screen_row<span class="Delimiter">))</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
trace_line& curr_line = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>Trace_index[screen_row]<span class="Delimiter">);</span>
ostringstream out<span class="Delimiter">;</span>
out << std::setw<span class="Delimiter">(</span><span class="Constant">4</span><span class="Delimiter">)</span> << curr_line<span class="Delimiter">.</span>depth << <span class="Constant">' '</span> << curr_line<span class="Delimiter">.</span>label << <span class="Constant">": "</span> << curr_line<span class="Delimiter">.</span>contents<span class="Delimiter">;</span>
@@ -216,8 +220,8 @@ void render<span class="Delimiter">()</span> <span class="Delimiter">{</span>
<span class="Delimiter">}</span>
long long int lines_hidden<span class="Delimiter">(</span>long long int screen_row<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- assert<span class="Delimiter">(</span>Trace_index<span class="Delimiter">.</span>find<span class="Delimiter">(</span>screen_row<span class="Delimiter">)</span> != Trace_index<span class="Delimiter">.</span>end<span class="Delimiter">());</span>
- if <span class="Delimiter">(</span>Trace_index<span class="Delimiter">.</span>find<span class="Delimiter">(</span>screen_row+<span class="Constant">1</span><span class="Delimiter">)</span> == Trace_index<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
+ assert<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Trace_index<span class="Delimiter">,</span> screen_row<span class="Delimiter">));</span>
+ if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Trace_index<span class="Delimiter">,</span> screen_row+<span class="Constant">1</span><span class="Delimiter">))</span>
<span class="Identifier">return</span> SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">)</span>-Trace_index[screen_row]<span class="Delimiter">;</span>
else
<span class="Identifier">return</span> Trace_index[screen_row+<span class="Constant">1</span>] - Trace_index[screen_row]<span class="Delimiter">;</span>
diff --git a/html/081run_interactive.cc.html b/html/081run_interactive.cc.html
index 79db9059..3802f61a 100644
--- a/html/081run_interactive.cc.html
+++ b/html/081run_interactive.cc.html
@@ -13,8 +13,8 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
-.cSpecial { color: #008000; }
.traceContains { color: #008000; }
+.cSpecial { color: #008000; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
@@ -36,46 +36,53 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">:(scenario run_interactive_code)</span>
recipe main [
+ <span class="Constant">1</span>:number/<span class="Special">raw <- </span>copy <span class="Constant">0</span>
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new [<span class="Constant">1</span>:number/<span class="Special">raw <- </span>copy <span class="Constant">34</span>]
run-interactive <span class="Constant">2</span>:address:array:character
+ <span class="Constant">3</span>:number/<span class="Special">raw <- </span>copy <span class="Constant">1</span>:number/<span class="Special">raw</span>
]
-<span class="traceContains">+mem: storing 34 in location 1</span>
+<span class="traceContains">+mem: storing 34 in location 3</span>
<span class="Delimiter">:(scenario run_interactive_empty)</span>
recipe main [
- <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>run-interactive <span class="Constant">0</span>
+ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>copy <span class="Constant">0</span>/<span class="Special">raw</span>
+ <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>run-interactive <span class="Constant">1</span>:address:array:character
]
<span class="Comment"># result is null</span>
-<span class="traceContains">+mem: storing 0 in location 1</span>
+<span class="traceContains">+mem: storing 0 in location 2</span>
-<span class="Comment">//: run code in 'interactive mode', i.e. with warnings off and return:</span>
+<span class="Comment">//: run code in 'interactive mode', i.e. with errors+warnings off and return:</span>
<span class="Comment">//: stringified output in case we want to print it to screen</span>
-<span class="Comment">//: any warnings encountered</span>
+<span class="Comment">//: any errors+warnings encountered</span>
<span class="Comment">//: simulated screen any prints went to</span>
<span class="Comment">//: any 'app' layer traces generated</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
RUN_INTERACTIVE<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"run-interactive"</span>] = RUN_INTERACTIVE<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"run-interactive"</span><span class="Delimiter">,</span> RUN_INTERACTIVE<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case RUN_INTERACTIVE: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'run-interactive' requires exactly one ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ 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>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'run-interactive' requires exactly one ingredient, but got "</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>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'run-interactive' should be a string, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'run-interactive' should be a string, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>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">:(before "End Primitive Recipe Implementations")</span>
+case RUN_INTERACTIVE: <span class="Delimiter">{</span>
bool new_code_pushed_to_stack = run_interactive<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
if <span class="Delimiter">(</span>!new_code_pushed_to_stack<span class="Delimiter">)</span> <span class="Delimiter">{</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">5</span><span class="Delimiter">);</span>
products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>trace_contents<span class="Delimiter">(</span><span class="Constant">"warn"</span><span class="Delimiter">));</span>
+ products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>trace_error_warning_contents<span class="Delimiter">());</span>
products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
- products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">3</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>trace_contents<span class="Delimiter">(</span><span class="Constant">"app"</span><span class="Delimiter">));</span>
+ products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">3</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>trace_app_contents<span class="Delimiter">());</span>
products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">4</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> <span class="Comment">// completed</span>
- cleanup_run_interactive<span class="Delimiter">();</span>
+ run_code_end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Comment">// done with this instruction</span>
<span class="Delimiter">}</span>
else <span class="Delimiter">{</span>
@@ -85,6 +92,9 @@ case RUN_INTERACTIVE: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Globals")</span>
bool Track_most_recent_products = <span class="Constant">false</span><span class="Delimiter">;</span>
+<span class="Delimiter">:(before "End Tracing")</span>
+trace_stream* Save_trace_stream = <span class="Constant">NULL</span><span class="Delimiter">;</span>
+string Save_trace_file<span class="Delimiter">;</span>
<span class="Delimiter">:(before "End Setup")</span>
Track_most_recent_products = <span class="Constant">false</span><span class="Delimiter">;</span>
<span class="Delimiter">:(code)</span>
@@ -92,7 +102,7 @@ Track_most_recent_products = <span class="Constant">false</span><span class="Del
<span class="Comment">// all warnings.</span>
<span class="Comment">// returns true if successfully called (no errors found during load and transform)</span>
bool run_interactive<span class="Delimiter">(</span>long long int address<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- assert<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">.</span>find<span class="Delimiter">(</span><span class="Constant">"interactive"</span><span class="Delimiter">)</span> != Recipe_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">()</span> && Recipe_ordinal[<span class="Constant">"interactive"</span>] != <span class="Constant">0</span><span class="Delimiter">);</span>
+ assert<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"interactive"</span><span class="Delimiter">)</span> && get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"interactive"</span><span class="Delimiter">)</span> != <span class="Constant">0</span><span class="Delimiter">);</span>
<span class="Comment">// try to sandbox the run as best you can</span>
<span class="Comment">// todo: test this</span>
if <span class="Delimiter">(</span>!Current_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -101,54 +111,83 @@ bool run_interactive<span class="Delimiter">(</span>long long int address<span c
<span class="Delimiter">}</span>
string command = trim<span class="Delimiter">(</span>strip_comments<span class="Delimiter">(</span>read_mu_string<span class="Delimiter">(</span>address<span class="Delimiter">)));</span>
if <span class="Delimiter">(</span>command<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
- Recipe<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>Recipe_ordinal[<span class="Constant">"interactive"</span>]<span class="Delimiter">);</span>
- Name[Recipe_ordinal[<span class="Constant">"interactive"</span>]]<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
- <span class="Comment">// stuff to undo later, in cleanup_run_interactive()</span>
- Hide_warnings = <span class="Constant">true</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>!Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- Trace_file = <span class="Constant">""</span><span class="Delimiter">;</span> <span class="Comment">// if there wasn't already a stream we don't want to save it</span>
- Trace_stream = new trace_stream<span class="Delimiter">;</span>
- Trace_stream<span class="Delimiter">-></span>collect_layers<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">"warn"</span><span class="Delimiter">);</span>
- Trace_stream<span class="Delimiter">-></span>collect_layers<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">"app"</span><span class="Delimiter">);</span>
- <span class="Delimiter">}</span>
+ Recipe<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"interactive"</span><span class="Delimiter">));</span>
+ Name[get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"interactive"</span><span class="Delimiter">)</span>]<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+ run_code_begin<span class="Delimiter">();</span>
+ <span class="Comment">// don't kill the current routine on parse errors</span>
+ routine* save_current_routine = Current_routine<span class="Delimiter">;</span>
+ Current_routine = <span class="Constant">NULL</span><span class="Delimiter">;</span>
<span class="Comment">// call run(string) but without the scheduling</span>
load<span class="Delimiter">(</span>string<span class="Delimiter">(</span><span class="Constant">"recipe interactive [</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">)</span> +
<span class="Constant">"local-scope</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
- <span class="Constant">"screen:address <- next-ingredient</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
+ <span class="Constant">"screen:address:screen <- next-ingredient</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
<span class="Constant">"$start-tracking-products</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
command + <span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
<span class="Constant">"$stop-tracking-products</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
<span class="Constant">"reply screen</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
<span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span>
transform_all<span class="Delimiter">();</span>
- if <span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span><span class="Constant">"warn"</span><span class="Delimiter">)</span> > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+ Current_routine = save_current_routine<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span><span class="Constant">"error"</span><span class="Delimiter">)</span> > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
<span class="Comment">// now call 'sandbox' which will run 'interactive' in a separate routine,</span>
<span class="Comment">// and wait for it</span>
- Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>push_front<span class="Delimiter">(</span>call<span class="Delimiter">(</span>Recipe_ordinal[<span class="Constant">"sandbox"</span>]<span class="Delimiter">));</span>
+ if <span class="Delimiter">(</span>Save_trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ ++Save_trace_stream<span class="Delimiter">-></span>callstack_depth<span class="Delimiter">;</span>
+ trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">"trace"</span><span class="Delimiter">)</span> << <span class="Constant">"run-interactive: incrementing callstack depth to "</span> << Save_trace_stream<span class="Delimiter">-></span>callstack_depth << end<span class="Delimiter">();</span>
+ assert<span class="Delimiter">(</span>Save_trace_stream<span class="Delimiter">-></span>callstack_depth < <span class="Constant">9000</span><span class="Delimiter">);</span> <span class="Comment">// 9998-101 plus cushion</span>
+ <span class="Delimiter">}</span>
+ Current_routine<span class="Delimiter">-></span>calls<span class="Delimiter">.</span>push_front<span class="Delimiter">(</span>call<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"sandbox"</span><span class="Delimiter">)));</span>
<span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+void run_code_begin<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+ <span class="Comment">// stuff to undo later, in run_code_end()</span>
+ Hide_warnings = <span class="Constant">true</span><span class="Delimiter">;</span>
+ Hide_errors = <span class="Constant">true</span><span class="Delimiter">;</span>
+ Disable_redefine_warnings = <span class="Constant">true</span><span class="Delimiter">;</span>
+ Save_trace_stream = Trace_stream<span class="Delimiter">;</span>
+ Save_trace_file = Trace_file<span class="Delimiter">;</span>
+ Trace_file = <span class="Constant">""</span><span class="Delimiter">;</span>
+ Trace_stream = new trace_stream<span class="Delimiter">;</span>
+ Trace_stream<span class="Delimiter">-></span>collect_depth = App_depth<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+void run_code_end<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+ Hide_warnings = <span class="Constant">false</span><span class="Delimiter">;</span>
+ Hide_errors = <span class="Constant">false</span><span class="Delimiter">;</span>
+ Disable_redefine_warnings = <span class="Constant">false</span><span class="Delimiter">;</span>
+ delete Trace_stream<span class="Delimiter">;</span>
+ Trace_stream = Save_trace_stream<span class="Delimiter">;</span>
+ Save_trace_stream = <span class="Constant">NULL</span><span class="Delimiter">;</span>
+ Trace_file = Save_trace_file<span class="Delimiter">;</span>
+ Save_trace_file<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+<span class="Delimiter">}</span>
+
<span class="Delimiter">:(before "End Load Recipes")</span>
load<span class="Delimiter">(</span>string<span class="Delimiter">(</span>
<span class="Constant">"recipe interactive [</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">)</span> + <span class="Comment">// just a dummy version to initialize the Recipe_ordinal and so on</span>
<span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
<span class="Constant">"recipe sandbox [</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
<span class="Constant">"local-scope</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
- <span class="Constant">"screen:address/shared <- new-fake-screen 30, 5</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
- <span class="Constant">"r:number/routine_id <- start-running interactive:recipe, screen:address</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
+ <span class="Constant">"screen:address:screen/shared <- new-fake-screen 30, 5</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
+ <span class="Constant">"r:number/routine_id <- start-running interactive:recipe, screen</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
<span class="Constant">"limit-time r, 100000/instructions</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
<span class="Constant">"wait-for-routine r</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
<span class="Constant">"sandbox-state:number <- routine-state r/routine_id</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
<span class="Constant">"completed?:boolean <- equal sandbox-state, 1/completed</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
<span class="Constant">"output:address:array:character <- $most-recent-products</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
- <span class="Constant">"warnings:address:array:character <- save-trace [warn]</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
- <span class="Constant">"stashes:address:array:character <- save-trace [app]</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
+ <span class="Constant">"warnings:address:array:character <- save-errors-warnings</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
+ <span class="Constant">"stashes:address:array:character <- save-app-trace</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
<span class="Constant">"$cleanup-run-interactive</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
<span class="Constant">"reply output, warnings, screen, stashes, completed?</span><span class="cSpecial">\n</span><span class="Constant">"</span> +
<span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span>
transform_all<span class="Delimiter">();</span>
recently_added_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+<span class="Comment">//: adjust errors/warnings in the sandbox</span>
+<span class="Delimiter">:(after "string maybe(string s)")</span>
+ if <span class="Delimiter">(</span>s == <span class="Constant">"interactive"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">""</span><span class="Delimiter">;</span>
+
<span class="Delimiter">:(scenario run_interactive_comments)</span>
recipe main [
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new [<span class="Comment"># ab</span>
@@ -158,19 +197,14 @@ add <span class="Constant">2</span><span class="Delimiter">,</span> <span class=
]
<span class="traceContains">+mem: storing 52 in location 4</span>
-<span class="Delimiter">:(scenario run_interactive_just_comments_without_trace)</span>
-recipe main [
- $close-trace
- <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new [<span class="Comment"># ab</span>
-]
- <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>run-interactive <span class="Constant">1</span>:address:array:character
- <span class="Constant">3</span>:array:character<span class="Special"> <- </span>copy *<span class="Constant">2</span>:address:array:character
-]
-
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
_START_TRACKING_PRODUCTS<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"$start-tracking-products"</span>] = _START_TRACKING_PRODUCTS<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"$start-tracking-products"</span><span class="Delimiter">,</span> _START_TRACKING_PRODUCTS<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case _START_TRACKING_PRODUCTS: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case _START_TRACKING_PRODUCTS: <span class="Delimiter">{</span>
Track_most_recent_products = <span class="Constant">true</span><span class="Delimiter">;</span>
@@ -180,7 +214,11 @@ case _START_TRACKING_PRODUCTS: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
_STOP_TRACKING_PRODUCTS<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"$stop-tracking-products"</span>] = _STOP_TRACKING_PRODUCTS<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"$stop-tracking-products"</span><span class="Delimiter">,</span> _STOP_TRACKING_PRODUCTS<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case _STOP_TRACKING_PRODUCTS: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case _STOP_TRACKING_PRODUCTS: <span class="Delimiter">{</span>
Track_most_recent_products = <span class="Constant">false</span><span class="Delimiter">;</span>
@@ -190,7 +228,11 @@ case _STOP_TRACKING_PRODUCTS: <span class="Delimiter">{</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
_MOST_RECENT_PRODUCTS<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"$most-recent-products"</span>] = _MOST_RECENT_PRODUCTS<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"$most-recent-products"</span><span class="Delimiter">,</span> _MOST_RECENT_PRODUCTS<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case _MOST_RECENT_PRODUCTS: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
case _MOST_RECENT_PRODUCTS: <span class="Delimiter">{</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
@@ -199,33 +241,47 @@ case _MOST_RECENT_PRODUCTS: <span class="Delimiter">{</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
-SAVE_TRACE<span class="Delimiter">,</span>
+SAVE_ERRORS_WARNINGS<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"save-trace"</span>] = SAVE_TRACE<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"save-errors-warnings"</span><span class="Delimiter">,</span> SAVE_ERRORS_WARNINGS<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case SAVE_ERRORS_WARNINGS: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
-case SAVE_TRACE: <span class="Delimiter">{</span>
+case SAVE_ERRORS_WARNINGS: <span class="Delimiter">{</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
- products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>trace_contents<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">));</span>
+ products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>trace_error_warning_contents<span class="Delimiter">());</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
-_CLEANUP_RUN_INTERACTIVE<span class="Delimiter">,</span>
+SAVE_APP_TRACE<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"$cleanup-run-interactive"</span>] = _CLEANUP_RUN_INTERACTIVE<span class="Delimiter">;</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"save-app-trace"</span><span class="Delimiter">,</span> SAVE_APP_TRACE<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case SAVE_APP_TRACE: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
-case _CLEANUP_RUN_INTERACTIVE: <span class="Delimiter">{</span>
- cleanup_run_interactive<span class="Delimiter">();</span>
+case SAVE_APP_TRACE: <span class="Delimiter">{</span>
+ products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
+ products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>trace_app_contents<span class="Delimiter">());</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
-<span class="Delimiter">:(code)</span>
-void cleanup_run_interactive<span class="Delimiter">()</span> <span class="Delimiter">{</span>
- Hide_warnings = <span class="Constant">false</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>Trace_stream && Trace_stream<span class="Delimiter">-></span>is_narrowly_collecting<span class="Delimiter">(</span><span class="Constant">"warn"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Comment">// hack</span>
- delete Trace_stream<span class="Delimiter">;</span>
- Trace_stream = <span class="Constant">NULL</span><span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
+_CLEANUP_RUN_INTERACTIVE<span class="Delimiter">,</span>
+<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"$cleanup-run-interactive"</span><span class="Delimiter">,</span> _CLEANUP_RUN_INTERACTIVE<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
+case _CLEANUP_RUN_INTERACTIVE: <span class="Delimiter">{</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case _CLEANUP_RUN_INTERACTIVE: <span class="Delimiter">{</span>
+ run_code_end<span class="Delimiter">();</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">:(scenario "run_interactive_returns_stringified_result")</span>
@@ -242,9 +298,9 @@ recipe main [
recipe main [
<span class="Comment"># try to interactively add 2 and 2</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new [
- <span class="Constant">100</span>:address:array:character<span class="Special"> <- </span>new [a]
- <span class="Constant">101</span>:address:array:character<span class="Special"> <- </span>new [b]
- <span class="Constant">102</span>:address:array:character<span class="Special"> <- </span>string-append <span class="Constant">100</span>:address:array:character<span class="Delimiter">,</span> <span class="Constant">101</span>:address:array:character
+ x:address:array:character<span class="Special"> <- </span>new [a]
+ y:address:array:character<span class="Special"> <- </span>new [b]
+ z:address:array:character<span class="Special"> <- </span>string-append x:address:array:character<span class="Delimiter">,</span> y:address:array:character
]
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>run-interactive <span class="Constant">1</span>:address:array:character
<span class="Constant">10</span>:array:character<span class="Special"> <- </span>copy <span class="Constant">2</span>:address:array:character/lookup
@@ -253,18 +309,31 @@ recipe main [
<span class="traceContains">+mem: storing 97 in location 11</span>
<span class="traceContains">+mem: storing 98 in location 12</span>
-<span class="Delimiter">:(scenario "run_interactive_returns_warnings")</span>
+<span class="Delimiter">:(scenario "run_interactive_returns_errors")</span>
recipe main [
- <span class="Comment"># run a command that generates a warning</span>
- <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new [get <span class="Constant">1234</span>:number<span class="Delimiter">,</span> foo:offset]
+ <span class="Comment"># run a command that generates an error</span>
+ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new [x:number<span class="Special"> <- </span>copy <span class="Constant">34</span>
+get x:number<span class="Delimiter">,</span> foo:offset]
<span class="Constant">2</span>:address:array:character<span class="Delimiter">,</span> <span class="Constant">3</span>:address:array:character<span class="Special"> <- </span>run-interactive <span class="Constant">1</span>:address:array:character
<span class="Constant">10</span>:array:character<span class="Special"> <- </span>copy <span class="Constant">3</span>:address:array:character/lookup
]
-<span class="Comment"># warning should be "unknown element foo in container number"</span>
+<span class="Comment"># error should be "unknown element foo in container number"</span>
<span class="traceContains">+mem: storing 117 in location 11</span>
<span class="traceContains">+mem: storing 110 in location 12</span>
<span class="traceContains">+mem: storing 107 in location 13</span>
<span class="traceContains">+mem: storing 110 in location 14</span>
+<span class="Comment"># ...</span>
+
+<span class="Delimiter">:(scenario run_interactive_with_comment)</span>
+recipe main [
+ <span class="Comment"># 2 instructions, with a comment after the first</span>
+ <span class="Constant">1</span>:address:array:number<span class="Special"> <- </span>new [a:number<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># abc</span>
+b:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
+]
+ <span class="Constant">2</span>:address:array:character<span class="Delimiter">,</span> <span class="Constant">3</span>:address:array:character<span class="Special"> <- </span>run-interactive <span class="Constant">1</span>:address:array:character
+]
+<span class="Comment"># no errors</span>
+<span class="traceContains">+mem: storing 0 in location 3</span>
<span class="Delimiter">:(before "End Globals")</span>
string Most_recent_products<span class="Delimiter">;</span>
@@ -283,10 +352,10 @@ void track_most_recent_products<span class="Delimiter">(</span>const instruction
if <span class="Delimiter">(</span>is_mu_string<span class="Delimiter">(</span>instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
tb_shutdown<span class="Delimiter">();</span>
- cerr << read_mu_string<span class="Delimiter">(</span>trace_contents<span class="Delimiter">(</span><span class="Constant">"warn"</span><span class="Delimiter">))</span> << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
+ cerr << read_mu_string<span class="Delimiter">(</span>trace_error_warning_contents<span class="Delimiter">())</span> << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
cerr << SIZE<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> << <span class="Constant">": "</span><span class="Delimiter">;</span>
for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> ++j<span class="Delimiter">)</span>
- cerr << products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)</span> << <span class="Constant">' '</span><span class="Delimiter">;</span>
+ cerr << no_scientific<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span>j<span class="Delimiter">))</span> << <span class="Constant">' '</span><span class="Delimiter">;</span>
cerr << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)));</span>
@@ -296,7 +365,7 @@ void track_most_recent_products<span class="Delimiter">(</span>const instruction
<span class="Comment">// End Record Product Special-cases</span>
<span class="Delimiter">}</span>
for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> ++j<span class="Delimiter">)</span>
- out << products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)</span> << <span class="Constant">' '</span><span class="Delimiter">;</span>
+ out << no_scientific<span class="Delimiter">(</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>at<span class="Delimiter">(</span>j<span class="Delimiter">))</span> << <span class="Constant">' '</span><span class="Delimiter">;</span>
out << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
Most_recent_products = out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
@@ -310,7 +379,7 @@ string strip_comments<span class="Delimiter">(</span>string in<span class="Delim
result << in<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
else <span class="Delimiter">{</span>
- while <span class="Delimiter">(</span>i < SIZE<span class="Delimiter">(</span>in<span class="Delimiter">)</span> && in<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span>
+ while <span class="Delimiter">(</span>i+<span class="Constant">1</span> < SIZE<span class="Delimiter">(</span>in<span class="Delimiter">)</span> && in<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i+<span class="Constant">1</span><span class="Delimiter">)</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span>
++i<span class="Delimiter">;</span>
<span class="Delimiter">}</span>
<span class="Delimiter">}</span>
@@ -320,21 +389,34 @@ string strip_comments<span class="Delimiter">(</span>string in<span class="Delim
long long int stringified_value_of_location<span class="Delimiter">(</span>long long int address<span class="Delimiter">)</span> <span class="Delimiter">{</span>
<span class="Comment">// convert to string</span>
ostringstream out<span class="Delimiter">;</span>
- out << Memory[address]<span class="Delimiter">;</span>
+ out << no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">));</span>
<span class="Identifier">return</span> new_mu_string<span class="Delimiter">(</span>out<span class="Delimiter">.</span>str<span class="Delimiter">());</span>
<span class="Delimiter">}</span>
-long long int trace_contents<span class="Delimiter">(</span>const string& layer<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+long long int trace_error_warning_contents<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!Trace_stream<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
+ ostringstream out<span class="Delimiter">;</span>
+ for <span class="Delimiter">(</span>vector<trace_line>::iterator p = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>p<span class="Delimiter">-></span>depth > Warning_depth<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ out << p<span class="Delimiter">-></span>contents<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>*--p<span class="Delimiter">-></span>contents<span class="Delimiter">.</span>end<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> out << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ string result = out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>result<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
+ truncate<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
+ <span class="Identifier">return</span> new_mu_string<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+long long int trace_app_contents<span class="Delimiter">()</span> <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>!Trace_stream<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
- if <span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span>layer<span class="Delimiter">)</span> <= <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
ostringstream out<span class="Delimiter">;</span>
for <span class="Delimiter">(</span>vector<trace_line>::iterator p = Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Trace_stream<span class="Delimiter">-></span>past_lines<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>p<span class="Delimiter">-></span>label != layer<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>p<span class="Delimiter">-></span>depth != App_depth<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
out << p<span class="Delimiter">-></span>contents<span class="Delimiter">;</span>
if <span class="Delimiter">(</span>*--p<span class="Delimiter">-></span>contents<span class="Delimiter">.</span>end<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> out << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
string result = out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
- assert<span class="Delimiter">(</span>!result<span class="Delimiter">.</span>empty<span class="Delimiter">());</span>
+ if <span class="Delimiter">(</span>result<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
truncate<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
<span class="Identifier">return</span> new_mu_string<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
@@ -349,51 +431,58 @@ void truncate<span class="Delimiter">(</span>string& x<span class="Delimiter
<span class="Delimiter">}</span>
<span class="Comment">//: simpler version of run-interactive: doesn't do any running, just loads</span>
-<span class="Comment">//: recipes and reports warnings.</span>
+<span class="Comment">//: recipes and reports errors+warnings.</span>
+
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
RELOAD<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"reload"</span>] = RELOAD<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"reload"</span><span class="Delimiter">,</span> RELOAD<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case RELOAD: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'reload' requires exactly one ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ 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>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'reload' requires exactly one ingredient, but got "</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>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'reload' should be a literal string, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>!is_mu_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'reload' should be a string, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>!Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- Trace_file = <span class="Constant">""</span><span class="Delimiter">;</span> <span class="Comment">// if there wasn't already a stream we don't want to save it</span>
- Trace_stream = new trace_stream<span class="Delimiter">;</span>
- Trace_stream<span class="Delimiter">-></span>collect_layers<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">"warn"</span><span class="Delimiter">);</span>
- <span class="Delimiter">}</span>
- Hide_warnings = <span class="Constant">true</span><span class="Delimiter">;</span>
- Disable_redefine_warnings = <span class="Constant">true</span><span class="Delimiter">;</span>
+ <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+case RELOAD: <span class="Delimiter">{</span>
<span class="Comment">// clear any containers in advance</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>recently_added_types<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
- Type_ordinal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>Type[recently_added_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span>]<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
+ Type_ordinal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> recently_added_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)).</span>name<span class="Delimiter">);</span>
Type<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>recently_added_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
<span class="Delimiter">}</span>
string code = read_mu_string<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
+ run_code_begin<span class="Delimiter">();</span>
+ routine* save_current_routine = Current_routine<span class="Delimiter">;</span>
+ Current_routine = <span class="Constant">NULL</span><span class="Delimiter">;</span>
vector<recipe_ordinal> recipes_reloaded = load<span class="Delimiter">(</span>code<span class="Delimiter">);</span>
for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>recipes_reloaded<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
Name<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>recipes_reloaded<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
<span class="Delimiter">}</span>
transform_all<span class="Delimiter">();</span>
Trace_stream<span class="Delimiter">-></span>newline<span class="Delimiter">();</span> <span class="Comment">// flush trace</span>
- Disable_redefine_warnings = <span class="Constant">false</span><span class="Delimiter">;</span>
- Hide_warnings = <span class="Constant">false</span><span class="Delimiter">;</span>
+ Current_routine = save_current_routine<span class="Delimiter">;</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
- products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>trace_contents<span class="Delimiter">(</span><span class="Constant">"warn"</span><span class="Delimiter">));</span>
- <span class="Comment">// hack: assume collect_layers isn't set anywhere else</span>
- if <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-></span>is_narrowly_collecting<span class="Delimiter">(</span><span class="Constant">"warn"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
- delete Trace_stream<span class="Delimiter">;</span>
- Trace_stream = <span class="Constant">NULL</span><span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
+ products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>trace_error_warning_contents<span class="Delimiter">());</span>
+ run_code_end<span class="Delimiter">();</span> <span class="Comment">// wait until we're done with the trace contents</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenario reload_continues_past_error)</span>
+recipe main [
+ local-scope
+ x:address:array:character<span class="Special"> <- </span>new [recipe foo [
+ get <span class="Constant">1234</span>:number<span class="Delimiter">,</span> foo:offset
+]]
+ reload x
+ <span class="Constant">1</span>:number/<span class="Special">raw <- </span>copy <span class="Constant">34</span>
+]
+<span class="traceContains">+mem: storing 34 in location 1</span>
</pre>
</body>
</html>
diff --git a/html/082persist.cc.html b/html/082persist.cc.html
index 01788333..1f6ed24f 100644
--- a/html/082persist.cc.html
+++ b/html/082persist.cc.html
@@ -14,7 +14,6 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
.cSpecial { color: #008000; }
-.PreProc { color: #c000c0; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Identifier { color: #804000; }
@@ -37,13 +36,28 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
RESTORE<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"restore"</span>] = RESTORE<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"restore"</span><span class="Delimiter">,</span> RESTORE<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case RESTORE: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'restore' requires exactly one ingredient, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ 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>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'restore' requires exactly one ingredient, but got "</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>
+ string filename<span class="Delimiter">;</span>
+ if <span class="Delimiter">(</span>is_literal_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ <span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ else if <span class="Delimiter">(</span>is_mu_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ <span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ else <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'restore' should be a string, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>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">:(before "End Primitive Recipe Implementations")</span>
+case RESTORE: <span class="Delimiter">{</span>
string filename<span class="Delimiter">;</span>
if <span class="Delimiter">(</span>is_literal_string<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
filename = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">;</span>
@@ -51,11 +65,12 @@ case RESTORE: <span class="Delimiter">{</span>
else if <span class="Delimiter">(</span>is_mu_string<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
filename = read_mu_string<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
<span class="Delimiter">}</span>
- else <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'restore' should be a string, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>Current_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ <span class="Comment">// do nothing in tests</span>
+ products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
+ products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>Current_scenario<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Comment">// do nothing in tests</span>
string contents = slurp<span class="Delimiter">(</span><span class="Constant">"lesson/"</span>+filename<span class="Delimiter">);</span>
products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
if <span class="Delimiter">(</span>contents<span class="Delimiter">.</span>empty<span class="Delimiter">())</span>
@@ -85,13 +100,31 @@ string slurp<span class="Delimiter">(</span>const string& filename<span clas
<span class="Delimiter">:(before "End Primitive Recipe Declarations")</span>
SAVE<span class="Delimiter">,</span>
<span class="Delimiter">:(before "End Primitive Recipe Numbers")</span>
-Recipe_ordinal[<span class="Constant">"save"</span>] = SAVE<span class="Delimiter">;</span>
-<span class="Delimiter">:(before "End Primitive Recipe Implementations")</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">"save"</span><span class="Delimiter">,</span> SAVE<span class="Delimiter">);</span>
+<span class="Delimiter">:(before "End Primitive Recipe Checks")</span>
case SAVE: <span class="Delimiter">{</span>
- if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": 'save' requires exactly two ingredients, but got "</span> << current_instruction<span class="Delimiter">().</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != <span class="Constant">2</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'save' requires exactly two ingredients, but got "</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>
+ if <span class="Delimiter">(</span>is_literal_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ <span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ else if <span class="Delimiter">(</span>is_mu_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ <span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ else <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'save' should be a string, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>!is_mu_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"second ingredient of 'save' should be an address:array:character, but got "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>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">:(before "End Primitive Recipe Implementations")</span>
+case SAVE: <span class="Delimiter">{</span>
if <span class="Delimiter">(</span>Current_scenario<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Comment">// do nothing in tests</span>
string filename<span class="Delimiter">;</span>
if <span class="Delimiter">(</span>is_literal_string<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
@@ -100,14 +133,6 @@ case SAVE: <span class="Delimiter">{</span>
else if <span class="Delimiter">(</span>is_mu_string<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
filename = read_mu_string<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
<span class="Delimiter">}</span>
- else <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": first ingredient of 'save' should be a string, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
- if <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
- raise << current_recipe_name<span class="Delimiter">()</span> << <span class="Constant">": second ingredient of 'save' should be an address:array:character, but got "</span> << current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
- <span class="Identifier">break</span><span class="Delimiter">;</span>
- <span class="Delimiter">}</span>
ofstream fout<span class="Delimiter">((</span><span class="Constant">"lesson/"</span>+filename<span class="Delimiter">).</span>c_str<span class="Delimiter">());</span>
string contents = read_mu_string<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
fout << contents<span class="Delimiter">;</span>
@@ -117,7 +142,7 @@ case SAVE: <span class="Delimiter">{</span>
<span class="Comment">// explicitly say '--all' for git 1.9</span>
int status = system<span class="Delimiter">(</span><span class="Constant">"cd lesson; git add --all .; git diff HEAD --exit-code >/dev/null || git commit -a -m . >/dev/null"</span><span class="Delimiter">);</span>
if <span class="Delimiter">(</span>status != <span class="Constant">0</span><span class="Delimiter">)</span>
- raise << <span class="Constant">"error in commit: contents "</span> << contents << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
+ raise_error << <span class="Constant">"error in commit: contents "</span> << contents << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span>
<span class="Identifier">break</span><span class="Delimiter">;</span>
<span class="Delimiter">}</span>
@@ -126,9 +151,6 @@ bool exists<span class="Delimiter">(</span>const string& filename<span class
struct stat dummy<span class="Delimiter">;</span>
<span class="Identifier">return</span> <span class="Constant">0</span> == stat<span class="Delimiter">(</span>filename<span class="Delimiter">.</span>c_str<span class="Delimiter">(),</span> &dummy<span class="Delimiter">);</span>
<span class="Delimiter">}</span>
-
-<span class="Delimiter">:(before "End Includes")</span>
-<span class="PreProc">#include</span><span class="Constant"><sys/stat.h></span>
</pre>
</body>
</html>
diff --git a/html/098check_type_pointers.cc.html b/html/098check_type_pointers.cc.html
new file mode 100644
index 00000000..74de0da6
--- /dev/null
+++ b/html/098check_type_pointers.cc.html
@@ -0,0 +1,67 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>Mu - 098check_type_pointers.cc</title>
+<meta name="Generator" content="Vim/7.4">
+<meta name="plugin-version" content="vim7.4_v1">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
+<meta name="colorscheme" content="minimal">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
+body { font-family: monospace; color: #eeeeee; background-color: #080808; }
+* { font-size: 1.05em; }
+.cSpecial { color: #008000; }
+.Constant { color: #00a0a0; }
+.Delimiter { color: #a04060; }
+.Identifier { color: #804000; }
+-->
+</style>
+
+<script type='text/javascript'>
+<!--
+
+-->
+</script>
+</head>
+<body>
+<pre id='vimCodeElement'>
+<span class="Delimiter">:(before "End Transform All")</span>
+check_type_pointers<span class="Delimiter">();</span>
+
+<span class="Delimiter">:(code)</span>
+void check_type_pointers<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+ for <span class="Delimiter">(</span>map<recipe_ordinal<span class="Delimiter">,</span> recipe>::iterator p = Recipe<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Recipe<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>any_type_ingredient_in_header<span class="Delimiter">(</span>p<span class="Delimiter">-></span>first<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+ const recipe& r = p<span class="Delimiter">-></span>second<span class="Delimiter">;</span>
+ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ const instruction& inst = r<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+ for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>type<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>r<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">" '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"' -- "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> << <span class="Constant">" has no type</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>r<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">" '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"' -- "</span> << inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> << <span class="Constant">" has no type name</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>type<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>r<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">" '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"' -- "</span> << inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> << <span class="Constant">" has no type</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+ raise_error << maybe<span class="Delimiter">(</span>r<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">" '"</span> << inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> << <span class="Constant">"' -- "</span> << inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> << <span class="Constant">" has no type name</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span>
+ <span class="Identifier">return</span><span class="Delimiter">;</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+ <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/html/999spaces.cc.html b/html/999spaces.cc.html
index dbcc31d2..dac58e9d 100644
--- a/html/999spaces.cc.html
+++ b/html/999spaces.cc.html
@@ -56,14 +56,11 @@ assert<span class="Delimiter">(</span>Next_recipe_ordinal == <span class="Consta
<span class="SalientComment">//:: Depths for tracing</span>
<span class="Comment">//:</span>
<span class="Comment">//: 0 - unused</span>
-<span class="Comment">//: 1-99 - app-level trace statements in mu</span>
-<span class="Comment">//: 100 - schedule</span>
-assert<span class="Delimiter">(</span>Scheduling_depth == <span class="Constant">100</span><span class="Delimiter">);</span>
-<span class="Comment">//: 101-9998 - call-stack statements (mostly label run)</span>
+<span class="Comment">//: 1-100 - app-level trace statements in mu</span>
+<span class="Comment">//: 101-9989 - call-stack statements (mostly label run)</span>
assert<span class="Delimiter">(</span>Initial_callstack_depth == <span class="Constant">101</span><span class="Delimiter">);</span>
-assert<span class="Delimiter">(</span>Max_callstack_depth == <span class="Constant">9998</span><span class="Delimiter">);</span>
-<span class="Comment">//: 9999 - intra-instruction lines (mostly label mem)</span>
-assert<span class="Delimiter">(</span>Primitive_recipe_depth == <span class="Constant">9999</span><span class="Delimiter">);</span>
+assert<span class="Delimiter">(</span>Max_callstack_depth == <span class="Constant">9989</span><span class="Delimiter">);</span>
+<span class="Comment">//: 9990-9999 - intra-instruction lines (mostly label mem)</span>
</pre>
</body>
</html>
diff --git a/html/channel.mu.html b/html/channel.mu.html
index 420eed5e..12babbde 100644
--- a/html/channel.mu.html
+++ b/html/channel.mu.html
@@ -13,12 +13,12 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
.muRecipe { color: #ff8700; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.Special { color: #ff6060; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
-->
</style>
@@ -33,11 +33,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># example program: communicating between routines using channels</span>
<span class="muRecipe">recipe</span> producer [
- <span class="Comment"># produce numbers 1 to 5 on a channel</span>
+ <span class="Comment"># produce characters 1 to 5 on a channel</span>
<span class="Constant">local-scope</span>
chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
<span class="Comment"># n = 0</span>
- n:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
+ n:character<span class="Special"> <- </span>copy <span class="Constant">0</span>
<span class="Delimiter">{</span>
done?:boolean<span class="Special"> <- </span>lesser-than n, <span class="Constant">5</span>
<span class="muControl">break-unless</span> done?
@@ -56,9 +56,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
chan:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
<span class="Delimiter">{</span>
<span class="Comment"># read an integer from the channel</span>
- n:number, chan:address:channel<span class="Special"> <- </span>read chan
+ n:character, chan:address:channel<span class="Special"> <- </span>read chan
<span class="Comment"># other threads might get between these prints</span>
- $print <span class="Constant">[consume: ]</span>, n:number, <span class="Constant">[ </span>
+ $print <span class="Constant">[consume: ]</span>, n:character, <span class="Constant">[ </span>
<span class="Constant">]</span>
<span class="muControl">loop</span>
<span class="Delimiter">}</span>
@@ -68,8 +68,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">local-scope</span>
chan:address:channel<span class="Special"> <- </span>new-channel <span class="Constant">3</span>
<span class="Comment"># create two background 'routines' that communicate by a channel</span>
- routine1:number<span class="Special"> <- </span>start-running <span class="Constant">producer:recipe</span>, chan
- routine2:number<span class="Special"> <- </span>start-running <span class="Constant">consumer:recipe</span>, chan
+ routine1:character<span class="Special"> <- </span>start-running <span class="Constant">producer:recipe</span>, chan
+ routine2:character<span class="Special"> <- </span>start-running <span class="Constant">consumer:recipe</span>, chan
wait-for-routine routine1
wait-for-routine routine2
]
diff --git a/html/chessboard.mu.html b/html/chessboard.mu.html
index 56b4842e..5e11ad01 100644
--- a/html/chessboard.mu.html
+++ b/html/chessboard.mu.html
@@ -13,16 +13,16 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
.muRecipe { color: #ff8700; }
-.muData { color: #ffff00; }
.SalientComment { color: #00ffff; }
-.muScenario { color: #00af00; }
+.muData { color: #ffff00; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.Special { color: #ff6060; }
.CommentedCode { color: #6c6c6c; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
+.muScenario { color: #00af00; }
-->
</style>
@@ -61,7 +61,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="SalientComment">## But enough about mu. Here's what it looks like to run the chessboard program.</span>
<span class="muScenario">scenario</span> print-board-and-read-move [
- $close-trace <span class="Comment"># administrivia: most scenarios save and check traces, but this one gets too large/slow</span>
+ trace-until <span class="Constant">100/app</span>
<span class="Comment"># we'll make the screen really wide because the program currently prints out a long line</span>
assume-screen <span class="Constant">120/width</span>, <span class="Constant">20/height</span>
<span class="Comment"># initialize keyboard to type in a move</span>
@@ -70,7 +70,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">]</span>
]
run [
- screen:address, console:address<span class="Special"> <- </span>chessboard screen:address, console:address
+ screen:address:screen, console:address:console<span class="Special"> <- </span>chessboard screen:address:screen, console:address:console
<span class="Comment"># icon for the cursor</span>
screen<span class="Special"> <- </span>print-character screen, <span class="Constant">9251/␣</span>
]
@@ -104,8 +104,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muRecipe">recipe</span> chessboard [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- console:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ console:address:console<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
board:address:array:address:array:character<span class="Special"> <- </span>initial-position
<span class="Comment"># hook up stdin</span>
stdin:address:channel<span class="Special"> <- </span>new-channel <span class="Constant">10/capacity</span>
@@ -147,7 +147,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muRecipe">recipe</span> new-board [
<span class="Constant">local-scope</span>
- initial-position:address:array:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ initial-position:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
<span class="Comment"># assert(length(initial-position) == 64)</span>
len:number<span class="Special"> <- </span>length *initial-position
correct-length?:boolean<span class="Special"> <- </span>equal len, <span class="Constant">64</span>
@@ -168,7 +168,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muRecipe">recipe</span> new-file [
<span class="Constant">local-scope</span>
- position:address:array:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ position:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
index:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
index<span class="Special"> <- </span>multiply index, <span class="Constant">8</span>
result:address:array:character<span class="Special"> <- </span>new <span class="Constant">character:type</span>, <span class="Constant">8</span>
@@ -187,7 +187,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muRecipe">recipe</span> print-board [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
board:address:array:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
row:number<span class="Special"> <- </span>copy <span class="Constant">7</span> <span class="Comment"># start printing from the top of the board</span>
<span class="Comment"># print each row</span>
@@ -236,7 +236,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># B P _ _ _ _ p B</span>
<span class="Comment"># N P _ _ _ _ p n</span>
<span class="Comment"># R P _ _ _ _ p r</span>
- initial-position:address:array:number<span class="Special"> <- </span>new-array <span class="Constant">82/R</span>, <span class="Constant">80/P</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">112/p</span>, <span class="Constant">114/r</span>, <span class="Constant">78/N</span>, <span class="Constant">80/P</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">112/p</span>, <span class="Constant">110/n</span>, <span class="Constant">66/B</span>, <span class="Constant">80/P</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">112/p</span>, <span class="Constant">98/b</span>, <span class="Constant">81/Q</span>, <span class="Constant">80/P</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">112/p</span>, <span class="Constant">113/q</span>, <span class="Constant">75/K</span>, <span class="Constant">80/P</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">112/p</span>, <span class="Constant">107/k</span>, <span class="Constant">66/B</span>, <span class="Constant">80/P</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">112/p</span>, <span class="Constant">98/b</span>, <span class="Constant">78/N</span>, <span class="Constant">80/P</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">112/p</span>, <span class="Constant">110/n</span>, <span class="Constant">82/R</span>, <span class="Constant">80/P</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">112/p</span>, <span class="Constant">114/r</span>
+ initial-position:address:array:character<span class="Special"> <- </span>new-array <span class="Constant">82/R</span>, <span class="Constant">80/P</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">112/p</span>, <span class="Constant">114/r</span>, <span class="Constant">78/N</span>, <span class="Constant">80/P</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">112/p</span>, <span class="Constant">110/n</span>, <span class="Constant">66/B</span>, <span class="Constant">80/P</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">112/p</span>, <span class="Constant">98/b</span>, <span class="Constant">81/Q</span>, <span class="Constant">80/P</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">112/p</span>, <span class="Constant">113/q</span>, <span class="Constant">75/K</span>, <span class="Constant">80/P</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">112/p</span>, <span class="Constant">107/k</span>, <span class="Constant">66/B</span>, <span class="Constant">80/P</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">112/p</span>, <span class="Constant">98/b</span>, <span class="Constant">78/N</span>, <span class="Constant">80/P</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">112/p</span>, <span class="Constant">110/n</span>, <span class="Constant">82/R</span>, <span class="Constant">80/P</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">32/blank</span>, <span class="Constant">112/p</span>, <span class="Constant">114/r</span>
<span class="CommentedCode">#? 82/R, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 114/r,</span>
<span class="CommentedCode">#? 78/N, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 110/n,</span>
<span class="CommentedCode">#? 66/B, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 98/b, </span>
@@ -253,7 +253,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-screen <span class="Constant">30/width</span>, <span class="Constant">12/height</span>
run [
<span class="Constant">1</span>:address:array:address:array:character/board<span class="Special"> <- </span>initial-position
- screen:address<span class="Special"> <- </span>print-board screen:address, <span class="Constant">1</span>:address:array:address:array:character/board
+ screen:address:screen<span class="Special"> <- </span>print-board screen:address:screen, <span class="Constant">1</span>:address:array:address:array:character/board
]
screen-should-contain [
<span class="Comment"># 012345678901234567890123456789</span>
@@ -282,12 +282,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
to-rank:number
]
-<span class="Comment"># result:address:move, quit?:boolean, error?:boolean <- read-move stdin:address:channel, screen:address</span>
+<span class="Comment"># result:address:move, quit?:boolean, error?:boolean <- read-move stdin:address:channel, screen:address:screen</span>
<span class="Comment"># prints only error messages to screen</span>
<span class="muRecipe">recipe</span> read-move [
<span class="Constant">local-scope</span>
stdin:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
from-file:number, quit?:boolean, error?:boolean<span class="Special"> <- </span>read-file stdin, screen
<span class="muControl">reply-if</span> quit?, <span class="Constant">0/dummy</span>, quit?, error?
<span class="muControl">reply-if</span> error?, <span class="Constant">0/dummy</span>, quit?, error?
@@ -314,12 +314,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">reply</span> result, quit?, error?
]
-<span class="Comment"># file:number, quit:boolean, error:boolean <- read-file stdin:address:channel, screen:address</span>
+<span class="Comment"># file:number, quit:boolean, error:boolean <- read-file stdin:address:channel, screen:address:screen</span>
<span class="Comment"># valid values for file: 0-7</span>
<span class="muRecipe">recipe</span> read-file [
<span class="Constant">local-scope</span>
stdin:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
c:character, stdin<span class="Special"> <- </span>read stdin
<span class="Delimiter">{</span>
q-pressed?:boolean<span class="Special"> <- </span>equal c, <span class="Constant">81/Q</span>
@@ -365,12 +365,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">reply</span> file, <span class="Constant">0/quit</span>, <span class="Constant">0/error</span>
]
-<span class="Comment"># rank:number <- read-rank stdin:address:channel, screen:address</span>
+<span class="Comment"># rank:number <- read-rank stdin:address:channel, screen:address:screen</span>
<span class="Comment"># valid values: 0-7, -1 (quit), -2 (error)</span>
<span class="muRecipe">recipe</span> read-rank [
<span class="Constant">local-scope</span>
stdin:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
c:character, stdin<span class="Special"> <- </span>read stdin
<span class="Delimiter">{</span>
q-pressed?:boolean<span class="Special"> <- </span>equal c, <span class="Constant">8/Q</span>
@@ -416,7 +416,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">local-scope</span>
stdin:address:channel<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
expected:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ screen:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
c:character, stdin<span class="Special"> <- </span>read stdin
<span class="Delimiter">{</span>
match?:boolean<span class="Special"> <- </span>equal c, expected
@@ -432,7 +432,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-screen <span class="Constant">20/width</span>, <span class="Constant">2/height</span>
run [
<span class="Constant">1</span>:address:channel<span class="Special"> <- </span>new-channel <span class="Constant">2</span>
- <span class="Constant">2</span>:number/routine<span class="Special"> <- </span>start-running <span class="Constant">read-move:recipe</span>, <span class="Constant">1</span>:address:channel, screen:address
+ <span class="Constant">2</span>:number/routine<span class="Special"> <- </span>start-running <span class="Constant">read-move:recipe</span>, <span class="Constant">1</span>:address:channel, screen:address:screen
<span class="Comment"># 'read-move' is waiting for input</span>
wait-for-routine <span class="Constant">2</span>:number
<span class="Constant">3</span>:number<span class="Special"> <- </span>routine-state <span class="Constant">2</span>:number/id
@@ -504,7 +504,7 @@ F read-move-blocking: routine failed to terminate on newline]
assume-screen <span class="Constant">20/width</span>, <span class="Constant">2/height</span>
run [
<span class="Constant">1</span>:address:channel<span class="Special"> <- </span>new-channel <span class="Constant">2</span>
- <span class="Constant">2</span>:number/routine<span class="Special"> <- </span>start-running <span class="Constant">read-move:recipe</span>, <span class="Constant">1</span>:address:channel, screen:address
+ <span class="Constant">2</span>:number/routine<span class="Special"> <- </span>start-running <span class="Constant">read-move:recipe</span>, <span class="Constant">1</span>:address:channel, screen:address:screen
<span class="Comment"># 'read-move' is waiting for input</span>
wait-for-routine <span class="Constant">2</span>:number
<span class="Constant">3</span>:number<span class="Special"> <- </span>routine-state <span class="Constant">2</span>:number/id
@@ -531,7 +531,7 @@ F read-move-quit: routine failed to terminate on 'q']
assume-screen <span class="Constant">20/width</span>, <span class="Constant">2/height</span>
run [
<span class="Constant">1</span>:address:channel<span class="Special"> <- </span>new-channel <span class="Constant">2</span>
- <span class="Constant">2</span>:number/routine<span class="Special"> <- </span>start-running <span class="Constant">read-move:recipe</span>, <span class="Constant">1</span>:address:channel, screen:address
+ <span class="Constant">2</span>:number/routine<span class="Special"> <- </span>start-running <span class="Constant">read-move:recipe</span>, <span class="Constant">1</span>:address:channel, screen:address:screen
<span class="Comment"># 'read-move' is waiting for input</span>
wait-for-routine <span class="Constant">2</span>:number
<span class="Constant">3</span>:number<span class="Special"> <- </span>routine-state <span class="Constant">2</span>:number/id
@@ -552,7 +552,7 @@ F read-move-file: routine failed to pause <span class="muRecipe">after</span> co
assume-screen <span class="Constant">20/width</span>, <span class="Constant">2/height</span>
run [
<span class="Constant">1</span>:address:channel<span class="Special"> <- </span>new-channel <span class="Constant">2</span>
- <span class="Constant">2</span>:number/routine<span class="Special"> <- </span>start-running <span class="Constant">read-move:recipe</span>, <span class="Constant">1</span>:address:channel, screen:address
+ <span class="Constant">2</span>:number/routine<span class="Special"> <- </span>start-running <span class="Constant">read-move:recipe</span>, <span class="Constant">1</span>:address:channel, screen:address:screen
<span class="Comment"># 'read-move' is waiting for input</span>
wait-for-routine <span class="Constant">2</span>:number
<span class="Constant">3</span>:number<span class="Special"> <- </span>routine-state <span class="Constant">2</span>:number/id
@@ -574,7 +574,7 @@ F read-move-file: routine failed to pause <span class="muRecipe">after</span> co
assume-screen <span class="Constant">20/width</span>, <span class="Constant">2/height</span>
run [
<span class="Constant">1</span>:address:channel<span class="Special"> <- </span>new-channel <span class="Constant">2</span>
- <span class="Constant">2</span>:number/routine<span class="Special"> <- </span>start-running <span class="Constant">read-move:recipe</span>, <span class="Constant">1</span>:address:channel, screen:address
+ <span class="Constant">2</span>:number/routine<span class="Special"> <- </span>start-running <span class="Constant">read-move:recipe</span>, <span class="Constant">1</span>:address:channel, screen:address:screen
<span class="Comment"># 'read-move' is waiting for input</span>
wait-for-routine <span class="Constant">2</span>:number
<span class="Constant">3</span>:number<span class="Special"> <- </span>routine-state <span class="Constant">2</span>:number/id
@@ -623,7 +623,7 @@ F read-move-file: routine failed to pause <span class="muRecipe">after</span> co
<span class="Constant">7</span>:address:number<span class="Special"> <- </span>get-address *<span class="Constant">3</span>:address:move, <span class="Constant">to-rank:offset</span>
*<span class="Constant">7</span>:address:number<span class="Special"> <- </span>copy <span class="Constant">3/'4'</span>
<span class="Constant">2</span>:address:array:address:array:character/board<span class="Special"> <- </span>make-move <span class="Constant">2</span>:address:array:address:array:character/board, <span class="Constant">3</span>:address:move
- screen:address<span class="Special"> <- </span>print-board screen:address, <span class="Constant">2</span>:address:array:address:array:character/board
+ screen:address:screen<span class="Special"> <- </span>print-board screen:address:screen, <span class="Constant">2</span>:address:array:address:array:character/board
]
screen-should-contain [
<span class="Comment"># 012345678901234567890123456789</span>
diff --git a/html/console.mu.html b/html/console.mu.html
index 116fb450..1a14d4ed 100644
--- a/html/console.mu.html
+++ b/html/console.mu.html
@@ -13,12 +13,12 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
.muRecipe { color: #ff8700; }
.Comment { color: #9090ff; }
.Delimiter { color: #a04060; }
.Special { color: #ff6060; }
.Constant { color: #00a0a0; }
-.muControl { color: #c0a020; }
-->
</style>
diff --git a/html/counters.mu.html b/html/counters.mu.html
index 9a02adca..495def81 100644
--- a/html/counters.mu.html
+++ b/html/counters.mu.html
@@ -17,7 +17,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.Special { color: #ff6060; }
-.muControl { color: #c0a020; }
-->
</style>
@@ -32,18 +31,16 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># example program: maintain multiple counters with isolated lexical scopes</span>
<span class="Comment"># (spaces)</span>
-<span class="muRecipe">recipe</span> new-counter [
- <span class="Constant">default-space</span>:address:array:location<span class="Special"> <- </span>new <span class="Constant">location:type</span>, <span class="Constant">30</span>
- n:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- <span class="muControl">reply</span> <span class="Constant">default-space</span>
+<span class="muRecipe">recipe</span> new-counter n:number<span class="muRecipe"> -> </span><span class="Constant">default-space</span>:address:array:location [
+ <span class="Constant">default-space</span><span class="Special"> <- </span>new <span class="Constant">location:type</span>, <span class="Constant">30</span>
+ <span class="Constant">load-ingredients</span>
]
-<span class="muRecipe">recipe</span> increment-counter [
+<span class="muRecipe">recipe</span> increment-counter outer:address:array:location/names:new-counter, x:number<span class="muRecipe"> -> </span>n:number/space:<span class="Constant">1</span> [
<span class="Constant">local-scope</span>
- <span class="Constant">0</span>:address:array:location/names:new-counter<span class="Special"> <- </span><span class="Constant">next-ingredient</span> <span class="Comment"># setup outer space; it *must* come from 'new-counter'</span>
- x:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- n:number/space:<span class="Constant">1</span><span class="Special"> <- </span>add n:number/space:<span class="Constant">1</span>, x
- <span class="muControl">reply</span> n:number/space:<span class="Constant">1</span>
+ <span class="Constant">load-ingredients</span>
+ <span class="Constant">0</span>:address:array:location/names:new-counter<span class="Special"> <- </span>copy outer <span class="Comment"># setup outer space; it *must* come from 'new-counter'</span>
+ n/space:<span class="Constant">1</span><span class="Special"> <- </span>add n/space:<span class="Constant">1</span>, x
]
<span class="muRecipe">recipe</span> main [
diff --git a/html/edit/001-editor.mu.html b/html/edit/001-editor.mu.html
index be568c9d..916e93c6 100644
--- a/html/edit/001-editor.mu.html
+++ b/html/edit/001-editor.mu.html
@@ -13,15 +13,15 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
.muRecipe { color: #ff8700; }
+.muScenario { color: #00af00; }
.muData { color: #ffff00; }
.Special { color: #ff6060; }
-.muScenario { color: #00af00; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.SalientComment { color: #00ffff; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
-->
</style>
@@ -37,9 +37,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># temporary main for this layer: just render the given string at the given</span>
<span class="Comment"># screen dimensions, then stop</span>
-<span class="muRecipe">recipe!</span> main [
+<span class="muRecipe">recipe!</span> main text:address:array:character [
<span class="Constant">local-scope</span>
- text:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
open-console
hide-screen <span class="Constant">0/screen</span>
new-editor text, <span class="Constant">0/screen</span>, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
@@ -52,7 +52,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
run [
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
- new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
]
screen-should-contain [
<span class="Comment"># top line of screen reserved for menu</span>
@@ -79,19 +79,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
cursor-column:number
]
-<span class="Comment"># editor:address, screen <- new-editor s:address:array:character, screen:address, left:number, right:number</span>
-<span class="Comment"># creates a new editor widget and renders its initial appearance to screen.</span>
-<span class="Comment"># top/left/right constrain the screen area available to the new editor.</span>
-<span class="Comment"># right is exclusive.</span>
-<span class="muRecipe">recipe</span> new-editor [
+<span class="Comment"># creates a new editor widget and renders its initial appearance to screen</span>
+<span class="Comment"># top/left/right constrain the screen area available to the new editor</span>
+<span class="Comment"># right is exclusive</span>
+<span class="muRecipe">recipe</span> new-editor s:address:array:character, screen:address:screen, left:number, right:number<span class="muRecipe"> -> </span>result:address:editor-data [
<span class="Constant">local-scope</span>
- s:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
<span class="Comment"># no clipping of bounds</span>
- left:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- right:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
right<span class="Special"> <- </span>subtract right, <span class="Constant">1</span>
- result:address:editor-data<span class="Special"> <- </span>new <span class="Constant">editor-data:type</span>
+ result<span class="Special"> <- </span>new <span class="Constant">editor-data:type</span>
<span class="Comment"># initialize screen-related fields</span>
x:address:number<span class="Special"> <- </span>get-address *result, <span class="Constant">left:offset</span>
*x<span class="Special"> <- </span>copy left
@@ -102,11 +98,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
*x<span class="Special"> <- </span>copy <span class="Constant">1/top</span>
x<span class="Special"> <- </span>get-address *result, <span class="Constant">cursor-column:offset</span>
*x<span class="Special"> <- </span>copy left
- init:address:address:duplex-list<span class="Special"> <- </span>get-address *result, <span class="Constant">data:offset</span>
+ init:address:address:duplex-list:character<span class="Special"> <- </span>get-address *result, <span class="Constant">data:offset</span>
*init<span class="Special"> <- </span>push-duplex <span class="Constant">167/§</span>, <span class="Constant">0/tail</span>
- top-of-screen:address:address:duplex-list<span class="Special"> <- </span>get-address *result, <span class="Constant">top-of-screen:offset</span>
+ top-of-screen:address:address:duplex-list:character<span class="Special"> <- </span>get-address *result, <span class="Constant">top-of-screen:offset</span>
*top-of-screen<span class="Special"> <- </span>copy *init
- y:address:address:duplex-list<span class="Special"> <- </span>get-address *result, <span class="Constant">before-cursor:offset</span>
+ y:address:address:duplex-list:character<span class="Special"> <- </span>get-address *result, <span class="Constant">before-cursor:offset</span>
*y<span class="Special"> <- </span>copy *init
result<span class="Special"> <- </span>insert-text result, s
<span class="Comment"># initialize cursor to top of screen</span>
@@ -115,20 +111,18 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># initial render to screen, just for some old tests</span>
_, _, screen, result<span class="Special"> <- </span>render screen, result
<span class="Constant"> <editor-initialization></span>
- <span class="muControl">reply</span> result
]
-<span class="muRecipe">recipe</span> insert-text [
+<span class="muRecipe">recipe</span> insert-text editor:address:editor-data, text:address:array:character<span class="muRecipe"> -> </span>editor:address:editor-data [
<span class="Constant">local-scope</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- text:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
<span class="Comment"># early exit if text is empty</span>
<span class="muControl">reply-unless</span> text, editor/same-as-ingredient:<span class="Constant">0</span>
len:number<span class="Special"> <- </span>length *text
<span class="muControl">reply-unless</span> len, editor/same-as-ingredient:<span class="Constant">0</span>
idx:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
<span class="Comment"># now we can start appending the rest, character by character</span>
- curr:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">data:offset</span>
+ curr:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">data:offset</span>
<span class="Delimiter">{</span>
done?:boolean<span class="Special"> <- </span>greater-or-equal idx, len
<span class="muControl">break-if</span> done?
@@ -145,7 +139,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> editor-initializes-without-data [
assume-screen <span class="Constant">5/width</span>, <span class="Constant">3/height</span>
run [
- <span class="Constant">1</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">0/data</span>, screen:address, <span class="Constant">2/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">1</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">0/data</span>, screen:address:screen, <span class="Constant">2/left</span>, <span class="Constant">5/right</span>
<span class="Constant">2</span>:editor-data<span class="Special"> <- </span>copy *<span class="Constant">1</span>:address:editor-data
]
memory-should-contain [
@@ -165,22 +159,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
]
-<span class="Comment"># last-row:number, last-column:number, screen, editor <- render screen:address, editor:address:editor-data</span>
-<span class="Comment">#</span>
<span class="Comment"># Assumes cursor should be at coordinates (cursor-row, cursor-column) and</span>
<span class="Comment"># updates before-cursor to match. Might also move coordinates if they're</span>
<span class="Comment"># outside text.</span>
-<span class="muRecipe">recipe</span> render [
+<span class="muRecipe">recipe</span> render screen:address:screen, editor:address:editor-data<span class="muRecipe"> -> </span>last-row:number, last-column:number, screen:address:screen, editor:address:editor-data [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
<span class="muControl">reply-unless</span> editor, <span class="Constant">1/top</span>, <span class="Constant">0/left</span>, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>
left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span>
screen-height:number<span class="Special"> <- </span>screen-height screen
right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span>
<span class="Comment"># traversing editor</span>
- curr:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
- prev:address:duplex-list<span class="Special"> <- </span>copy curr <span class="Comment"># just in case curr becomes null and we can't compute prev-duplex</span>
+ curr:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ prev:address:duplex-list:character<span class="Special"> <- </span>copy curr <span class="Comment"># just in case curr becomes null and we can't compute prev-duplex</span>
curr<span class="Special"> <- </span>next-duplex curr
<span class="Comment"># traversing screen</span>
<span class="Constant"> +render-loop-initialization</span>
@@ -189,7 +180,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
column:number<span class="Special"> <- </span>copy left
cursor-row:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-row:offset</span>
cursor-column:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-column:offset</span>
- before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
+ before-cursor:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
screen<span class="Special"> <- </span>move-cursor screen, row, column
<span class="Delimiter">{</span>
<span class="Constant"> +next-character</span>
@@ -251,7 +242,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">loop</span>
<span class="Delimiter">}</span>
<span class="Comment"># save first character off-screen</span>
- bottom-of-screen:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">bottom-of-screen:offset</span>
+ bottom-of-screen:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">bottom-of-screen:offset</span>
*bottom-of-screen<span class="Special"> <- </span>copy curr
<span class="Comment"># is cursor to the right of the last line? move to end</span>
<span class="Delimiter">{</span>
@@ -268,11 +259,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">reply</span> row, column, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>
]
-<span class="muRecipe">recipe</span> clear-line-delimited [
+<span class="muRecipe">recipe</span> clear-line-delimited screen:address:screen, column:number, right:number [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- column:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- right:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
<span class="Delimiter">{</span>
done?:boolean<span class="Special"> <- </span>greater-than column, right
<span class="muControl">break-if</span> done?
@@ -282,13 +271,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">}</span>
]
-<span class="muRecipe">recipe</span> clear-screen-from [
+<span class="muRecipe">recipe</span> clear-screen-from screen:address:screen, row:number, column:number, left:number, right:number<span class="muRecipe"> -> </span>screen:address:screen [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- row:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- column:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- left:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- right:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
<span class="Comment"># if it's the real screen, use the optimized primitive</span>
<span class="Delimiter">{</span>
<span class="muControl">break-if</span> screen
@@ -302,12 +287,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>
]
-<span class="muRecipe">recipe</span> clear-rest-of-screen [
+<span class="muRecipe">recipe</span> clear-rest-of-screen screen:address:screen, row:number, left:number, right:number [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- row:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- left:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- right:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
row<span class="Special"> <- </span>add row, <span class="Constant">1</span>
screen<span class="Special"> <- </span>move-cursor screen, row, left
screen-height:number<span class="Special"> <- </span>screen-height screen
@@ -326,7 +308,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
run [
s:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def]</span>
- new-editor s:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ new-editor s:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -340,7 +322,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-screen <span class="Constant">5/width</span>, <span class="Constant">5/height</span>
run [
s:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
- new-editor s:address:array:character, screen:address, <span class="Constant">1/left</span>, <span class="Constant">5/right</span>
+ new-editor s:address:array:character, screen:address:screen, <span class="Constant">1/left</span>, <span class="Constant">5/right</span>
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -354,7 +336,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
run [
s:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def]</span>
- new-editor s:address:array:character, screen:address, <span class="Constant">1/left</span>, <span class="Constant">5/right</span>
+ new-editor s:address:array:character, screen:address:screen, <span class="Constant">1/left</span>, <span class="Constant">5/right</span>
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -368,7 +350,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-screen <span class="Constant">5/width</span>, <span class="Constant">5/height</span>
run [
s:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc def]</span>
- new-editor s:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ new-editor s:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -388,7 +370,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-screen <span class="Constant">5/width</span>, <span class="Constant">5/height</span>
run [
s:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcde]</span>
- new-editor s:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ new-editor s:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
]
<span class="Comment"># still wrap, even though the line would fit. We need room to click on the</span>
<span class="Comment"># end of the line</span>
@@ -410,7 +392,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-screen <span class="Constant">5/width</span>, <span class="Constant">5/height</span>
run [
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -433,7 +415,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
s:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant"># de</span>
<span class="Constant">f]</span>
- new-editor s:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ new-editor s:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -462,12 +444,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
color<span class="Special"> <- </span>get-color color, c
]
-<span class="Comment"># color <- get-color color:number, c:character</span>
<span class="Comment"># so far the previous color is all the information we need; that may change</span>
-<span class="muRecipe">recipe</span> get-color [
+<span class="muRecipe">recipe</span> get-color color:number, c:character<span class="muRecipe"> -> </span>color:number [
<span class="Constant">local-scope</span>
- color:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- c:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
color-is-white?:boolean<span class="Special"> <- </span>equal color, <span class="Constant">7/white</span>
<span class="Comment"># if color is white and next character is '#', switch color to blue</span>
<span class="Delimiter">{</span>
@@ -516,7 +496,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
s:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">d <- e</span>
<span class="Constant">f]</span>
- new-editor s:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">8/right</span>
+ new-editor s:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">8/right</span>
]
screen-should-contain [
<span class="Constant"> . .</span>
diff --git a/html/edit/002-typing.mu.html b/html/edit/002-typing.mu.html
index 787e3a4e..c1f1128f 100644
--- a/html/edit/002-typing.mu.html
+++ b/html/edit/002-typing.mu.html
@@ -13,15 +13,15 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
.muRecipe { color: #ff8700; }
-.muData { color: #ffff00; }
.Special { color: #ff6060; }
-.muScenario { color: #00af00; }
+.muData { color: #ffff00; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.SalientComment { color: #00ffff; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
+.muScenario { color: #00af00; }
-->
</style>
@@ -37,27 +37,25 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># temporary main: interactive editor</span>
<span class="Comment"># hit ctrl-c to exit</span>
-<span class="muRecipe">recipe!</span> main [
+<span class="muRecipe">recipe!</span> main text:address:array:character [
<span class="Constant">local-scope</span>
- text:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
open-console
editor:address:editor-data<span class="Special"> <- </span>new-editor text, <span class="Constant">0/screen</span>, <span class="Constant">5/left</span>, <span class="Constant">45/right</span>
editor-event-loop <span class="Constant">0/screen</span>, <span class="Constant">0/console</span>, editor
close-console
]
-<span class="muRecipe">recipe</span> editor-event-loop [
+<span class="muRecipe">recipe</span> editor-event-loop screen:address:screen, console:address:console, editor:address:editor-data [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- console:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
<span class="Delimiter">{</span>
<span class="Comment"># looping over each (keyboard or touch) event as it occurs</span>
<span class="Constant"> +next-event</span>
cursor-row:number<span class="Special"> <- </span>get *editor, <span class="Constant">cursor-row:offset</span>
cursor-column:number<span class="Special"> <- </span>get *editor, <span class="Constant">cursor-column:offset</span>
screen<span class="Special"> <- </span>move-cursor screen, cursor-row, cursor-column
- e:event, console:address, found?:boolean, quit?:boolean<span class="Special"> <- </span>read-event console
+ e:event, console:address:console, found?:boolean, quit?:boolean<span class="Special"> <- </span>read-event console
<span class="muControl">loop-unless</span> found?
<span class="muControl">break-if</span> quit? <span class="Comment"># only in tests</span>
trace <span class="Constant">10</span>, <span class="Constant">[app]</span>, <span class="Constant">[next-event]</span>
@@ -82,11 +80,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
<span class="Comment"># process click, return if it was on current editor</span>
-<span class="muRecipe">recipe</span> move-cursor-in-editor [
+<span class="muRecipe">recipe</span> move-cursor-in-editor screen:address:screen, editor:address:editor-data, t:touch-event<span class="muRecipe"> -> </span>in-focus?:boolean [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- t:touch-event<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
<span class="muControl">reply-unless</span> editor, <span class="Constant">0/false</span>
click-row:number<span class="Special"> <- </span>get t, <span class="Constant">row:offset</span>
<span class="muControl">reply-unless</span> click-row, <span class="Constant">0/false</span> <span class="Comment"># ignore clicks on 'menu'</span>
@@ -106,24 +102,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">reply</span> <span class="Constant">1/true</span>
]
-<span class="Comment"># editor <- snap-cursor screen:address, editor:address:editor-data, target-row:number, target-column:number</span>
-<span class="Comment">#</span>
<span class="Comment"># Variant of 'render' that only moves the cursor (coordinates and</span>
<span class="Comment"># before-cursor). If it's past the end of a line, it 'slides' it left. If it's</span>
<span class="Comment"># past the last line it positions at end of last line.</span>
-<span class="muRecipe">recipe</span> snap-cursor [
+<span class="muRecipe">recipe</span> snap-cursor screen:address:screen, editor:address:editor-data, target-row:number, target-column:number<span class="muRecipe"> -> </span>editor:address:editor-data [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- target-row:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- target-column:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- <span class="muControl">reply-unless</span> editor, <span class="Constant">1/top</span>, editor/same-as-ingredient:<span class="Constant">1</span>
+ <span class="Constant">load-ingredients</span>
+ <span class="muControl">reply-unless</span> editor
left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span>
right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span>
screen-height:number<span class="Special"> <- </span>screen-height screen
<span class="Comment"># count newlines until screen row</span>
- curr:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
- prev:address:duplex-list<span class="Special"> <- </span>copy curr <span class="Comment"># just in case curr becomes null and we can't compute prev-duplex</span>
+ curr:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ prev:address:duplex-list:character<span class="Special"> <- </span>copy curr <span class="Comment"># just in case curr becomes null and we can't compute prev-duplex</span>
curr<span class="Special"> <- </span>next-duplex curr
row:number<span class="Special"> <- </span>copy <span class="Constant">1/top</span>
column:number<span class="Special"> <- </span>copy left
@@ -131,7 +122,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
*cursor-row<span class="Special"> <- </span>copy target-row
cursor-column:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-column:offset</span>
*cursor-column<span class="Special"> <- </span>copy target-column
- before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
+ before-cursor:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
<span class="Delimiter">{</span>
<span class="Constant"> +next-character</span>
<span class="muControl">break-unless</span> curr
@@ -195,23 +186,20 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
*cursor-column<span class="Special"> <- </span>copy column
*before-cursor<span class="Special"> <- </span>copy prev
<span class="Delimiter">}</span>
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">1</span>
]
-<span class="Comment"># screen, editor, go-render?:boolean <- handle-keyboard-event screen:address, editor:address:editor-data, e:event</span>
<span class="Comment"># Process an event 'e' and try to minimally update the screen.</span>
<span class="Comment"># Set 'go-render?' to true to indicate the caller must perform a non-minimal update.</span>
-<span class="muRecipe">recipe</span> handle-keyboard-event [
+<span class="muRecipe">recipe</span> handle-keyboard-event screen:address:screen, editor:address:editor-data, e:event<span class="muRecipe"> -> </span>screen:address:screen, editor:address:editor-data, go-render?:boolean [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- e:event<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- <span class="muControl">reply-unless</span> editor, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span>
+ <span class="Constant">load-ingredients</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
+ <span class="muControl">reply-unless</span> editor
screen-width:number<span class="Special"> <- </span>screen-width screen
screen-height:number<span class="Special"> <- </span>screen-height screen
left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span>
right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span>
- before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
+ before-cursor:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
cursor-row:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-row:offset</span>
cursor-column:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-column:offset</span>
save-row:number<span class="Special"> <- </span>copy *cursor-row
@@ -225,27 +213,27 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> <handle-special-character></span>
<span class="Comment"># ignore any other special characters</span>
regular-character?:boolean<span class="Special"> <- </span>greater-or-equal *c, <span class="Constant">32/space</span>
- <span class="muControl">reply-unless</span> regular-character?, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
+ <span class="muControl">reply-unless</span> regular-character?
<span class="Comment"># otherwise type it in</span>
<span class="Constant"> <insert-character-begin></span>
editor, screen, go-render?:boolean<span class="Special"> <- </span>insert-at-cursor editor, *c, screen
<span class="Constant"> <insert-character-end></span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, go-render?
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
<span class="Comment"># special key to modify the text or move the cursor</span>
k:address:number<span class="Special"> <- </span>maybe-convert e:event, <span class="Constant">keycode:variant</span>
assert k, <span class="Constant">[event was of unknown type; neither keyboard nor mouse]</span>
<span class="Comment"># handlers for each special key will go here</span>
<span class="Constant"> <handle-special-key></span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
+ <span class="muControl">reply</span>
]
-<span class="muRecipe">recipe</span> insert-at-cursor [
+<span class="muRecipe">recipe</span> insert-at-cursor editor:address:editor-data, c:character, screen:address:screen<span class="muRecipe"> -> </span>editor:address:editor-data, screen:address:screen, go-render?:boolean [
<span class="Constant">local-scope</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- c:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
+ <span class="Constant">load-ingredients</span>
+ before-cursor:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
insert-duplex c, *before-cursor
*before-cursor<span class="Special"> <- </span>next-duplex *before-cursor
cursor-row:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-row:offset</span>
@@ -260,7 +248,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> <insert-character-special-case></span>
<span class="Comment"># but mostly we'll just move the cursor right</span>
*cursor-column<span class="Special"> <- </span>add *cursor-column, <span class="Constant">1</span>
- next:address:duplex-list<span class="Special"> <- </span>next-duplex *before-cursor
+ next:address:duplex-list:character<span class="Special"> <- </span>next-duplex *before-cursor
<span class="Delimiter">{</span>
<span class="Comment"># at end of all text? no need to scroll? just print the character and leave</span>
at-end?:boolean<span class="Special"> <- </span>equal next, <span class="Constant">0/null</span>
@@ -272,20 +260,22 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">break-if</span> overflow?
move-cursor screen, save-row, save-column
print-character screen, c
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">2</span>, <span class="Constant">0/no-more-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
<span class="Delimiter">{</span>
<span class="Comment"># not at right margin? print the character and rest of line</span>
<span class="muControl">break-unless</span> next
at-right?:boolean<span class="Special"> <- </span>greater-or-equal *cursor-column, screen-width
<span class="muControl">break-if</span> at-right?
- curr:address:duplex-list<span class="Special"> <- </span>copy *before-cursor
+ curr:address:duplex-list:character<span class="Special"> <- </span>copy *before-cursor
move-cursor screen, save-row, save-column
curr-column:number<span class="Special"> <- </span>copy save-column
<span class="Delimiter">{</span>
<span class="Comment"># hit right margin? give up and let caller render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
at-right?:boolean<span class="Special"> <- </span>greater-than curr-column, right
- <span class="muControl">reply-if</span> at-right?, editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">2</span>, <span class="Constant">1/go-render</span>
+ <span class="muControl">reply-if</span> at-right?
<span class="muControl">break-unless</span> curr
<span class="Comment"># newline? done.</span>
currc:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span>
@@ -296,16 +286,17 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
curr<span class="Special"> <- </span>next-duplex curr
<span class="muControl">loop</span>
<span class="Delimiter">}</span>
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">2</span>, <span class="Constant">0/no-more-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">2</span>, <span class="Constant">1/go-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
+ <span class="muControl">reply</span>
]
<span class="Comment"># helper for tests</span>
-<span class="muRecipe">recipe</span> editor-render [
+<span class="muRecipe">recipe</span> editor-render screen:address:screen, editor:address:editor-data<span class="muRecipe"> -> </span>screen:address:screen [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span>
right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span>
row:number, column:number<span class="Special"> <- </span>render screen, editor
@@ -319,11 +310,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> editor-handles-empty-event-queue [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
assume-console <span class="Constant">[]</span>
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -336,14 +327,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> editor-handles-mouse-clicks [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
assume-console [
left-click <span class="Constant">1</span>, <span class="Constant">1</span> <span class="Comment"># on the 'b'</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -363,13 +354,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> editor-handles-mouse-clicks-outside-text [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
<span class="Constant"> $clear-trace</span>
assume-console [
left-click <span class="Constant">1</span>, <span class="Constant">7</span> <span class="Comment"># last line, to the right of text</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -384,13 +375,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
<span class="Constant"> $clear-trace</span>
assume-console [
left-click <span class="Constant">1</span>, <span class="Constant">7</span> <span class="Comment"># interior line, to the right of text</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -405,13 +396,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
<span class="Constant"> $clear-trace</span>
assume-console [
left-click <span class="Constant">3</span>, <span class="Constant">7</span> <span class="Comment"># below text</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -426,7 +417,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
<span class="Comment"># editor occupies only left half of screen</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
assume-console [
@@ -434,7 +425,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
left-click <span class="Constant">3</span>, <span class="Constant">8</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -454,7 +445,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> editor-handles-mouse-clicks-in-menu-area [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
assume-console [
@@ -462,7 +453,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
left-click <span class="Constant">0</span>, <span class="Constant">3</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -476,14 +467,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> editor-inserts-characters-into-empty-editor [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
assume-console [
type <span class="Constant">[abc]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -497,7 +488,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> editor-inserts-characters-at-cursor [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
<span class="Comment"># type two letters at different places</span>
@@ -507,7 +498,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[d]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -521,7 +512,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> editor-inserts-characters-at-cursor-2 [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
assume-console [
@@ -529,7 +520,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[d]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -544,7 +535,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">d]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
assume-console [
@@ -552,7 +543,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[e]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -567,7 +558,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> editor-inserts-characters-at-cursor-3 [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
assume-console [
@@ -575,7 +566,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[d]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -590,7 +581,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">d]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
assume-console [
@@ -598,7 +589,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[e]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -614,7 +605,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">d]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
assume-console [
@@ -622,7 +613,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[ef]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -637,13 +628,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> editor-moves-cursor-after-inserting-characters [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ab]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
assume-console [
type <span class="Constant">[01]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -658,14 +649,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> editor-wraps-line-on-insert [
assume-screen <span class="Constant">5/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># type a letter</span>
assume-console [
type <span class="Constant">[e]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># no wrap yet</span>
screen-should-contain [
@@ -680,7 +671,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[f]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># now wrap</span>
screen-should-contain [
@@ -697,7 +688,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcdefg</span>
<span class="Constant">defg]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># type more text at the start</span>
assume-console [
@@ -705,7 +696,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[abc]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -740,20 +731,21 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">break-unless</span> below-screen?
<span class="Constant"> <scroll-down></span>
<span class="Delimiter">}</span>
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">2</span>, <span class="Constant">1/go-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
<span class="muScenario">scenario</span> editor-wraps-cursor-after-inserting-characters [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcde]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
assume-console [
left-click <span class="Constant">1</span>, <span class="Constant">4</span> <span class="Comment"># line is full; no wrap icon yet</span>
type <span class="Constant">[f]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -773,13 +765,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> editor-wraps-cursor-after-inserting-characters-2 [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcde]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
assume-console [
left-click <span class="Constant">1</span>, <span class="Constant">3</span> <span class="Comment"># right before the wrap icon</span>
type <span class="Constant">[f]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -799,13 +791,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> editor-wraps-cursor-to-left-margin [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcde]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">2/left</span>, <span class="Constant">7/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">2/left</span>, <span class="Constant">7/right</span>
assume-console [
left-click <span class="Constant">1</span>, <span class="Constant">5</span> <span class="Comment"># line is full; no wrap icon yet</span>
type <span class="Constant">[01]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -836,13 +828,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> editor-moves-cursor-down-after-inserting-newline [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
assume-console [
type <span class="Constant">[0</span>
<span class="Constant">1]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -860,17 +852,17 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> <insert-enter-begin></span>
editor<span class="Special"> <- </span>insert-new-line-and-indent editor, screen
<span class="Constant"> <insert-enter-end></span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
-<span class="muRecipe">recipe</span> insert-new-line-and-indent [
+<span class="muRecipe">recipe</span> insert-new-line-and-indent editor:address:editor-data, screen:address:screen<span class="muRecipe"> -> </span>editor:address:editor-data, screen:address:screen, go-render?:boolean [
<span class="Constant">local-scope</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
cursor-row:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-row:offset</span>
cursor-column:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-column:offset</span>
- before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
+ before-cursor:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span>
right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span>
screen-height:number<span class="Special"> <- </span>screen-height screen
@@ -884,13 +876,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
below-screen?:boolean<span class="Special"> <- </span>greater-or-equal *cursor-row, screen-height <span class="Comment"># must be equal, never greater</span>
<span class="muControl">break-unless</span> below-screen?
<span class="Constant"> <scroll-down></span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
*cursor-row<span class="Special"> <- </span>subtract *cursor-row, <span class="Constant">1</span> <span class="Comment"># bring back into screen range</span>
<span class="Delimiter">}</span>
<span class="Comment"># indent if necessary</span>
indent?:boolean<span class="Special"> <- </span>get *editor, <span class="Constant">indent?:offset</span>
- <span class="muControl">reply-unless</span> indent?, editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>
- d:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">data:offset</span>
- end-of-previous-line:address:duplex-list<span class="Special"> <- </span>prev-duplex *before-cursor
+ <span class="muControl">reply-unless</span> indent?
+ d:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">data:offset</span>
+ end-of-previous-line:address:duplex-list:character<span class="Special"> <- </span>prev-duplex *before-cursor
indent:number<span class="Special"> <- </span>line-indent end-of-previous-line, d
i:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
<span class="Delimiter">{</span>
@@ -900,19 +893,17 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
i<span class="Special"> <- </span>add i, <span class="Constant">1</span>
<span class="muControl">loop</span>
<span class="Delimiter">}</span>
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>
]
<span class="Comment"># takes a pointer 'curr' into the doubly-linked list and its sentinel, counts</span>
<span class="Comment"># the number of spaces at the start of the line containing 'curr'.</span>
-<span class="muRecipe">recipe</span> line-indent [
+<span class="muRecipe">recipe</span> line-indent curr:address:duplex-list:character, start:address:duplex-list:character<span class="muRecipe"> -> </span>result:number [
<span class="Constant">local-scope</span>
- curr:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- start:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
result:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
- <span class="muControl">reply-unless</span> curr, result
+ <span class="muControl">reply-unless</span> curr
at-start?:boolean<span class="Special"> <- </span>equal curr, start
- <span class="muControl">reply-if</span> at-start?, result
+ <span class="muControl">reply-if</span> at-start?
<span class="Delimiter">{</span>
curr<span class="Special"> <- </span>prev-duplex curr
<span class="muControl">break-unless</span> curr
@@ -934,19 +925,18 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">}</span>
<span class="muControl">loop</span>
<span class="Delimiter">}</span>
- <span class="muControl">reply</span> result
]
<span class="muScenario">scenario</span> editor-moves-cursor-down-after-inserting-newline-2 [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">1/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">1/left</span>, <span class="Constant">10/right</span>
assume-console [
type <span class="Constant">[0</span>
<span class="Constant">1]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -960,7 +950,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> editor-clears-previous-line-completely-after-inserting-newline [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcde]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
assume-console [
press enter
]
@@ -972,7 +962,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> . .</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># line should be fully cleared</span>
screen-should-contain [
@@ -989,7 +979,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ab</span>
<span class="Constant"> cd</span>
<span class="Constant">ef]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
<span class="Comment"># position cursor after 'cd' and hit 'newline'</span>
assume-console [
left-click <span class="Constant">2</span>, <span class="Constant">8</span>
@@ -997,7 +987,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1013,7 +1003,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ab</span>
<span class="Constant"> cd</span>
<span class="Constant">ef]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
<span class="Comment"># position cursor after 'cd' and hit 'newline' surrounded by paste markers</span>
assume-console [
left-click <span class="Constant">2</span>, <span class="Constant">8</span>
@@ -1022,7 +1012,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press <span class="Constant">65506</span> <span class="Comment"># end paste</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1039,7 +1029,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">break-unless</span> paste-start?
indent?:address:boolean<span class="Special"> <- </span>get-address *editor, <span class="Constant">indent?:offset</span>
*indent?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
@@ -1049,18 +1040,16 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">break-unless</span> paste-end?
indent?:address:boolean<span class="Special"> <- </span>get-address *editor, <span class="Constant">indent?:offset</span>
*indent?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
<span class="SalientComment">## helpers</span>
-<span class="muRecipe">recipe</span> draw-horizontal [
+<span class="muRecipe">recipe</span> draw-horizontal screen:address:screen, row:number, x:number, right:number [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- row:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- x:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- right:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
style:character, style-found?:boolean<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
<span class="Delimiter">{</span>
<span class="muControl">break-if</span> style-found?
diff --git a/html/edit/003-shortcuts.mu.html b/html/edit/003-shortcuts.mu.html
index 82273ba7..023f8448 100644
--- a/html/edit/003-shortcuts.mu.html
+++ b/html/edit/003-shortcuts.mu.html
@@ -13,14 +13,14 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
+.muRecipe { color: #ff8700; }
.muScenario { color: #00af00; }
.Special { color: #ff6060; }
-.muRecipe { color: #ff8700; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.SalientComment { color: #00ffff; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
-->
</style>
@@ -43,12 +43,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># just one character in final line</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ab</span>
<span class="Constant">cd]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
assume-console [
press tab
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -65,7 +65,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
editor, screen, go-render?:boolean<span class="Special"> <- </span>insert-at-cursor editor, <span class="Constant">32/space</span>, screen
editor, screen, go-render?:boolean<span class="Special"> <- </span>insert-at-cursor editor, <span class="Constant">32/space</span>, screen
<span class="Constant"> <insert-character-end></span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
@@ -74,7 +75,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> editor-handles-backspace-key [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
assume-console [
@@ -82,7 +83,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press backspace
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">5</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -104,46 +105,48 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
delete-previous-character?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">8/backspace</span>
<span class="muControl">break-unless</span> delete-previous-character?
<span class="Constant"> <backspace-character-begin></span>
- editor, screen, go-render?:boolean, backspaced-cell:address:duplex-list<span class="Special"> <- </span>delete-before-cursor editor, screen
+ editor, screen, go-render?:boolean, backspaced-cell:address:duplex-list:character<span class="Special"> <- </span>delete-before-cursor editor, screen
<span class="Constant"> <backspace-character-end></span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, go-render?
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
-<span class="Comment"># editor, screen, go-render?:boolean, backspaced-cell:address:duplex-list <- delete-before-cursor editor:address:editor-data, screen</span>
<span class="Comment"># return values:</span>
<span class="Comment"># go-render? - whether caller needs to update the screen</span>
<span class="Comment"># backspaced-cell - value deleted (or 0 if nothing was deleted) so we can save it for undo, etc.</span>
-<span class="muRecipe">recipe</span> delete-before-cursor [
+<span class="muRecipe">recipe</span> delete-before-cursor editor:address:editor-data, screen:address:screen<span class="muRecipe"> -> </span>editor:address:editor-data, screen:address:screen, go-render?:boolean, backspaced-cell:address:duplex-list:character [
<span class="Constant">local-scope</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
+ <span class="Constant">load-ingredients</span>
+ before-cursor:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
<span class="Comment"># if at start of text (before-cursor at § sentinel), return</span>
- prev:address:duplex-list<span class="Special"> <- </span>prev-duplex *before-cursor
- <span class="muControl">reply-unless</span> prev, editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span>, <span class="Constant">0/nothing-deleted</span>
+ prev:address:duplex-list:character<span class="Special"> <- </span>prev-duplex *before-cursor
+ go-render?, backspaced-cell<span class="Special"> <- </span>copy <span class="Constant">0/no-more-render</span>, <span class="Constant">0/nothing-deleted</span>
+ <span class="muControl">reply-unless</span> prev
trace <span class="Constant">10</span>, <span class="Constant">[app]</span>, <span class="Constant">[delete-before-cursor]</span>
original-row:number<span class="Special"> <- </span>get *editor, <span class="Constant">cursor-row:offset</span>
editor, scroll?:boolean<span class="Special"> <- </span>move-cursor-coordinates-left editor
- backspaced-cell:address:duplex-list<span class="Special"> <- </span>copy *before-cursor
+ backspaced-cell:address:duplex-list:character<span class="Special"> <- </span>copy *before-cursor
remove-duplex *before-cursor <span class="Comment"># will also neatly trim next/prev pointers in backspaced-cell/*before-cursor</span>
*before-cursor<span class="Special"> <- </span>copy prev
- <span class="muControl">reply-if</span> scroll?, editor/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">1/go-render</span>, backspaced-cell
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
+ <span class="muControl">reply-if</span> scroll?
screen-width:number<span class="Special"> <- </span>screen-width screen
cursor-row:number<span class="Special"> <- </span>get *editor, <span class="Constant">cursor-row:offset</span>
cursor-column:number<span class="Special"> <- </span>get *editor, <span class="Constant">cursor-column:offset</span>
<span class="Comment"># did we just backspace over a newline?</span>
same-row?:boolean<span class="Special"> <- </span>equal cursor-row, original-row
- <span class="muControl">reply-unless</span> same-row?, editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span>, backspaced-cell
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
+ <span class="muControl">reply-unless</span> same-row?
left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span>
right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span>
- curr:address:duplex-list<span class="Special"> <- </span>next-duplex *before-cursor
+ curr:address:duplex-list:character<span class="Special"> <- </span>next-duplex *before-cursor
screen<span class="Special"> <- </span>move-cursor screen, cursor-row, cursor-column
curr-column:number<span class="Special"> <- </span>copy cursor-column
<span class="Delimiter">{</span>
<span class="Comment"># hit right margin? give up and let caller render</span>
- at-right?:boolean<span class="Special"> <- </span>greater-or-equal curr-column, screen-width
- <span class="muControl">reply-if</span> at-right?, editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span>, backspaced-cell
+ at-right?:boolean<span class="Special"> <- </span>greater-or-equal curr-column, right
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
+ <span class="muControl">reply-if</span> at-right?
<span class="muControl">break-unless</span> curr
<span class="Comment"># newline? done.</span>
currc:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span>
@@ -156,13 +159,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">}</span>
<span class="Comment"># we're guaranteed not to be at the right margin</span>
screen<span class="Special"> <- </span>print-character screen, <span class="Constant">32/space</span>
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span>, backspaced-cell
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
]
-<span class="muRecipe">recipe</span> move-cursor-coordinates-left [
+<span class="muRecipe">recipe</span> move-cursor-coordinates-left editor:address:editor-data<span class="muRecipe"> -> </span>editor:address:editor-data, go-render?:boolean [
<span class="Constant">local-scope</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- before-cursor:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">before-cursor:offset</span>
+ <span class="Constant">load-ingredients</span>
+ before-cursor:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">before-cursor:offset</span>
cursor-row:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-row:offset</span>
cursor-column:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-column:offset</span>
left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span>
@@ -172,7 +175,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">break-if</span> at-left-margin?
trace <span class="Constant">10</span>, <span class="Constant">[app]</span>, <span class="Constant">[decrementing cursor column]</span>
*cursor-column<span class="Special"> <- </span>subtract *cursor-column, <span class="Constant">1</span>
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">0/no-more-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
<span class="Comment"># if at left margin, we must move to previous row:</span>
top-of-screen?:boolean<span class="Special"> <- </span>equal *cursor-row, <span class="Constant">1</span> <span class="Comment"># exclude menu bar</span>
@@ -193,28 +197,26 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">break-unless</span> previous-character-is-newline?
<span class="Comment"># compute length of previous line</span>
trace <span class="Constant">10</span>, <span class="Constant">[app]</span>, <span class="Constant">[switching to previous line]</span>
- d:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">data:offset</span>
+ d:address: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
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, go-render?
+ <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>
trace <span class="Constant">10</span>, <span class="Constant">[app]</span>, <span class="Constant">[wrapping to previous line]</span>
right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span>
*cursor-column<span class="Special"> <- </span>subtract right, <span class="Constant">1</span> <span class="Comment"># leave room for wrap icon</span>
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, go-render?
]
<span class="Comment"># takes a pointer 'curr' into the doubly-linked list and its sentinel, counts</span>
<span class="Comment"># the length of the previous line before the 'curr' pointer.</span>
-<span class="muRecipe">recipe</span> previous-line-length [
+<span class="muRecipe">recipe</span> previous-line-length curr:address:duplex-list:character, start:address:duplex-list:character<span class="muRecipe"> -> </span>result:number [
<span class="Constant">local-scope</span>
- curr:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- start:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
result:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
- <span class="muControl">reply-unless</span> curr, result
+ <span class="muControl">reply-unless</span> curr
at-start?:boolean<span class="Special"> <- </span>equal curr, start
- <span class="muControl">reply-if</span> at-start?, result
+ <span class="muControl">reply-if</span> at-start?
<span class="Delimiter">{</span>
curr<span class="Special"> <- </span>prev-duplex curr
<span class="muControl">break-unless</span> curr
@@ -226,7 +228,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
result<span class="Special"> <- </span>add result, <span class="Constant">1</span>
<span class="muControl">loop</span>
<span class="Delimiter">}</span>
- <span class="muControl">reply</span> result
]
<span class="muScenario">scenario</span> editor-clears-last-line-on-backspace [
@@ -234,13 +235,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># just one character in final line</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ab</span>
<span class="Constant">cd]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
assume-console [
left-click <span class="Constant">2</span>, <span class="Constant">0</span> <span class="Comment"># cursor at only character in final line</span>
press backspace
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">5</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -256,19 +257,77 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
]
+<span class="muScenario">scenario</span> editor-joins-and-wraps-lines-on-backspace [
+ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
+ <span class="Comment"># initialize editor with two long-ish but non-wrapping lines</span>
+ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc def</span>
+<span class="Constant">ghi jkl]</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ editor-render screen, <span class="Constant">2</span>:address:editor-data
+<span class="Constant"> $clear-trace</span>
+ <span class="Comment"># position the cursor at the start of the second and hit backspace</span>
+ assume-console [
+ left-click <span class="Constant">2</span>, <span class="Constant">0</span>
+ press backspace
+ ]
+ run [
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
+ ]
+ <span class="Comment"># resulting single line should wrap correctly</span>
+ screen-should-contain [
+ <span class="Constant"> . .</span>
+ <span class="Constant"> .abc defgh↩.</span>
+ <span class="Constant"> .i jkl .</span>
+<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span>
+ <span class="Constant"> . .</span>
+ ]
+]
+
+<span class="muScenario">scenario</span> editor-wraps-long-lines-on-backspace [
+ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
+ <span class="Comment"># initialize editor in part of the screen with a long line</span>
+ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc def ghij]</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">8/right</span>
+ editor-render screen, <span class="Constant">2</span>:address:editor-data
+ <span class="Comment"># confirm that it wraps</span>
+ screen-should-contain [
+ <span class="Constant"> . .</span>
+ <span class="Constant"> .abc def↩ .</span>
+ <span class="Constant"> . ghij .</span>
+ <span class="Constant"> .┈┈┈┈┈┈┈┈ .</span>
+ ]
+<span class="Constant"> $clear-trace</span>
+ <span class="Comment"># position the cursor somewhere in the middle of the top screen line and hit backspace</span>
+ assume-console [
+ left-click <span class="Constant">1</span>, <span class="Constant">4</span>
+ press backspace
+ ]
+ run [
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
+ ]
+ <span class="Comment"># resulting single line should wrap correctly and not overflow its bounds</span>
+ screen-should-contain [
+ <span class="Constant"> . .</span>
+ <span class="Constant"> .abcdef ↩ .</span>
+ <span class="Constant"> .ghij .</span>
+ <span class="Constant"> .┈┈┈┈┈┈┈┈ .</span>
+ <span class="Constant"> . .</span>
+ ]
+]
+
<span class="Comment"># delete - delete character at cursor</span>
<span class="muScenario">scenario</span> editor-handles-delete-key [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
assume-console [
press delete
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -282,7 +341,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press delete
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -298,25 +357,26 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
delete-next-character?:boolean<span class="Special"> <- </span>equal *k, <span class="Constant">65522/delete</span>
<span class="muControl">break-unless</span> delete-next-character?
<span class="Constant"> <delete-character-begin></span>
- editor, screen, go-render?:boolean, deleted-cell:address:duplex-list<span class="Special"> <- </span>delete-at-cursor editor, screen
+ editor, screen, go-render?:boolean, deleted-cell:address:duplex-list:character<span class="Special"> <- </span>delete-at-cursor editor, screen
<span class="Constant"> <delete-character-end></span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, go-render?
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
-<span class="muRecipe">recipe</span> delete-at-cursor [
+<span class="muRecipe">recipe</span> delete-at-cursor editor:address:editor-data, screen:address:screen<span class="muRecipe"> -> </span>editor:address:editor-data, screen:address:screen, go-render?:boolean, deleted-cell:address:duplex-list:character [
<span class="Constant">local-scope</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
- candidate:address:duplex-list<span class="Special"> <- </span>next-duplex *before-cursor
- <span class="muControl">reply-unless</span> candidate, editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span>, <span class="Constant">0/nothing-deleted</span>
- currc:character<span class="Special"> <- </span>get *candidate, <span class="Constant">value:offset</span>
- remove-duplex candidate
+ <span class="Constant">load-ingredients</span>
+ before-cursor:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
+ deleted-cell:address:duplex-list:character<span class="Special"> <- </span>next-duplex *before-cursor
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
+ <span class="muControl">reply-unless</span> deleted-cell
+ currc:character<span class="Special"> <- </span>get *deleted-cell, <span class="Constant">value:offset</span>
+ remove-duplex deleted-cell
deleted-newline?:boolean<span class="Special"> <- </span>equal currc, <span class="Constant">10/newline</span>
- <span class="muControl">reply-if</span> deleted-newline?, editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span>, candidate/deleted-cell
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
+ <span class="muControl">reply-if</span> deleted-newline?
<span class="Comment"># wasn't a newline? render rest of line</span>
- curr:address:duplex-list<span class="Special"> <- </span>next-duplex *before-cursor <span class="Comment"># refresh after remove-duplex above</span>
+ curr:address:duplex-list:character<span class="Special"> <- </span>next-duplex *before-cursor <span class="Comment"># refresh after remove-duplex above</span>
cursor-row:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-row:offset</span>
cursor-column:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-column:offset</span>
screen<span class="Special"> <- </span>move-cursor screen, *cursor-row, *cursor-column
@@ -325,7 +385,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">{</span>
<span class="Comment"># hit right margin? give up and let caller render</span>
at-right?:boolean<span class="Special"> <- </span>greater-or-equal curr-column, screen-width
- <span class="muControl">reply-if</span> at-right?, editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span>, candidate/deleted-cell
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
+ <span class="muControl">reply-if</span> at-right?
<span class="muControl">break-unless</span> curr
<span class="Comment"># newline? done.</span>
currc:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span>
@@ -338,7 +399,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">}</span>
<span class="Comment"># we're guaranteed not to be at the right margin</span>
screen<span class="Special"> <- </span>print-character screen, <span class="Constant">32/space</span>
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span>, candidate/deleted-cell
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
]
<span class="Comment"># right arrow</span>
@@ -346,7 +407,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> editor-moves-cursor-right-with-key [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
assume-console [
@@ -354,7 +415,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[0]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -370,7 +431,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
move-to-next-character?:boolean<span class="Special"> <- </span>equal *k, <span class="Constant">65514/right-arrow</span>
<span class="muControl">break-unless</span> move-to-next-character?
<span class="Comment"># if not at end of text</span>
- next-cursor:address:duplex-list<span class="Special"> <- </span>next-duplex *before-cursor
+ next-cursor:address:duplex-list:character<span class="Special"> <- </span>next-duplex *before-cursor
<span class="muControl">break-unless</span> next-cursor
<span class="Comment"># scan to next character</span>
<span class="Constant"> <move-cursor-begin></span>
@@ -379,15 +440,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
screen<span class="Special"> <- </span>move-cursor screen, *cursor-row, *cursor-column
undo-coalesce-tag:number<span class="Special"> <- </span>copy <span class="Constant">2/right-arrow</span>
<span class="Constant"> <move-cursor-end></span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, go-render?
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
-<span class="muRecipe">recipe</span> move-cursor-coordinates-right [
+<span class="muRecipe">recipe</span> move-cursor-coordinates-right editor:address:editor-data, screen-height:number<span class="muRecipe"> -> </span>editor:address:editor-data, go-render?:boolean [
<span class="Constant">local-scope</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- screen-height:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- before-cursor:address:duplex-list<span class="Special"> <- </span>get *editor <span class="Constant">before-cursor:offset</span>
+ <span class="Constant">load-ingredients</span>
+ before-cursor:address:duplex-list:character<span class="Special"> <- </span>get *editor <span class="Constant">before-cursor:offset</span>
cursor-row:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-row:offset</span>
cursor-column:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-column:offset</span>
left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span>
@@ -400,10 +460,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
*cursor-row<span class="Special"> <- </span>add *cursor-row, <span class="Constant">1</span>
*cursor-column<span class="Special"> <- </span>copy left
below-screen?:boolean<span class="Special"> <- </span>greater-or-equal *cursor-row, screen-height <span class="Comment"># must be equal</span>
- <span class="muControl">reply-unless</span> below-screen?, editor/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">0/no-more-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
+ <span class="muControl">reply-unless</span> below-screen?
<span class="Constant"> <scroll-down></span>
*cursor-row<span class="Special"> <- </span>subtract *cursor-row, <span class="Constant">1</span> <span class="Comment"># bring back into screen range</span>
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">1/go-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
<span class="Comment"># if the line wraps, move cursor to start of next row</span>
<span class="Delimiter">{</span>
@@ -412,7 +474,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
at-wrap?:boolean<span class="Special"> <- </span>equal *cursor-column, wrap-column
<span class="muControl">break-unless</span> at-wrap?
<span class="Comment"># and if next character isn't newline</span>
- next:address:duplex-list<span class="Special"> <- </span>next-duplex before-cursor
+ next:address:duplex-list:character<span class="Special"> <- </span>next-duplex before-cursor
<span class="muControl">break-unless</span> next
next-character:character<span class="Special"> <- </span>get *next, <span class="Constant">value:offset</span>
newline?:boolean<span class="Special"> <- </span>equal next-character, <span class="Constant">10/newline</span>
@@ -423,18 +485,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">reply-unless</span> below-screen?, editor/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">0/no-more-render</span>
<span class="Constant"> <scroll-down></span>
*cursor-row<span class="Special"> <- </span>subtract *cursor-row, <span class="Constant">1</span> <span class="Comment"># bring back into screen range</span>
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">1/go-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
<span class="Comment"># otherwise move cursor one character right</span>
*cursor-column<span class="Special"> <- </span>add *cursor-column, <span class="Constant">1</span>
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">0/no-more-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
]
<span class="muScenario">scenario</span> editor-moves-cursor-to-next-line-with-right-arrow [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">d]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
<span class="Comment"># type right-arrow a few times to get to start of second line</span>
@@ -445,7 +508,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press right-arrow <span class="Comment"># next line</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span>
<span class="Comment"># type something and ensure it goes where it should</span>
@@ -453,7 +516,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[0]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -469,7 +532,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">d]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">1/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">1/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
assume-console [
press right-arrow
@@ -479,7 +542,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[0]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -493,7 +556,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> editor-moves-cursor-to-next-wrapped-line-with-right-arrow [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcdef]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
assume-console [
@@ -501,7 +564,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press right-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -523,7 +586,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Comment"># line just barely wrapping</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcde]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
<span class="Comment"># position cursor at last character before wrap and hit right-arrow</span>
@@ -532,7 +595,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press right-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -545,7 +608,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press right-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -559,7 +622,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> editor-moves-cursor-to-next-wrapped-line-with-right-arrow-3 [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcdef]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">1/left</span>, <span class="Constant">6/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">1/left</span>, <span class="Constant">6/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
assume-console [
@@ -567,7 +630,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press right-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -589,7 +652,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">d]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
<span class="Comment"># move to end of line, press right-arrow, type a character</span>
@@ -599,7 +662,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[0]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># new character should be in next line</span>
screen-should-contain [
@@ -619,7 +682,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muScenario">scenario</span> editor-moves-cursor-left-with-key [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
assume-console [
@@ -628,7 +691,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[0]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -645,14 +708,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">break-unless</span> move-to-previous-character?
trace <span class="Constant">10</span>, <span class="Constant">[app]</span>, <span class="Constant">[left arrow]</span>
<span class="Comment"># if not at start of text (before-cursor at § sentinel)</span>
- prev:address:duplex-list<span class="Special"> <- </span>prev-duplex *before-cursor
- <span class="muControl">reply-unless</span> prev, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span>
+ prev:address:duplex-list:character<span class="Special"> <- </span>prev-duplex *before-cursor
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
+ <span class="muControl">reply-unless</span> prev
<span class="Constant"> <move-cursor-begin></span>
editor, go-render?<span class="Special"> <- </span>move-cursor-coordinates-left editor
*before-cursor<span class="Special"> <- </span>copy prev
undo-coalesce-tag:number<span class="Special"> <- </span>copy <span class="Constant">1/left-arrow</span>
<span class="Constant"> <move-cursor-end></span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, go-render?
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
@@ -661,7 +725,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># initialize editor with two lines</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">d]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
<span class="Comment"># position cursor at start of second line (so there's no previous newline)</span>
@@ -670,7 +734,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press left-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -687,7 +751,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def</span>
<span class="Constant">g]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
<span class="Comment"># position cursor further down (so there's a newline before the character at</span>
@@ -698,7 +762,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[0]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -715,7 +779,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def</span>
<span class="Constant">g]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
<span class="Comment"># position cursor at start of text, press left-arrow, then type a character</span>
@@ -725,7 +789,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[0]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># left-arrow should have had no effect</span>
screen-should-contain [
@@ -744,7 +808,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
d]
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
<span class="Comment"># position cursor right after empty line</span>
@@ -754,7 +818,7 @@ d]
type <span class="Constant">[0]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -770,7 +834,7 @@ d]
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="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abcdef]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
screen-should-contain [
@@ -786,7 +850,7 @@ d]
press left-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -805,7 +869,7 @@ d]
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
assume-console [
@@ -813,7 +877,7 @@ d]
press up-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -826,7 +890,7 @@ d]
type <span class="Constant">[0]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -845,16 +909,16 @@ d]
editor, go-render?<span class="Special"> <- </span>move-to-previous-line editor
undo-coalesce-tag:number<span class="Special"> <- </span>copy <span class="Constant">3/up-arrow</span>
<span class="Constant"> <move-cursor-end></span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, go-render?
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
-<span class="muRecipe">recipe</span> move-to-previous-line [
+<span class="muRecipe">recipe</span> move-to-previous-line editor:address:editor-data<span class="muRecipe"> -> </span>editor:address:editor-data, go-render?:boolean [
<span class="Constant">local-scope</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
cursor-row:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-row:offset</span>
cursor-column:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-column:offset</span>
- before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
+ before-cursor:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span>
right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span>
already-at-top?:boolean<span class="Special"> <- </span>lesser-or-equal *cursor-row, <span class="Constant">1/top</span>
@@ -864,21 +928,23 @@ d]
<span class="Comment"># if not at newline, move to start of line (previous newline)</span>
<span class="Comment"># then scan back another line</span>
<span class="Comment"># if either step fails, give up without modifying cursor or coordinates</span>
- curr:address:duplex-list<span class="Special"> <- </span>copy *before-cursor
+ curr:address:duplex-list:character<span class="Special"> <- </span>copy *before-cursor
<span class="Delimiter">{</span>
- old:address:duplex-list<span class="Special"> <- </span>copy curr
+ old:address:duplex-list:character<span class="Special"> <- </span>copy curr
c2:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span>
at-newline?:boolean<span class="Special"> <- </span>equal c2, <span class="Constant">10/newline</span>
<span class="muControl">break-if</span> at-newline?
- curr:address:duplex-list<span class="Special"> <- </span>before-previous-line curr, editor
+ curr:address:duplex-list:character<span class="Special"> <- </span>before-previous-line curr, editor
no-motion?:boolean<span class="Special"> <- </span>equal curr, old
- <span class="muControl">reply-if</span> no-motion?, editor/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">0/no-more-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
+ <span class="muControl">reply-if</span> no-motion?
<span class="Delimiter">}</span>
<span class="Delimiter">{</span>
old<span class="Special"> <- </span>copy curr
curr<span class="Special"> <- </span>before-previous-line curr, editor
no-motion?:boolean<span class="Special"> <- </span>equal curr, old
- <span class="muControl">reply-if</span> no-motion?, editor/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">0/no-more-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
+ <span class="muControl">reply-if</span> no-motion?
<span class="Delimiter">}</span>
*before-cursor<span class="Special"> <- </span>copy curr
*cursor-row<span class="Special"> <- </span>subtract *cursor-row, <span class="Constant">1</span>
@@ -888,7 +954,7 @@ d]
<span class="Delimiter">{</span>
done?:boolean<span class="Special"> <- </span>greater-or-equal *cursor-column, target-column
<span class="muControl">break-if</span> done?
- curr:address:duplex-list<span class="Special"> <- </span>next-duplex *before-cursor
+ curr:address:duplex-list:character<span class="Special"> <- </span>next-duplex *before-cursor
<span class="muControl">break-unless</span> curr
currc:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span>
at-newline?:boolean<span class="Special"> <- </span>equal currc, <span class="Constant">10/newline</span>
@@ -898,13 +964,15 @@ d]
*cursor-column<span class="Special"> <- </span>add *cursor-column, <span class="Constant">1</span>
<span class="muControl">loop</span>
<span class="Delimiter">}</span>
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">0/no-more-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
<span class="Delimiter">{</span>
<span class="Comment"># if cursor already at top, scroll up</span>
<span class="muControl">break-unless</span> already-at-top?
<span class="Constant"> <scroll-up></span>
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">1/go-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
@@ -912,7 +980,7 @@ d]
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ab</span>
<span class="Constant">def]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
assume-console [
@@ -920,7 +988,7 @@ d]
press up-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -933,7 +1001,7 @@ d]
type <span class="Constant">[0]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -948,7 +1016,7 @@ d]
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new [
def]
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
assume-console [
@@ -956,7 +1024,7 @@ def]
press up-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -969,7 +1037,7 @@ def]
type <span class="Constant">[0]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -986,7 +1054,7 @@ def]
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def</span>
<span class="Constant">ghi]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
<span class="Comment"># click on the third line and hit up-arrow, so you end up just after a newline</span>
@@ -995,7 +1063,7 @@ def]
press up-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1008,7 +1076,7 @@ def]
type <span class="Constant">[0]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -1025,7 +1093,7 @@ def]
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
<span class="Comment"># cursor starts out at (1, 0)</span>
@@ -1033,7 +1101,7 @@ def]
press down-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1047,7 +1115,7 @@ def]
type <span class="Constant">[0]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -1066,17 +1134,16 @@ def]
editor, go-render?<span class="Special"> <- </span>move-to-next-line editor, screen-height
undo-coalesce-tag:number<span class="Special"> <- </span>copy <span class="Constant">4/down-arrow</span>
<span class="Constant"> <move-cursor-end></span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, go-render?
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
-<span class="muRecipe">recipe</span> move-to-next-line [
+<span class="muRecipe">recipe</span> move-to-next-line editor:address:editor-data, screen-height:number<span class="muRecipe"> -> </span>editor:address:editor-data, go-render?:boolean [
<span class="Constant">local-scope</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- screen-height:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
cursor-row:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-row:offset</span>
cursor-column:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-column:offset</span>
- before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
+ before-cursor:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span>
right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span>
last-line:number<span class="Special"> <- </span>subtract screen-height, <span class="Constant">1</span>
@@ -1086,7 +1153,7 @@ def]
<span class="muControl">break-if</span> already-at-bottom?
<span class="Comment"># scan to start of next line, then to right column or until end of line</span>
max:number<span class="Special"> <- </span>subtract right, left
- next-line:address:duplex-list<span class="Special"> <- </span>before-start-of-next-line *before-cursor, max
+ next-line:address:duplex-list:character<span class="Special"> <- </span>before-start-of-next-line *before-cursor, max
<span class="Delimiter">{</span>
<span class="Comment"># already at end of buffer? try to scroll up (so we can see more</span>
<span class="Comment"># warnings or sandboxes below)</span>
@@ -1094,7 +1161,8 @@ def]
<span class="muControl">break-unless</span> no-motion?
scroll?:boolean<span class="Special"> <- </span>greater-than *cursor-row, <span class="Constant">1</span>
<span class="muControl">break-if</span> scroll?, <span class="Constant">+try-to-scroll:label</span>
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">0/no-more-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
*cursor-row<span class="Special"> <- </span>add *cursor-row, <span class="Constant">1</span>
*before-cursor<span class="Special"> <- </span>copy next-line
@@ -1103,7 +1171,7 @@ def]
<span class="Delimiter">{</span>
done?:boolean<span class="Special"> <- </span>greater-or-equal *cursor-column, target-column
<span class="muControl">break-if</span> done?
- curr:address:duplex-list<span class="Special"> <- </span>next-duplex *before-cursor
+ curr:address:duplex-list:character<span class="Special"> <- </span>next-duplex *before-cursor
<span class="muControl">break-unless</span> curr
currc:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span>
at-newline?:boolean<span class="Special"> <- </span>equal currc, <span class="Constant">10/newline</span>
@@ -1113,18 +1181,19 @@ def]
*cursor-column<span class="Special"> <- </span>add *cursor-column, <span class="Constant">1</span>
<span class="muControl">loop</span>
<span class="Delimiter">}</span>
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">0/no-more-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
<span class="Constant"> +try-to-scroll</span>
<span class="Constant"> <scroll-down></span>
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">1/go-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
]
<span class="muScenario">scenario</span> editor-adjusts-column-at-next-line [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">de]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
assume-console [
@@ -1132,7 +1201,7 @@ def]
press down-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1145,7 +1214,7 @@ def]
type <span class="Constant">[0]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -1156,78 +1225,13 @@ def]
]
]
-<span class="muScenario">scenario</span> editor-scrolls-at-end-on-down-arrow [
- assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
- <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
-<span class="Constant">de]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
- editor-render screen, <span class="Constant">2</span>:address:editor-data
-<span class="Constant"> $clear-trace</span>
- <span class="Comment"># try to move down past end of text</span>
- assume-console [
- left-click <span class="Constant">2</span>, <span class="Constant">0</span>
- press down-arrow
- ]
- run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
- <span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
- <span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
- ]
- <span class="Comment"># screen should scroll, moving cursor to end of text</span>
- memory-should-contain [
- <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span>
- <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">2</span>
- ]
- assume-console [
- type <span class="Constant">[0]</span>
- ]
- run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
- ]
- screen-should-contain [
- <span class="Constant"> . .</span>
- <span class="Constant"> .de0 .</span>
-<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span>
- <span class="Constant"> . .</span>
- ]
- <span class="Comment"># try to move down again</span>
-<span class="Constant"> $clear-trace</span>
- assume-console [
- left-click <span class="Constant">2</span>, <span class="Constant">0</span>
- press down-arrow
- ]
- run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
- <span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
- <span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
- ]
- <span class="Comment"># screen stops scrolling because cursor is already at top</span>
- memory-should-contain [
- <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span>
- <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">3</span>
- ]
- check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span>
- assume-console [
- type <span class="Constant">[1]</span>
- ]
- run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
- ]
- screen-should-contain [
- <span class="Constant"> . .</span>
- <span class="Constant"> .de01 .</span>
-<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span>
- <span class="Constant"> . .</span>
- ]
-]
-
<span class="Comment"># ctrl-a/home - move cursor to start of line</span>
<span class="muScenario">scenario</span> editor-moves-to-start-of-line-with-ctrl-a [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span>
<span class="Constant">456]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
<span class="Comment"># start on second line, press ctrl-a</span>
@@ -1236,7 +1240,7 @@ def]
press ctrl-a
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">5</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1256,7 +1260,8 @@ def]
move-to-start-of-line editor
undo-coalesce-tag:number<span class="Special"> <- </span>copy <span class="Constant">0/never</span>
<span class="Constant"> <move-cursor-end></span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
@@ -1268,20 +1273,21 @@ def]
move-to-start-of-line editor
undo-coalesce-tag:number<span class="Special"> <- </span>copy <span class="Constant">0/never</span>
<span class="Constant"> <move-cursor-end></span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
-<span class="muRecipe">recipe</span> move-to-start-of-line [
+<span class="muRecipe">recipe</span> move-to-start-of-line editor:address:editor-data [
<span class="Constant">local-scope</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
<span class="Comment"># update cursor column</span>
left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span>
cursor-column:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-column:offset</span>
*cursor-column<span class="Special"> <- </span>copy left
<span class="Comment"># update before-cursor</span>
- before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
- init:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">data:offset</span>
+ before-cursor:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
+ init:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">data:offset</span>
<span class="Comment"># while not at start of line, move </span>
<span class="Delimiter">{</span>
at-start-of-text?:boolean<span class="Special"> <- </span>equal *before-cursor, init
@@ -1299,7 +1305,7 @@ def]
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span>
<span class="Constant">456]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
<span class="Comment"># start on first line (no newline before), press ctrl-a</span>
@@ -1308,7 +1314,7 @@ def]
press ctrl-a
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">5</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1324,7 +1330,7 @@ def]
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span>
<span class="Constant">456]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
<span class="Constant"> $clear-trace</span>
<span class="Comment"># start on second line, press 'home'</span>
assume-console [
@@ -1332,7 +1338,7 @@ def]
press home
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1348,7 +1354,7 @@ def]
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span>
<span class="Constant">456]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
<span class="Comment"># start on first line (no newline before), press 'home'</span>
@@ -1357,7 +1363,7 @@ def]
press home
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1375,7 +1381,7 @@ def]
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span>
<span class="Constant">456]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
<span class="Comment"># start on first line, press ctrl-e</span>
@@ -1384,7 +1390,7 @@ def]
press ctrl-e
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">5</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1399,7 +1405,7 @@ def]
type <span class="Constant">[z]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">5</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1425,7 +1431,8 @@ def]
move-to-end-of-line editor
undo-coalesce-tag:number<span class="Special"> <- </span>copy <span class="Constant">0/never</span>
<span class="Constant"> <move-cursor-end></span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
@@ -1437,18 +1444,19 @@ def]
move-to-end-of-line editor
undo-coalesce-tag:number<span class="Special"> <- </span>copy <span class="Constant">0/never</span>
<span class="Constant"> <move-cursor-end></span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
-<span class="muRecipe">recipe</span> move-to-end-of-line [
+<span class="muRecipe">recipe</span> move-to-end-of-line editor:address:editor-data [
<span class="Constant">local-scope</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
+ <span class="Constant">load-ingredients</span>
+ before-cursor:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
cursor-column:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-column:offset</span>
<span class="Comment"># while not at start of line, move </span>
<span class="Delimiter">{</span>
- next:address:duplex-list<span class="Special"> <- </span>next-duplex *before-cursor
+ next:address:duplex-list:character<span class="Special"> <- </span>next-duplex *before-cursor
<span class="muControl">break-unless</span> next <span class="Comment"># end of text</span>
nextc:character<span class="Special"> <- </span>get *next, <span class="Constant">value:offset</span>
at-end-of-line?:boolean<span class="Special"> <- </span>equal nextc, <span class="Constant">10/newline</span>
@@ -1463,7 +1471,7 @@ def]
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span>
<span class="Constant">456]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
<span class="Comment"># start on second line (no newline after), press ctrl-e</span>
@@ -1472,7 +1480,7 @@ def]
press ctrl-e
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">5</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1488,7 +1496,7 @@ def]
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span>
<span class="Constant">456]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
<span class="Comment"># start on first line, press 'end'</span>
@@ -1497,7 +1505,7 @@ def]
press end
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1513,7 +1521,7 @@ def]
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span>
<span class="Constant">456]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Constant"> $clear-trace</span>
<span class="Comment"># start on second line (no newline after), press 'end'</span>
@@ -1522,7 +1530,7 @@ def]
press end
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1540,14 +1548,14 @@ def]
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span>
<span class="Constant">456]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
<span class="Comment"># start on second line, press ctrl-u</span>
assume-console [
left-click <span class="Constant">2</span>, <span class="Constant">2</span>
press ctrl-u
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># cursor deletes to start of line</span>
screen-should-contain [
@@ -1564,20 +1572,21 @@ def]
delete-to-start-of-line?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">21/ctrl-u</span>
<span class="muControl">break-unless</span> delete-to-start-of-line?
<span class="Constant"> <delete-to-start-of-line-begin></span>
- deleted-cells:address:duplex-list<span class="Special"> <- </span>delete-to-start-of-line editor
+ deleted-cells:address:duplex-list:character<span class="Special"> <- </span>delete-to-start-of-line editor
<span class="Constant"> <delete-to-start-of-line-end></span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
-<span class="muRecipe">recipe</span> delete-to-start-of-line [
+<span class="muRecipe">recipe</span> delete-to-start-of-line editor:address:editor-data<span class="muRecipe"> -> </span>result:address:duplex-list:character [
<span class="Constant">local-scope</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
<span class="Comment"># compute range to delete</span>
- init:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">data:offset</span>
- before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
- start:address:duplex-list<span class="Special"> <- </span>copy *before-cursor
- end:address:duplex-list<span class="Special"> <- </span>next-duplex *before-cursor
+ init:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">data:offset</span>
+ before-cursor:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
+ start:address:duplex-list:character<span class="Special"> <- </span>copy *before-cursor
+ end:address:duplex-list:character<span class="Special"> <- </span>next-duplex *before-cursor
<span class="Delimiter">{</span>
at-start-of-text?:boolean<span class="Special"> <- </span>equal start, init
<span class="muControl">break-if</span> at-start-of-text?
@@ -1589,28 +1598,27 @@ def]
<span class="muControl">loop</span>
<span class="Delimiter">}</span>
<span class="Comment"># snip it out</span>
- result:address:duplex-list<span class="Special"> <- </span>next-duplex start
+ result:address:duplex-list:character<span class="Special"> <- </span>next-duplex start
remove-duplex-between start, end
<span class="Comment"># adjust cursor</span>
- *before-cursor<span class="Special"> <- </span>prev-duplex end
+ *before-cursor<span class="Special"> <- </span>copy start
left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span>
cursor-column:address:number<span class="Special"> <- </span>get-address *editor, <span class="Constant">cursor-column:offset</span>
*cursor-column<span class="Special"> <- </span>copy left
- <span class="muControl">reply</span> result
]
<span class="muScenario">scenario</span> editor-deletes-to-start-of-line-with-ctrl-u-2 [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span>
<span class="Constant">456]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
<span class="Comment"># start on first line (no newline before), press ctrl-u</span>
assume-console [
left-click <span class="Constant">1</span>, <span class="Constant">2</span>
press ctrl-u
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># cursor deletes to start of line</span>
screen-should-contain [
@@ -1626,14 +1634,14 @@ def]
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span>
<span class="Constant">456]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
<span class="Comment"># start past end of line, press ctrl-u</span>
assume-console [
left-click <span class="Constant">1</span>, <span class="Constant">3</span>
press ctrl-u
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># cursor deletes to start of line</span>
screen-should-contain [
@@ -1649,14 +1657,14 @@ def]
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span>
<span class="Constant">456]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
<span class="Comment"># start past end of final line, press ctrl-u</span>
assume-console [
left-click <span class="Constant">2</span>, <span class="Constant">3</span>
press ctrl-u
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># cursor deletes to start of line</span>
screen-should-contain [
@@ -1674,14 +1682,14 @@ def]
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span>
<span class="Constant">456]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
<span class="Comment"># start on first line, press ctrl-k</span>
assume-console [
left-click <span class="Constant">1</span>, <span class="Constant">1</span>
press ctrl-k
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># cursor deletes to end of line</span>
screen-should-contain [
@@ -1698,18 +1706,19 @@ def]
delete-to-end-of-line?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">11/ctrl-k</span>
<span class="muControl">break-unless</span> delete-to-end-of-line?
<span class="Constant"> <delete-to-end-of-line-begin></span>
- deleted-cells:address:duplex-list<span class="Special"> <- </span>delete-to-end-of-line editor
+ deleted-cells:address:duplex-list:character<span class="Special"> <- </span>delete-to-end-of-line editor
<span class="Constant"> <delete-to-end-of-line-end></span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
-<span class="muRecipe">recipe</span> delete-to-end-of-line [
+<span class="muRecipe">recipe</span> delete-to-end-of-line editor:address:editor-data<span class="muRecipe"> -> </span>result:address:duplex-list:character [
<span class="Constant">local-scope</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
<span class="Comment"># compute range to delete</span>
- start:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">before-cursor:offset</span>
- end:address:duplex-list<span class="Special"> <- </span>next-duplex start
+ start:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">before-cursor:offset</span>
+ end:address:duplex-list:character<span class="Special"> <- </span>next-duplex start
<span class="Delimiter">{</span>
at-end-of-text?:boolean<span class="Special"> <- </span>equal end, <span class="Constant">0/null</span>
<span class="muControl">break-if</span> at-end-of-text?
@@ -1720,23 +1729,22 @@ def]
<span class="muControl">loop</span>
<span class="Delimiter">}</span>
<span class="Comment"># snip it out</span>
- result:address:duplex-list<span class="Special"> <- </span>next-duplex start
+ result<span class="Special"> <- </span>next-duplex start
remove-duplex-between start, end
- <span class="muControl">reply</span> result
]
<span class="muScenario">scenario</span> editor-deletes-to-end-of-line-with-ctrl-k-2 [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span>
<span class="Constant">456]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
<span class="Comment"># start on second line (no newline after), press ctrl-k</span>
assume-console [
left-click <span class="Constant">2</span>, <span class="Constant">1</span>
press ctrl-k
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># cursor deletes to end of line</span>
screen-should-contain [
@@ -1752,14 +1760,14 @@ def]
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span>
<span class="Constant">456]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
<span class="Comment"># start at end of line</span>
assume-console [
left-click <span class="Constant">1</span>, <span class="Constant">2</span>
press ctrl-k
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># cursor deletes just last character</span>
screen-should-contain [
@@ -1775,14 +1783,14 @@ def]
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span>
<span class="Constant">456]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
<span class="Comment"># start past end of line</span>
assume-console [
left-click <span class="Constant">1</span>, <span class="Constant">3</span>
press ctrl-k
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># cursor deletes nothing</span>
screen-should-contain [
@@ -1798,14 +1806,14 @@ def]
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span>
<span class="Constant">456]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
<span class="Comment"># start at end of text</span>
assume-console [
left-click <span class="Constant">2</span>, <span class="Constant">2</span>
press ctrl-k
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># cursor deletes just the final character</span>
screen-should-contain [
@@ -1821,14 +1829,14 @@ def]
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[123</span>
<span class="Constant">456]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
<span class="Comment"># start past end of text</span>
assume-console [
left-click <span class="Constant">2</span>, <span class="Constant">3</span>
press ctrl-k
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># cursor deletes nothing</span>
screen-should-contain [
@@ -1850,7 +1858,7 @@ def]
<span class="Constant">b</span>
<span class="Constant">c</span>
<span class="Constant">d]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> .a .</span>
@@ -1863,7 +1871,7 @@ def]
press down-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen slides by one line</span>
screen-should-contain [
@@ -1876,29 +1884,25 @@ def]
<span class="muRecipe">after</span> <span class="Constant"><scroll-down></span> [
trace <span class="Constant">10</span>, <span class="Constant">[app]</span>, <span class="Constant">[scroll down]</span>
- top-of-screen:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
+ top-of-screen:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span>
right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span>
max:number<span class="Special"> <- </span>subtract right, left
- old-top:address:duplex-list<span class="Special"> <- </span>copy *top-of-screen
+ old-top:address:duplex-list:character<span class="Special"> <- </span>copy *top-of-screen
*top-of-screen<span class="Special"> <- </span>before-start-of-next-line *top-of-screen, max
no-movement?:boolean<span class="Special"> <- </span>equal old-top, *top-of-screen
- <span class="Comment"># Hack: this reply doesn't match one of the locations of <scroll-down>,</span>
- <span class="Comment"># directly within insert-at-cursor. However, I'm unable to trigger the</span>
- <span class="Comment"># error.. If necessary create a duplicate copy of <scroll-down> with the</span>
- <span class="Comment"># right 'reply-if'.</span>
- <span class="muControl">reply-if</span> no-movement?, editor/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">0/no-more-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
+ <span class="muControl">reply-if</span> no-movement?
]
<span class="Comment"># takes a pointer into the doubly-linked list, scans ahead at most 'max'</span>
<span class="Comment"># positions until the next newline</span>
<span class="Comment"># beware: never return null pointer.</span>
-<span class="muRecipe">recipe</span> before-start-of-next-line [
+<span class="muRecipe">recipe</span> before-start-of-next-line original:address:duplex-list:character, max:number<span class="muRecipe"> -> </span>curr:address:duplex-list:character [
<span class="Constant">local-scope</span>
- original:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- max:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
count:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
- curr:address:duplex-list<span class="Special"> <- </span>copy original
+ curr:address:duplex-list:character<span class="Special"> <- </span>copy original
<span class="Comment"># skip the initial newline if it exists</span>
<span class="Delimiter">{</span>
c:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span>
@@ -1931,7 +1935,7 @@ def]
<span class="Constant">g</span>
<span class="Constant">h</span>
<span class="Constant">i]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> .abcd↩ .</span>
@@ -1944,7 +1948,7 @@ def]
press down-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen shows partial wrapped line</span>
screen-should-contain [
@@ -1963,14 +1967,14 @@ def]
<span class="Constant">k</span>
<span class="Constant">l</span>
<span class="Constant">m]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
<span class="Comment"># position cursor at last line, then try to move further down</span>
assume-console [
left-click <span class="Constant">3</span>, <span class="Constant">0</span>
press down-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen shows partial wrapped line containing a wrap icon</span>
screen-should-contain [
@@ -1984,7 +1988,7 @@ def]
press down-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen shows partial wrapped line</span>
screen-should-contain [
@@ -2002,14 +2006,14 @@ def]
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span>
<span class="Constant">b</span>
<span class="Constant">cdef]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
<span class="Comment"># position cursor at end, type a character</span>
assume-console [
left-click <span class="Constant">3</span>, <span class="Constant">4</span>
type <span class="Constant">[g]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -2032,14 +2036,14 @@ def]
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span>
<span class="Constant">b</span>
<span class="Constant">c]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
assume-console [
left-click <span class="Constant">3</span>, <span class="Constant">4</span>
type [
]
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -2063,14 +2067,14 @@ def]
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span>
<span class="Constant">b</span>
<span class="Constant">cdefgh]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
<span class="Comment"># position cursor at end of screen and try to move right</span>
assume-console [
left-click <span class="Constant">3</span>, <span class="Constant">3</span>
press right-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -2095,14 +2099,14 @@ def]
<span class="Constant">b</span>
<span class="Constant">c</span>
<span class="Constant">d]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
<span class="Comment"># position cursor at end of screen and try to move right</span>
assume-console [
left-click <span class="Constant">3</span>, <span class="Constant">3</span>
press right-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -2119,6 +2123,71 @@ def]
]
]
+<span class="muScenario">scenario</span> editor-scrolls-at-end-on-down-arrow [
+ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
+ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
+<span class="Constant">de]</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ editor-render screen, <span class="Constant">2</span>:address:editor-data
+<span class="Constant"> $clear-trace</span>
+ <span class="Comment"># try to move down past end of text</span>
+ assume-console [
+ left-click <span class="Constant">2</span>, <span class="Constant">0</span>
+ press down-arrow
+ ]
+ run [
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
+ <span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
+ <span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
+ ]
+ <span class="Comment"># screen should scroll, moving cursor to end of text</span>
+ memory-should-contain [
+ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span>
+ <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">2</span>
+ ]
+ assume-console [
+ type <span class="Constant">[0]</span>
+ ]
+ run [
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
+ ]
+ screen-should-contain [
+ <span class="Constant"> . .</span>
+ <span class="Constant"> .de0 .</span>
+<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span>
+ <span class="Constant"> . .</span>
+ ]
+ <span class="Comment"># try to move down again</span>
+<span class="Constant"> $clear-trace</span>
+ assume-console [
+ left-click <span class="Constant">2</span>, <span class="Constant">0</span>
+ press down-arrow
+ ]
+ run [
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
+ <span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
+ <span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
+ ]
+ <span class="Comment"># screen stops scrolling because cursor is already at top</span>
+ memory-should-contain [
+ <span class="Constant">3</span><span class="Special"> <- </span><span class="Constant">1</span>
+ <span class="Constant">4</span><span class="Special"> <- </span><span class="Constant">3</span>
+ ]
+ check-trace-count-for-label <span class="Constant">0</span>, <span class="Constant">[print-character]</span>
+ assume-console [
+ type <span class="Constant">[1]</span>
+ ]
+ run [
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
+ ]
+ screen-should-contain [
+ <span class="Constant"> . .</span>
+ <span class="Constant"> .de01 .</span>
+<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span>
+ <span class="Constant"> . .</span>
+ ]
+]
+
<span class="muScenario">scenario</span> editor-combines-page-and-line-scroll [
<span class="Comment"># screen has 1 line for menu + 3 lines</span>
assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span>
@@ -2130,7 +2199,7 @@ def]
<span class="Constant">e</span>
<span class="Constant">f</span>
<span class="Constant">g]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
<span class="Comment"># scroll down one page and one line</span>
assume-console [
press page-down
@@ -2138,7 +2207,7 @@ def]
press down-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen scrolls down 3 lines</span>
screen-should-contain [
@@ -2159,7 +2228,7 @@ def]
<span class="Constant">b</span>
<span class="Constant">c</span>
<span class="Constant">d]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> .a .</span>
@@ -2172,7 +2241,7 @@ def]
press up-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen slides by one line</span>
screen-should-contain [
@@ -2185,33 +2254,33 @@ def]
<span class="muRecipe">after</span> <span class="Constant"><scroll-up></span> [
trace <span class="Constant">10</span>, <span class="Constant">[app]</span>, <span class="Constant">[scroll up]</span>
- top-of-screen:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
- old-top:address:duplex-list<span class="Special"> <- </span>copy *top-of-screen
+ top-of-screen:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
+ old-top:address:duplex-list:character<span class="Special"> <- </span>copy *top-of-screen
*top-of-screen<span class="Special"> <- </span>before-previous-line *top-of-screen, editor
no-movement?:boolean<span class="Special"> <- </span>equal old-top, *top-of-screen
- <span class="muControl">reply-if</span> no-movement?, editor/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">0/no-more-render</span>
+ go-render?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
+ <span class="muControl">reply-if</span> no-movement?
]
<span class="Comment"># takes a pointer into the doubly-linked list, scans back to before start of</span>
<span class="Comment"># previous *wrapped* line</span>
<span class="Comment"># beware: never return null pointer</span>
-<span class="muRecipe">recipe</span> before-previous-line [
+<span class="muRecipe">recipe</span> before-previous-line curr:address:duplex-list:character, editor:address:editor-data<span class="muRecipe"> -> </span>curr:address:duplex-list:character [
<span class="Constant">local-scope</span>
- curr:address:duplex-list<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
c:character<span class="Special"> <- </span>get *curr, <span class="Constant">value:offset</span>
<span class="Comment"># compute max, number of characters to skip</span>
<span class="Comment"># 1 + len%(width-1)</span>
<span class="Comment"># except rotate second term to vary from 1 to width-1 rather than 0 to width-2</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
left:number<span class="Special"> <- </span>get *editor, <span class="Constant">left:offset</span>
right:number<span class="Special"> <- </span>get *editor, <span class="Constant">right:offset</span>
max-line-length:number<span class="Special"> <- </span>subtract right, left, <span class="Constant">-1/exclusive-right</span>, <span class="Constant">1/wrap-icon</span>
- sentinel:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">data:offset</span>
+ sentinel:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">data:offset</span>
len:number<span class="Special"> <- </span>previous-line-length curr, sentinel
<span class="Delimiter">{</span>
<span class="muControl">break-if</span> len
<span class="Comment"># empty line; just skip this newline</span>
- prev:address:duplex-list<span class="Special"> <- </span>prev-duplex curr
+ prev:address:duplex-list:character<span class="Special"> <- </span>prev-duplex curr
<span class="muControl">reply-unless</span> prev, curr
<span class="muControl">reply</span> prev
<span class="Delimiter">}</span>
@@ -2227,7 +2296,7 @@ def]
<span class="Delimiter">{</span>
done?:boolean<span class="Special"> <- </span>greater-or-equal count, max
<span class="muControl">break-if</span> done?
- prev:address:duplex-list<span class="Special"> <- </span>prev-duplex curr
+ prev:address:duplex-list:character<span class="Special"> <- </span>prev-duplex curr
<span class="muControl">break-unless</span> prev
curr<span class="Special"> <- </span>copy prev
count<span class="Special"> <- </span>add count, <span class="Constant">1</span>
@@ -2245,7 +2314,7 @@ def]
<span class="Constant">g</span>
<span class="Constant">h</span>
<span class="Constant">i]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> .abcd↩ .</span>
@@ -2257,7 +2326,7 @@ def]
press page-down
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -2270,7 +2339,7 @@ def]
press up-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen shows partial wrapped line</span>
screen-should-contain [
@@ -2289,13 +2358,13 @@ def]
<span class="Constant">k</span>
<span class="Constant">l</span>
<span class="Constant">m]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
<span class="Comment"># position cursor at top of second page</span>
assume-console [
press page-down
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -2309,7 +2378,7 @@ def]
press up-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen shows partial wrapped line</span>
screen-should-contain [
@@ -2324,7 +2393,7 @@ def]
press up-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen shows partial wrapped line</span>
screen-should-contain [
@@ -2339,7 +2408,7 @@ def]
press up-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen shows partial wrapped line</span>
screen-should-contain [
@@ -2362,7 +2431,7 @@ def]
<span class="Constant">g</span>
<span class="Constant">h</span>
<span class="Constant">i]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">6/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">6/right</span>
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> .abcde↩ .</span>
@@ -2374,7 +2443,7 @@ def]
press page-down
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -2387,7 +2456,7 @@ def]
press up-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen shows partial wrapped line</span>
screen-should-contain [
@@ -2408,12 +2477,12 @@ def]
c
d
e]
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">6/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">6/right</span>
assume-console [
press page-down
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -2425,7 +2494,7 @@ e]
press page-down
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -2437,7 +2506,7 @@ e]
press page-up
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -2456,13 +2525,13 @@ e]
<span class="Constant">c</span>
<span class="Constant">d</span>
<span class="Constant">e]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
<span class="Comment"># position cursor at top of second page</span>
assume-console [
press page-down
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -2475,7 +2544,7 @@ e]
press left-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -2500,7 +2569,7 @@ e]
<span class="Constant">b</span>
<span class="Constant">c</span>
<span class="Constant">d]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> .a .</span>
@@ -2515,7 +2584,7 @@ e]
press up-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen slides by one line</span>
screen-should-contain [
@@ -2529,7 +2598,7 @@ e]
press up-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen remains unchanged</span>
screen-should-contain [
@@ -2548,7 +2617,7 @@ e]
<span class="Constant">b</span>
<span class="Constant">c</span>
<span class="Constant">d]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> .a .</span>
@@ -2560,7 +2629,7 @@ e]
press page-down
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen shows next page</span>
screen-should-contain [
@@ -2575,15 +2644,15 @@ e]
<span class="Delimiter">{</span>
page-down?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">6/ctrl-f</span>
<span class="muControl">break-unless</span> page-down?
- top-of-screen:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
- old-top:address:duplex-list<span class="Special"> <- </span>copy *top-of-screen
+ top-of-screen:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
+ old-top:address:duplex-list:character<span class="Special"> <- </span>copy *top-of-screen
<span class="Constant"> <move-cursor-begin></span>
page-down editor
undo-coalesce-tag:number<span class="Special"> <- </span>copy <span class="Constant">0/never</span>
<span class="Constant"> <move-cursor-end></span>
no-movement?:boolean<span class="Special"> <- </span>equal *top-of-screen, old-top
- <span class="muControl">reply-if</span> no-movement?, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span>
+ go-render?<span class="Special"> <- </span>not no-movement?
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
@@ -2591,28 +2660,28 @@ e]
<span class="Delimiter">{</span>
page-down?:boolean<span class="Special"> <- </span>equal *k, <span class="Constant">65518/page-down</span>
<span class="muControl">break-unless</span> page-down?
- top-of-screen:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
- old-top:address:duplex-list<span class="Special"> <- </span>copy *top-of-screen
+ top-of-screen:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
+ old-top:address:duplex-list:character<span class="Special"> <- </span>copy *top-of-screen
<span class="Constant"> <move-cursor-begin></span>
page-down editor
undo-coalesce-tag:number<span class="Special"> <- </span>copy <span class="Constant">0/never</span>
<span class="Constant"> <move-cursor-end></span>
no-movement?:boolean<span class="Special"> <- </span>equal *top-of-screen, old-top
- <span class="muControl">reply-if</span> no-movement?, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span>
+ go-render?<span class="Special"> <- </span>not no-movement?
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
<span class="Comment"># page-down skips entire wrapped lines, so it can't scroll past lines</span>
<span class="Comment"># taking up the entire screen</span>
-<span class="muRecipe">recipe</span> page-down [
+<span class="muRecipe">recipe</span> page-down editor:address:editor-data<span class="muRecipe"> -> </span>editor:address:editor-data [
<span class="Constant">local-scope</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
<span class="Comment"># if editor contents don't overflow screen, do nothing</span>
- bottom-of-screen:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">bottom-of-screen:offset</span>
- <span class="muControl">reply-unless</span> bottom-of-screen, editor/same-as-ingredient:<span class="Constant">0</span>
+ bottom-of-screen:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">bottom-of-screen:offset</span>
+ <span class="muControl">reply-unless</span> bottom-of-screen
<span class="Comment"># if not, position cursor at final character</span>
- before-cursor:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
+ before-cursor:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
*before-cursor<span class="Special"> <- </span>prev-duplex bottom-of-screen
<span class="Comment"># keep one line in common with previous page</span>
<span class="Delimiter">{</span>
@@ -2623,16 +2692,15 @@ e]
<span class="Delimiter">}</span>
<span class="Comment"># move cursor and top-of-screen to start of that line</span>
move-to-start-of-line editor
- top-of-screen:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
+ top-of-screen:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
*top-of-screen<span class="Special"> <- </span>copy *before-cursor
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>
]
<span class="muScenario">scenario</span> editor-does-not-scroll-past-end [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">4/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span>
<span class="Constant">b]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
screen-should-contain [
<span class="Constant"> . .</span>
@@ -2645,7 +2713,7 @@ e]
press page-down
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen remains unmodified</span>
screen-should-contain [
@@ -2664,7 +2732,7 @@ e]
<span class="Constant">b</span>
<span class="Constant">cdefgh]</span>
<span class="Comment"># editor screen triggers wrap of last line</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">4/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">4/right</span>
<span class="Comment"># some part of last line is not displayed</span>
screen-should-contain [
<span class="Constant"> . .</span>
@@ -2677,7 +2745,7 @@ e]
press page-down
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen shows entire wrapped line</span>
screen-should-contain [
@@ -2695,7 +2763,7 @@ e]
<span class="Comment"># and still has something left over</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span>
<span class="Constant">bcdefgh]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">4/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">4/right</span>
<span class="Comment"># some part of last line is not displayed</span>
screen-should-contain [
<span class="Constant"> . .</span>
@@ -2708,7 +2776,7 @@ e]
press page-down
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen shows entire wrapped line</span>
screen-should-contain [
@@ -2727,7 +2795,7 @@ e]
<span class="Constant">b</span>
<span class="Constant">c</span>
<span class="Constant">d]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> .a .</span>
@@ -2739,7 +2807,7 @@ e]
press page-down
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen shows next page</span>
screen-should-contain [
@@ -2753,7 +2821,7 @@ e]
press page-up
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen shows original page again</span>
screen-should-contain [
@@ -2768,15 +2836,15 @@ e]
<span class="Delimiter">{</span>
page-up?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">2/ctrl-b</span>
<span class="muControl">break-unless</span> page-up?
- top-of-screen:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
- old-top:address:duplex-list<span class="Special"> <- </span>copy *top-of-screen
+ top-of-screen:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
+ old-top:address:duplex-list:character<span class="Special"> <- </span>copy *top-of-screen
<span class="Constant"> <move-cursor-begin></span>
editor<span class="Special"> <- </span>page-up editor, screen-height
undo-coalesce-tag:number<span class="Special"> <- </span>copy <span class="Constant">0/never</span>
<span class="Constant"> <move-cursor-end></span>
no-movement?:boolean<span class="Special"> <- </span>equal *top-of-screen, old-top
- <span class="muControl">reply-if</span> no-movement?, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span>
+ go-render?<span class="Special"> <- </span>not no-movement?
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
@@ -2784,36 +2852,34 @@ e]
<span class="Delimiter">{</span>
page-up?:boolean<span class="Special"> <- </span>equal *k, <span class="Constant">65519/page-up</span>
<span class="muControl">break-unless</span> page-up?
- top-of-screen:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
- old-top:address:duplex-list<span class="Special"> <- </span>copy *top-of-screen
+ top-of-screen:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
+ old-top:address:duplex-list:character<span class="Special"> <- </span>copy *top-of-screen
<span class="Constant"> <move-cursor-begin></span>
editor<span class="Special"> <- </span>page-up editor, screen-height
undo-coalesce-tag:number<span class="Special"> <- </span>copy <span class="Constant">0/never</span>
<span class="Constant"> <move-cursor-end></span>
no-movement?:boolean<span class="Special"> <- </span>equal *top-of-screen, old-top
<span class="Comment"># don't bother re-rendering if nothing changed. todo: test this</span>
- <span class="muControl">reply-if</span> no-movement?, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">0/no-more-render</span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span>
+ go-render?<span class="Special"> <- </span>not no-movement?
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
]
-<span class="muRecipe">recipe</span> page-up [
+<span class="muRecipe">recipe</span> page-up editor:address:editor-data, screen-height:number<span class="muRecipe"> -> </span>editor:address:editor-data [
<span class="Constant">local-scope</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- screen-height:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
max:number<span class="Special"> <- </span>subtract screen-height, <span class="Constant">1/menu-bar</span>, <span class="Constant">1/overlapping-line</span>
count:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
- top-of-screen:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
+ top-of-screen:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
<span class="Delimiter">{</span>
done?:boolean<span class="Special"> <- </span>greater-or-equal count, max
<span class="muControl">break-if</span> done?
- prev:address:duplex-list<span class="Special"> <- </span>before-previous-line *top-of-screen, editor
+ prev:address:duplex-list:character<span class="Special"> <- </span>before-previous-line *top-of-screen, editor
<span class="muControl">break-unless</span> prev
*top-of-screen<span class="Special"> <- </span>copy prev
count<span class="Special"> <- </span>add count, <span class="Constant">1</span>
<span class="muControl">loop</span>
<span class="Delimiter">}</span>
- <span class="muControl">reply</span> editor/same-as-ingredient:<span class="Constant">0</span>
]
<span class="muScenario">scenario</span> editor-can-scroll-up-multiple-pages [
@@ -2828,7 +2894,7 @@ e]
<span class="Constant">f</span>
<span class="Constant">g</span>
<span class="Constant">h]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> .a .</span>
@@ -2841,7 +2907,7 @@ e]
press page-down
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen shows third page</span>
screen-should-contain [
@@ -2855,7 +2921,7 @@ e]
press page-up
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen shows second page</span>
screen-should-contain [
@@ -2869,7 +2935,7 @@ e]
press page-up
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen shows original page again</span>
screen-should-contain [
@@ -2895,7 +2961,7 @@ e]
<span class="Constant">n</span>
<span class="Constant">o]</span>
<span class="Comment"># editor screen triggers wrap of last line</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">4/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">4/right</span>
<span class="Comment"># some part of last line is not displayed</span>
screen-should-contain [
<span class="Constant"> . .</span>
@@ -2912,7 +2978,7 @@ e]
press down-arrow
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen shows entire wrapped line</span>
screen-should-contain [
@@ -2928,7 +2994,7 @@ e]
press page-up
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen resets</span>
screen-should-contain [
@@ -2948,7 +3014,7 @@ e]
<span class="Comment"># and still has something left over</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span>
<span class="Constant">bcdefgh]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">4/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">4/right</span>
<span class="Comment"># some part of last line is not displayed</span>
screen-should-contain [
<span class="Constant"> . .</span>
@@ -2961,7 +3027,7 @@ e]
press page-down
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen shows entire wrapped line</span>
screen-should-contain [
@@ -2975,7 +3041,7 @@ e]
press page-up
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># screen resets</span>
screen-should-contain [
@@ -2998,7 +3064,7 @@ e]
<span class="Constant">gxx</span>
<span class="Constant">hxx</span>
<span class="Constant">]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">4/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">4/right</span>
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> .axx .</span>
@@ -3009,7 +3075,7 @@ e]
press page-down
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -3021,7 +3087,7 @@ e]
press page-down
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -3034,7 +3100,7 @@ e]
press page-up
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -3056,7 +3122,7 @@ exy
fxy
gxy
]
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">4/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">4/right</span>
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> .axy .</span>
@@ -3067,7 +3133,7 @@ gxy
press page-down
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -3079,7 +3145,7 @@ gxy
press page-down
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -3092,7 +3158,7 @@ gxy
press page-up
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
diff --git a/html/edit/004-programming-environment.mu.html b/html/edit/004-programming-environment.mu.html
index 406c19a9..172b1dcc 100644
--- a/html/edit/004-programming-environment.mu.html
+++ b/html/edit/004-programming-environment.mu.html
@@ -13,16 +13,16 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
.muRecipe { color: #ff8700; }
-.muData { color: #ffff00; }
.Special { color: #ff6060; }
-.muScenario { color: #00af00; }
+.muData { color: #ffff00; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.SalientComment { color: #00ffff; }
.CommentedCode { color: #6c6c6c; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
+.muScenario { color: #00af00; }
-->
</style>
@@ -46,7 +46,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
initial-sandbox:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span>
hide-screen <span class="Constant">0/screen</span>
env:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment <span class="Constant">0/screen</span>, initial-recipe, initial-sandbox
- env<span class="Special"> <- </span>restore-sandboxes env
render-all <span class="Constant">0/screen</span>, env
event-loop <span class="Constant">0/screen</span>, <span class="Constant">0/console</span>, env
<span class="Comment"># never gets here</span>
@@ -58,15 +57,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
sandbox-in-focus?:boolean <span class="Comment"># false => cursor in recipes; true => cursor in current-sandbox</span>
]
-<span class="muRecipe">recipe</span> new-programming-environment [
+<span class="muRecipe">recipe</span> new-programming-environment screen:address:screen, initial-recipe-contents:address:array:character, initial-sandbox-contents:address:array:character<span class="muRecipe"> -> </span>result:address:programming-environment-data [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- initial-recipe-contents:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- initial-sandbox-contents:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
width:number<span class="Special"> <- </span>screen-width screen
height:number<span class="Special"> <- </span>screen-height screen
<span class="Comment"># top menu</span>
- result:address:programming-environment-data<span class="Special"> <- </span>new <span class="Constant">programming-environment-data:type</span>
+ result<span class="Special"> <- </span>new <span class="Constant">programming-environment-data:type</span>
draw-horizontal screen, <span class="Constant">0</span>, <span class="Constant">0/left</span>, width, <span class="Constant">32/space</span>, <span class="Constant">0/black</span>, <span class="Constant">238/grey</span>
button-start:number<span class="Special"> <- </span>subtract width, <span class="Constant">20</span>
button-on-screen?:boolean<span class="Special"> <- </span>greater-or-equal button-start, <span class="Constant">0</span>
@@ -84,15 +81,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
new-left:number<span class="Special"> <- </span>add divider, <span class="Constant">1</span>
current-sandbox:address:address:editor-data<span class="Special"> <- </span>get-address *result, <span class="Constant">current-sandbox:offset</span>
*current-sandbox<span class="Special"> <- </span>new-editor initial-sandbox-contents, screen, new-left, width/right
-<span class="Constant"> +programming-environment-initialization</span>
- <span class="muControl">reply</span> result
]
-<span class="muRecipe">recipe</span> event-loop [
+<span class="muRecipe">recipe</span> event-loop screen:address:screen, console:address:console, env:address:programming-environment-data [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- console:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
recipes:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">recipes:offset</span>
current-sandbox:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">current-sandbox:offset</span>
sandbox-in-focus?:address:boolean<span class="Special"> <- </span>get-address *env, <span class="Constant">sandbox-in-focus?:offset</span>
@@ -222,10 +215,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">}</span>
]
-<span class="muRecipe">recipe</span> resize [
+<span class="muRecipe">recipe</span> resize screen:address:screen, env:address:programming-environment-data<span class="muRecipe"> -> </span>env:address:programming-environment-data [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
clear-screen screen <span class="Comment"># update screen dimensions</span>
width:number<span class="Special"> <- </span>screen-width screen
divider:number, _<span class="Special"> <- </span>divide-with-remainder width, <span class="Constant">2</span>
@@ -249,16 +241,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
*cursor-row<span class="Special"> <- </span>copy <span class="Constant">1</span>
cursor-column:address:number<span class="Special"> <- </span>get-address *current-sandbox, <span class="Constant">cursor-column:offset</span>
*cursor-column<span class="Special"> <- </span>copy *left
- <span class="muControl">reply</span> env/same-as-ingredient:<span class="Constant">1</span>
]
<span class="muScenario">scenario</span> point-at-multiple-editors [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">30/width</span>, <span class="Constant">5/height</span>
<span class="Comment"># initialize both halves of screen</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[def]</span>
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
<span class="Comment"># focus on both sides</span>
assume-console [
left-click <span class="Constant">1</span>, <span class="Constant">1</span>
@@ -266,7 +257,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
<span class="Comment"># check cursor column in each</span>
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
<span class="Constant">4</span>:address:editor-data<span class="Special"> <- </span>get *<span class="Constant">3</span>:address:programming-environment-data, <span class="Constant">recipes:offset</span>
<span class="Constant">5</span>:number<span class="Special"> <- </span>get *<span class="Constant">4</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
<span class="Constant">6</span>:address:editor-data<span class="Special"> <- </span>get *<span class="Constant">3</span>:address:programming-environment-data, <span class="Constant">current-sandbox:offset</span>
@@ -279,12 +270,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
<span class="muScenario">scenario</span> edit-multiple-editors [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">30/width</span>, <span class="Constant">5/height</span>
<span class="Comment"># initialize both halves of screen</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[def]</span>
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
render-all screen, <span class="Constant">3</span>:address:programming-environment-data
<span class="Comment"># type one letter in each of them</span>
assume-console [
@@ -294,7 +285,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[1]</span>
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
<span class="Constant">4</span>:address:editor-data<span class="Special"> <- </span>get *<span class="Constant">3</span>:address:programming-environment-data, <span class="Constant">recipes:offset</span>
<span class="Constant">5</span>:number<span class="Special"> <- </span>get *<span class="Constant">4</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
<span class="Constant">6</span>:address:editor-data<span class="Special"> <- </span>get *<span class="Constant">3</span>:address:programming-environment-data, <span class="Constant">current-sandbox:offset</span>
@@ -312,7 +303,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
<span class="Comment"># show the cursor at the right window</span>
run [
- print-character screen:address, <span class="Constant">9251/␣/cursor</span>
+ print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span>
]
screen-should-contain [
<span class="Constant"> . run (F4) .</span>
@@ -323,12 +314,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
<span class="muScenario">scenario</span> multiple-editors-cover-only-their-own-areas [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">60/width</span>, <span class="Constant">10/height</span>
run [
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[def]</span>
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
render-all screen, <span class="Constant">3</span>:address:programming-environment-data
]
<span class="Comment"># divider isn't messed up</span>
@@ -342,17 +333,17 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
<span class="muScenario">scenario</span> editor-in-focus-keeps-cursor [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">30/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[def]</span>
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
render-all screen, <span class="Constant">3</span>:address:programming-environment-data
<span class="Comment"># initialize programming environment and highlight cursor</span>
assume-console <span class="Constant">[]</span>
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
- print-character screen:address, <span class="Constant">9251/␣/cursor</span>
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
+ print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span>
]
<span class="Comment"># is cursor at the right place?</span>
screen-should-contain [
@@ -366,8 +357,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[z]</span>
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
- print-character screen:address, <span class="Constant">9251/␣/cursor</span>
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
+ print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span>
]
<span class="Comment"># cursor should still be right</span>
screen-should-contain [
@@ -379,13 +370,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
<span class="muScenario">scenario</span> backspace-in-sandbox-editor-joins-lines [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">30/width</span>, <span class="Constant">5/height</span>
<span class="Comment"># initialize sandbox side with two lines</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span>
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def]</span>
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
render-all screen, <span class="Constant">3</span>:address:programming-environment-data
screen-should-contain [
<span class="Constant"> . run (F4) .</span>
@@ -400,8 +391,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press backspace
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
- print-character screen:address, <span class="Constant">9251/␣/cursor</span>
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
+ print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span>
]
<span class="Comment"># cursor moves to end of old line</span>
screen-should-contain [
@@ -412,10 +403,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
]
-<span class="muRecipe">recipe</span> render-all [
+<span class="muRecipe">recipe</span> render-all screen:address:screen, env:address:programming-environment-data<span class="muRecipe"> -> </span>screen:address:screen [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
trace <span class="Constant">10</span>, <span class="Constant">[app]</span>, <span class="Constant">[render all]</span>
hide-screen screen
<span class="Comment"># top menu</span>
@@ -444,13 +434,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
screen<span class="Special"> <- </span>update-cursor screen, recipes, current-sandbox, sandbox-in-focus?
<span class="Comment">#</span>
show-screen screen
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>
]
-<span class="muRecipe">recipe</span> render-recipes [
+<span class="muRecipe">recipe</span> render-recipes screen:address:screen, env:address:programming-environment-data<span class="muRecipe"> -> </span>screen:address:screen [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
trace <span class="Constant">11</span>, <span class="Constant">[app]</span>, <span class="Constant">[render recipes]</span>
recipes:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">recipes:offset</span>
<span class="Comment"># render recipes</span>
@@ -464,33 +452,27 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
draw-horizontal screen, row, left, right, <span class="Constant">9480/horizontal-dotted</span>
row<span class="Special"> <- </span>add row, <span class="Constant">1</span>
clear-screen-from screen, row, left, left, right
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>
]
<span class="Comment"># replaced in a later layer</span>
-<span class="muRecipe">recipe</span> render-sandbox-side [
+<span class="muRecipe">recipe</span> render-sandbox-side screen:address:screen, env:address:programming-environment-data<span class="muRecipe"> -> </span>screen:address:screen [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
current-sandbox:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">current-sandbox:offset</span>
left:number<span class="Special"> <- </span>get *current-sandbox, <span class="Constant">left:offset</span>
right:number<span class="Special"> <- </span>get *current-sandbox, <span class="Constant">right:offset</span>
row:number, column:number, screen, current-sandbox<span class="Special"> <- </span>render screen, current-sandbox
clear-line-delimited screen, column, right
row<span class="Special"> <- </span>add row, <span class="Constant">1</span>
- <span class="Comment"># draw solid line after recipes (you'll see why in later layers)</span>
+ <span class="Comment"># draw solid line after code (you'll see why in later layers)</span>
draw-horizontal screen, row, left, right, <span class="Constant">9473/horizontal</span>
row<span class="Special"> <- </span>add row, <span class="Constant">1</span>
clear-screen-from screen, row, left, left, right
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>
]
-<span class="muRecipe">recipe</span> update-cursor [
+<span class="muRecipe">recipe</span> update-cursor screen:address:screen, recipes:address:editor-data, current-sandbox:address:editor-data, sandbox-in-focus?:boolean<span class="muRecipe"> -> </span>screen:address:screen [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- recipes:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- current-sandbox:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- sandbox-in-focus?:boolean<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
<span class="Delimiter">{</span>
<span class="muControl">break-if</span> sandbox-in-focus?
cursor-row:number<span class="Special"> <- </span>get *recipes, <span class="Constant">cursor-row:offset</span>
@@ -502,21 +484,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
cursor-column:number<span class="Special"> <- </span>get *current-sandbox, <span class="Constant">cursor-column:offset</span>
<span class="Delimiter">}</span>
screen<span class="Special"> <- </span>move-cursor screen, cursor-row, cursor-column
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>
]
-<span class="Comment"># row, screen <- render-string screen:address, s:address:array:character, left:number, right:number, color:number, row:number</span>
<span class="Comment"># print a string 's' to 'editor' in 'color' starting at 'row'</span>
<span class="Comment"># clear rest of last line, move cursor to next line</span>
-<span class="muRecipe">recipe</span> render-string [
+<span class="muRecipe">recipe</span> render-string screen:address:screen, s:address:array:character, left:number, right:number, color:number, row:number<span class="muRecipe"> -> </span>row:number, screen:address:screen [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- s:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- left:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- right:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- color:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- row:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- <span class="muControl">reply-unless</span> s, row/same-as-ingredient:<span class="Constant">5</span>, screen/same-as-ingredient:<span class="Constant">0</span>
+ <span class="Constant">load-ingredients</span>
+ <span class="muControl">reply-unless</span> s
column:number<span class="Special"> <- </span>copy left
screen<span class="Special"> <- </span>move-cursor screen, row, column
screen-height:number<span class="Special"> <- </span>screen-height screen
@@ -568,20 +543,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">break-if</span> was-at-left?
row<span class="Special"> <- </span>add row, <span class="Constant">1</span>
<span class="Delimiter">}</span>
- move-cursor row, left
- <span class="muControl">reply</span> row/same-as-ingredient:<span class="Constant">5</span>, screen/same-as-ingredient:<span class="Constant">0</span>
+ move-cursor screen, row, left
]
-<span class="Comment"># row, screen <- render-code-string screen:address, s:address:array:character, left:number, right:number, row:number</span>
<span class="Comment"># like 'render-string' but with colorization for comments like in the editor</span>
-<span class="muRecipe">recipe</span> render-code-string [
+<span class="muRecipe">recipe</span> render-code-string screen:address:screen, s:address:array:character, left:number, right:number, row:number<span class="muRecipe"> -> </span>row:number, screen:address:screen [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- s:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- left:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- right:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- row:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- <span class="muControl">reply-unless</span> s, row/same-as-ingredient:<span class="Constant">4</span>, screen/same-as-ingredient:<span class="Constant">0</span>
+ <span class="Constant">load-ingredients</span>
+ <span class="muControl">reply-unless</span> s
color:number<span class="Special"> <- </span>copy <span class="Constant">7/white</span>
column:number<span class="Special"> <- </span>copy left
screen<span class="Special"> <- </span>move-cursor screen, row, column
@@ -635,8 +604,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">break-if</span> was-at-left?
row<span class="Special"> <- </span>add row, <span class="Constant">1</span>
<span class="Delimiter">}</span>
- move-cursor row, left
- <span class="muControl">reply</span> row/same-as-ingredient:<span class="Constant">4</span>, screen/same-as-ingredient:<span class="Constant">0</span>
+ move-cursor screen, row, left
]
<span class="Comment"># ctrl-l - redraw screen (just in case it printed junk somehow)</span>
@@ -667,12 +635,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># ctrl-x - maximize/unmaximize the side with focus</span>
<span class="muScenario">scenario</span> maximize-side [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">30/width</span>, <span class="Constant">5/height</span>
<span class="Comment"># initialize both halves of screen</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[def]</span>
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
screen<span class="Special"> <- </span>render-all screen, <span class="Constant">3</span>:address:programming-environment-data
screen-should-contain [
<span class="Constant"> . run (F4) .</span>
@@ -685,7 +653,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-x
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
<span class="Comment"># only left side visible</span>
screen-should-contain [
@@ -699,7 +667,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-x
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
screen-should-contain [
<span class="Constant"> . run (F4) .</span>
@@ -733,11 +701,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">}</span>
]
-<span class="muRecipe">recipe</span> maximize [
+<span class="muRecipe">recipe</span> maximize screen:address:screen, console:address:console, env:address:programming-environment-data<span class="muRecipe"> -> </span>screen:address:screen, console:address:console [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- console:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
hide-screen screen
<span class="Comment"># maximize one of the sides</span>
maximized?:address:boolean<span class="Special"> <- </span>get-address *env, <span class="Constant">maximized?:offset</span>
@@ -760,7 +726,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
screen<span class="Special"> <- </span>render-sandbox-side screen, env
<span class="Delimiter">}</span>
show-screen screen
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, console/same-as-ingredient:<span class="Constant">1</span>
]
<span class="Comment"># when maximized, wait for any event and simply unmaximize</span>
@@ -794,12 +759,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="SalientComment">## helpers</span>
-<span class="muRecipe">recipe</span> draw-vertical [
+<span class="muRecipe">recipe</span> draw-vertical screen:address:screen, col:number, y:number, bottom:number [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- col:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- y:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- bottom:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
style:character, style-found?:boolean<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
<span class="Delimiter">{</span>
<span class="muControl">break-if</span> style-found?
diff --git a/html/edit/005-sandbox.mu.html b/html/edit/005-sandbox.mu.html
index 7115ca00..3fdab8a0 100644
--- a/html/edit/005-sandbox.mu.html
+++ b/html/edit/005-sandbox.mu.html
@@ -13,15 +13,15 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
-.muScenario { color: #00af00; }
-.muData { color: #ffff00; }
-.Special { color: #ff6060; }
+.muControl { color: #c0a020; }
.muRecipe { color: #ff8700; }
+.Special { color: #ff6060; }
+.muData { color: #ffff00; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.SalientComment { color: #00ffff; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
+.muScenario { color: #00af00; }
-->
</style>
@@ -39,6 +39,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># (non-editable) sandboxes below the editor, showing the result and a maybe</span>
<span class="Comment"># few other things.</span>
+<span class="muRecipe">recipe!</span> main [
+ <span class="Constant">local-scope</span>
+ open-console
+ initial-recipe:address:array:character<span class="Special"> <- </span>restore <span class="Constant">[recipes.mu]</span>
+ initial-sandbox:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span>
+ hide-screen <span class="Constant">0/screen</span>
+ env:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment <span class="Constant">0/screen</span>, initial-recipe, initial-sandbox
+ env<span class="Special"> <- </span>restore-sandboxes env
+ render-all <span class="Constant">0/screen</span>, env
+ event-loop <span class="Constant">0/screen</span>, <span class="Constant">0/console</span>, env
+ <span class="Comment"># never gets here</span>
+]
+
<span class="muData">container</span> programming-environment-data [
sandbox:address:sandbox-data <span class="Comment"># list of sandboxes, from top to bottom</span>
]
@@ -56,19 +69,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
<span class="muScenario">scenario</span> run-and-show-results [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span>
<span class="Comment"># recipe editor is empty</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span>
<span class="Comment"># sandbox editor contains an instruction without storing outputs</span>
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[divide-with-remainder 11, 3]</span>
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
<span class="Comment"># run the code in the editors</span>
assume-console [
press F4
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
<span class="Comment"># check that screen prints the results</span>
screen-should-contain [
@@ -111,7 +124,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press F4
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
<span class="Comment"># check that screen prints the results</span>
screen-should-contain [
@@ -131,8 +144,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
]
-<span class="Comment"># hook into event-loop recipe: read non-unicode keypress from k, process it if</span>
-<span class="Comment"># necessary, then go to next level</span>
<span class="muRecipe">after</span> <span class="Constant"><global-keypress></span> [
<span class="Comment"># F4? load all code and run all sandboxes.</span>
<span class="Delimiter">{</span>
@@ -153,12 +164,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">}</span>
]
-<span class="muRecipe">recipe</span> run-sandboxes [
+<span class="muRecipe">recipe</span> run-sandboxes env:address:programming-environment-data, screen:address:screen<span class="muRecipe"> -> </span>errors-found?:boolean, env:address:programming-environment-data, screen:address:screen [
<span class="Constant">local-scope</span>
- env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- stop?:boolean, env, screen<span class="Special"> <- </span>update-recipes env, screen
- <span class="muControl">reply-if</span> stop?, <span class="Constant">1/errors-found</span>, env/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>
+ <span class="Constant">load-ingredients</span>
+ errors-found?:boolean, env, screen<span class="Special"> <- </span>update-recipes env, screen
+ <span class="muControl">reply-if</span> errors-found?
<span class="Comment"># check contents of right editor (sandbox)</span>
current-sandbox:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">current-sandbox:offset</span>
<span class="Delimiter">{</span>
@@ -175,9 +185,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
*next<span class="Special"> <- </span>copy *dest
*dest<span class="Special"> <- </span>copy new-sandbox
<span class="Comment"># clear sandbox editor</span>
- init:address:address:duplex-list<span class="Special"> <- </span>get-address *current-sandbox, <span class="Constant">data:offset</span>
+ init:address:address:duplex-list:character<span class="Special"> <- </span>get-address *current-sandbox, <span class="Constant">data:offset</span>
*init<span class="Special"> <- </span>push-duplex <span class="Constant">167/§</span>, <span class="Constant">0/tail</span>
- top-of-screen:address:address:duplex-list<span class="Special"> <- </span>get-address *current-sandbox, <span class="Constant">top-of-screen:offset</span>
+ top-of-screen:address:address:duplex-list:character<span class="Special"> <- </span>get-address *current-sandbox, <span class="Constant">top-of-screen:offset</span>
*top-of-screen<span class="Special"> <- </span>copy *init
<span class="Delimiter">}</span>
<span class="Comment"># save all sandboxes before running, just in case we die when running</span>
@@ -186,49 +196,45 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
curr:address:sandbox-data<span class="Special"> <- </span>get *env, <span class="Constant">sandbox:offset</span>
<span class="Delimiter">{</span>
<span class="muControl">break-unless</span> curr
- update-sandbox curr
+ curr<span class="Special"> <- </span>update-sandbox curr
curr<span class="Special"> <- </span>get *curr, <span class="Constant">next-sandbox:offset</span>
<span class="muControl">loop</span>
<span class="Delimiter">}</span>
- <span class="muControl">reply</span> <span class="Constant">0/no-errors-found</span>, env/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>
+ errors-found?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
]
<span class="Comment"># copy code from recipe editor, persist, load into mu</span>
-<span class="Comment"># replaced in a later layer</span>
-<span class="muRecipe">recipe</span> update-recipes [
+<span class="Comment"># replaced in a later layer (whereupon errors-found? will actually be set)</span>
+<span class="muRecipe">recipe</span> update-recipes env:address:programming-environment-data, screen:address:screen<span class="muRecipe"> -> </span>errors-found?:boolean, env:address:programming-environment-data, screen:address:screen [
<span class="Constant">local-scope</span>
- env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
recipes:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">recipes:offset</span>
in:address:array:character<span class="Special"> <- </span>editor-contents recipes
- save <span class="Constant">[recipes.mu]</span>, in
+ save <span class="Constant">[recipes.mu]</span>, in <span class="Comment"># newlayer: persistence</span>
reload in
- <span class="muControl">reply</span> <span class="Constant">0/no-errors-found</span>, env/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>
+ errors-found?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
]
<span class="Comment"># replaced in a later layer</span>
-<span class="muRecipe">recipe</span> update-sandbox [
+<span class="muRecipe">recipe</span> update-sandbox sandbox:address:sandbox-data<span class="muRecipe"> -> </span>sandbox:address:sandbox-data [
<span class="Constant">local-scope</span>
- sandbox:address:sandbox-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
data:address:array:character<span class="Special"> <- </span>get *sandbox, <span class="Constant">data:offset</span>
response:address:address:array:character<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">response:offset</span>
fake-screen:address:address:screen<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">screen:offset</span>
*response, _, *fake-screen<span class="Special"> <- </span>run-interactive data
]
-<span class="muRecipe">recipe</span> update-status [
+<span class="muRecipe">recipe</span> update-status screen:address:screen, msg:address:array:character, color:number<span class="muRecipe"> -> </span>screen:address:screen [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- msg:address:array:character<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- color:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
screen<span class="Special"> <- </span>move-cursor screen, <span class="Constant">0</span>, <span class="Constant">2</span>
screen<span class="Special"> <- </span>print-string screen, msg, color, <span class="Constant">238/grey/background</span>
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>
]
-<span class="muRecipe">recipe</span> save-sandboxes [
+<span class="muRecipe">recipe</span> save-sandboxes env:address:programming-environment-data [
<span class="Constant">local-scope</span>
- env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
current-sandbox:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">current-sandbox:offset</span>
<span class="Comment"># first clear previous versions, in case we deleted some sandbox</span>
$system <span class="Constant">[rm lesson/[0-9]</span>* >/dev/null <span class="Constant">2</span>>/dev/null] <span class="Comment"># some shells can't handle '>&'</span>
@@ -252,10 +258,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">}</span>
]
-<span class="muRecipe">recipe!</span> render-sandbox-side [
+<span class="muRecipe">recipe!</span> render-sandbox-side screen:address:screen, env:address:programming-environment-data<span class="muRecipe"> -> </span>screen:address:screen [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
trace <span class="Constant">11</span>, <span class="Constant">[app]</span>, <span class="Constant">[render sandbox side]</span>
current-sandbox:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">current-sandbox:offset</span>
left:number<span class="Special"> <- </span>get *current-sandbox, <span class="Constant">left:offset</span>
@@ -267,20 +272,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
sandbox:address:sandbox-data<span class="Special"> <- </span>get *env, <span class="Constant">sandbox:offset</span>
row, screen<span class="Special"> <- </span>render-sandboxes screen, sandbox, left, right, row
clear-rest-of-screen screen, row, left, left, right
- <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>
]
-<span class="muRecipe">recipe</span> render-sandboxes [
+<span class="muRecipe">recipe</span> render-sandboxes screen:address:screen, sandbox:address:sandbox-data, left:number, right:number, row:number<span class="muRecipe"> -> </span>row:number, screen:address:screen [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- sandbox:address:sandbox-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- left:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- right:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- row:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- <span class="muControl">reply-unless</span> sandbox, row/same-as-ingredient:<span class="Constant">4</span>, screen/same-as-ingredient:<span class="Constant">0</span>
+ <span class="Constant">load-ingredients</span>
+ <span class="muControl">reply-unless</span> sandbox
screen-height:number<span class="Special"> <- </span>screen-height screen
at-bottom?:boolean<span class="Special"> <- </span>greater-or-equal row, screen-height
- <span class="muControl">reply-if</span> at-bottom?:boolean, row/same-as-ingredient:<span class="Constant">4</span>, screen/same-as-ingredient:<span class="Constant">0</span>
+ <span class="muControl">reply-if</span> at-bottom?:boolean
<span class="Comment"># render sandbox menu</span>
row<span class="Special"> <- </span>add row, <span class="Constant">1</span>
screen<span class="Special"> <- </span>move-cursor screen, row, left
@@ -301,7 +301,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
sandbox-response:address: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>
- sandbox-screen:address<span class="Special"> <- </span>get *sandbox, <span class="Constant">screen:offset</span>
+ sandbox-screen:address:screen<span class="Special"> <- </span>get *sandbox, <span class="Constant">screen:offset</span>
empty-screen?:boolean<span class="Special"> <- </span>fake-screen-is-empty? sandbox-screen
<span class="muControl">break-if</span> empty-screen?
row, screen<span class="Special"> <- </span>render-screen screen, sandbox-screen, left, right, row
@@ -314,19 +314,18 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">}</span>
<span class="Constant"> +render-sandbox-end</span>
at-bottom?:boolean<span class="Special"> <- </span>greater-or-equal row, screen-height
- <span class="muControl">reply-if</span> at-bottom?, row/same-as-ingredient:<span class="Constant">4</span>, screen/same-as-ingredient:<span class="Constant">0</span>
+ <span class="muControl">reply-if</span> at-bottom?
<span class="Comment"># draw solid line after sandbox</span>
draw-horizontal screen, row, left, right, <span class="Constant">9473/horizontal-double</span>
<span class="Comment"># draw next sandbox</span>
next-sandbox:address:sandbox-data<span class="Special"> <- </span>get *sandbox, <span class="Constant">next-sandbox:offset</span>
row, screen<span class="Special"> <- </span>render-sandboxes screen, next-sandbox, left, right, row
- <span class="muControl">reply</span> row/same-as-ingredient:<span class="Constant">4</span>, screen/same-as-ingredient:<span class="Constant">0</span>
]
<span class="Comment"># assumes programming environment has no sandboxes; restores them from previous session</span>
-<span class="muRecipe">recipe</span> restore-sandboxes [
+<span class="muRecipe">recipe</span> restore-sandboxes env:address:programming-environment-data<span class="muRecipe"> -> </span>env:address:programming-environment-data [
<span class="Constant">local-scope</span>
- env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
<span class="Comment"># read all scenarios, pushing them to end of a list of scenarios</span>
suffix:address:array:character<span class="Special"> <- </span>new <span class="Constant">[.out]</span>
idx:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
@@ -352,29 +351,23 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
curr<span class="Special"> <- </span>get-address **curr, <span class="Constant">next-sandbox:offset</span>
<span class="muControl">loop</span>
<span class="Delimiter">}</span>
- <span class="muControl">reply</span> env/same-as-ingredient:<span class="Constant">0</span>
]
-<span class="Comment"># row, screen <- render-screen screen:address, sandbox-screen:address, left:number, right:number, row:number</span>
<span class="Comment"># print the fake sandbox screen to 'screen' with appropriate delimiters</span>
<span class="Comment"># leave cursor at start of next line</span>
-<span class="muRecipe">recipe</span> render-screen [
+<span class="muRecipe">recipe</span> render-screen screen:address:screen, sandbox-screen:address:screen, left:number, right:number, row:number<span class="muRecipe"> -> </span>row:number, screen:address:screen [
<span class="Constant">local-scope</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- s:address:screen<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- left:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- right:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- row:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- <span class="muControl">reply-unless</span> s, row/same-as-ingredient:<span class="Constant">4</span>, screen/same-as-ingredient:<span class="Constant">0</span>
+ <span class="Constant">load-ingredients</span>
+ <span class="muControl">reply-unless</span> sandbox-screen
<span class="Comment"># print 'screen:'</span>
header:address:array:character<span class="Special"> <- </span>new <span class="Constant">[screen:]</span>
row<span class="Special"> <- </span>render-string screen, header, left, right, <span class="Constant">245/grey</span>, row
screen<span class="Special"> <- </span>move-cursor screen, row, left
- <span class="Comment"># start printing s</span>
+ <span class="Comment"># start printing sandbox-screen</span>
column:number<span class="Special"> <- </span>copy left
- s-width:number<span class="Special"> <- </span>screen-width s
- s-height:number<span class="Special"> <- </span>screen-height s
- buf:address:array:screen-cell<span class="Special"> <- </span>get *s, <span class="Constant">data:offset</span>
+ s-width:number<span class="Special"> <- </span>screen-width sandbox-screen
+ s-height:number<span class="Special"> <- </span>screen-height sandbox-screen
+ buf:address:array:screen-cell<span class="Special"> <- </span>get *sandbox-screen, <span class="Constant">data:offset</span>
stop-printing:number<span class="Special"> <- </span>add left, s-width, <span class="Constant">3</span>
max-column:number<span class="Special"> <- </span>min stop-printing, right
i:number<span class="Special"> <- </span>copy <span class="Constant">0</span>
@@ -424,36 +417,33 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
row<span class="Special"> <- </span>add row, <span class="Constant">1</span>
<span class="muControl">loop</span>
<span class="Delimiter">}</span>
- <span class="muControl">reply</span> row/same-as-ingredient:<span class="Constant">4</span>, screen/same-as-ingredient:<span class="Constant">0</span>
]
<span class="muScenario">scenario</span> run-updates-results [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">100/width</span>, <span class="Constant">12/height</span>
<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:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span>
<span class="Constant">recipe foo [</span>
<span class="Constant">z:number <- add 2, 2</span>
+<span class="Constant">reply z</span>
<span class="Constant">]</span>]
<span class="Comment"># sandbox editor contains an instruction without storing outputs</span>
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span>
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
<span class="Comment"># run the code in the editors</span>
assume-console [
press F4
]
- run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
- ]
- <span class="Comment"># check that screen prints the results</span>
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
screen-should-contain [
<span class="Constant"> . run (F4) .</span>
<span class="Constant"> . ┊ .</span>
<span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
<span class="Constant"> .z:number <- add 2, 2 ┊ x.</span>
- <span class="Constant"> .] ┊foo .</span>
- <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 .</span>
- <span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
+ <span class="Constant"> .reply z ┊foo .</span>
+ <span class="Constant"> .] ┊4 .</span>
+<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
<span class="Constant"> . ┊ .</span>
]
<span class="Comment"># make a change (incrementing one of the args to 'add'), then rerun</span>
@@ -464,7 +454,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press F4
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
<span class="Comment"># check that screen updates the result on the right</span>
screen-should-contain [
@@ -472,27 +462,27 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> . ┊ .</span>
<span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
<span class="Constant"> .z:number <- add 2, 3 ┊ x.</span>
- <span class="Constant"> .] ┊foo .</span>
- <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊5 .</span>
- <span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
+ <span class="Constant"> .reply z ┊foo .</span>
+ <span class="Constant"> .] ┊5 .</span>
+<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
<span class="Constant"> . ┊ .</span>
]
]
<span class="muScenario">scenario</span> run-instruction-manages-screen-per-sandbox [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">100/width</span>, <span class="Constant">20/height</span>
<span class="Comment"># left editor is empty</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span>
<span class="Comment"># right editor contains an instruction</span>
- <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[print-integer screen:address, 4]</span>
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[print-integer screen, 4]</span>
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
<span class="Comment"># run the code in the editor</span>
assume-console [
press F4
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
<span class="Comment"># check that it prints a little toy screen</span>
screen-should-contain [
@@ -500,7 +490,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> . ┊ .</span>
<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
<span class="Constant"> . ┊ x.</span>
- <span class="Constant"> . ┊print-integer screen:address, 4 .</span>
+ <span class="Constant"> . ┊print-integer screen, 4 .</span>
<span class="Constant"> . ┊screen: .</span>
<span class="Constant"> . ┊ .4 . .</span>
<span class="Constant"> . ┊ . . .</span>
@@ -512,11 +502,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
]
-<span class="muRecipe">recipe</span> editor-contents [
+<span class="muRecipe">recipe</span> editor-contents editor:address:editor-data<span class="muRecipe"> -> </span>result:address:array:character [
<span class="Constant">local-scope</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
buf:address:buffer<span class="Special"> <- </span>new-buffer <span class="Constant">80</span>
- curr:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">data:offset</span>
+ curr:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">data:offset</span>
<span class="Comment"># skip § sentinel</span>
assert curr, <span class="Constant">[editor without data is illegal; must have at least a sentinel]</span>
curr<span class="Special"> <- </span>next-duplex curr
@@ -528,20 +518,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
curr<span class="Special"> <- </span>next-duplex curr
<span class="muControl">loop</span>
<span class="Delimiter">}</span>
- result:address:array:character<span class="Special"> <- </span>buffer-to-array buf
- <span class="muControl">reply</span> result
+ result<span class="Special"> <- </span>buffer-to-array buf
]
<span class="muScenario">scenario</span> editor-provides-edited-contents [
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
assume-console [
left-click <span class="Constant">1</span>, <span class="Constant">2</span>
type <span class="Constant">[def]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:address:array:character<span class="Special"> <- </span>editor-contents <span class="Constant">2</span>:address:editor-data
<span class="Constant">4</span>:array:character<span class="Special"> <- </span>copy *<span class="Constant">3</span>:address:array:character
]
diff --git a/html/edit/006-sandbox-edit.mu.html b/html/edit/006-sandbox-edit.mu.html
index e5c2d430..a1e3bb2f 100644
--- a/html/edit/006-sandbox-edit.mu.html
+++ b/html/edit/006-sandbox-edit.mu.html
@@ -13,14 +13,14 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
+.muRecipe { color: #ff8700; }
.muScenario { color: #00af00; }
.Special { color: #ff6060; }
-.muRecipe { color: #ff8700; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.SalientComment { color: #00ffff; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
-->
</style>
@@ -35,25 +35,25 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="SalientComment">## editing sandboxes after they've been created</span>
<span class="muScenario">scenario</span> clicking-on-a-sandbox-moves-it-to-editor [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">40/width</span>, <span class="Constant">10/height</span>
<span class="Comment"># basic recipe</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span>
<span class="Constant">recipe foo [</span>
-<span class="Constant"> add 2, 2</span>
+<span class="Constant"> reply 4</span>
<span class="Constant">]</span>]
<span class="Comment"># run it</span>
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span>
assume-console [
press F4
]
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
screen-should-contain [
<span class="Constant"> . run (F4) .</span>
<span class="Constant"> . ┊ .</span>
<span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━.</span>
- <span class="Constant"> . add 2, 2 ┊ x.</span>
+ <span class="Constant"> . reply 4 ┊ x.</span>
<span class="Constant"> .] ┊foo .</span>
<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 .</span>
<span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━.</span>
@@ -64,14 +64,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
left-click <span class="Constant">3</span>, <span class="Constant">30</span>
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
<span class="Comment"># it pops back into editor</span>
screen-should-contain [
<span class="Constant"> . run (F4) .</span>
<span class="Constant"> . ┊foo .</span>
<span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━.</span>
- <span class="Constant"> . add 2, 2 ┊ .</span>
+ <span class="Constant"> . reply 4 ┊ .</span>
<span class="Constant"> .] ┊ .</span>
<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊ .</span>
<span class="Constant"> . ┊ .</span>
@@ -82,13 +82,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[0]</span>
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
screen-should-contain [
<span class="Constant"> . run (F4) .</span>
<span class="Constant"> . ┊0foo .</span>
<span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━.</span>
- <span class="Constant"> . add 2, 2 ┊ .</span>
+ <span class="Constant"> . reply 4 ┊ .</span>
<span class="Constant"> .] ┊ .</span>
<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊ .</span>
<span class="Constant"> . ┊ .</span>
@@ -97,8 +97,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
<span class="muRecipe">after</span> <span class="Constant"><global-touch></span> [
- <span class="Comment"># right side of screen and below sandbox editor? pop appropriate sandbox</span>
- <span class="Comment"># contents back into sandbox editor provided it's empty</span>
+ <span class="Comment"># below sandbox editor? pop appropriate sandbox contents back into sandbox editor</span>
<span class="Delimiter">{</span>
sandbox-left-margin:number<span class="Special"> <- </span>get *current-sandbox, <span class="Constant">left:offset</span>
click-column:number<span class="Special"> <- </span>get *t, <span class="Constant">column:offset</span>
@@ -111,7 +110,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
below-sandbox-editor?:boolean<span class="Special"> <- </span>greater-or-equal click-row, first-sandbox-begins
<span class="muControl">break-unless</span> below-sandbox-editor?
empty-sandbox-editor?:boolean<span class="Special"> <- </span>empty-editor? current-sandbox
- <span class="muControl">break-unless</span> empty-sandbox-editor? <span class="Comment"># make the user hit F4 before editing a new sandbox</span>
+ <span class="muControl">break-unless</span> empty-sandbox-editor? <span class="Comment"># don't clobber existing contents</span>
<span class="Comment"># identify the sandbox to edit and remove it from the sandbox list</span>
sandbox:address:sandbox-data<span class="Special"> <- </span>extract-sandbox env, click-row
text:address:array:character<span class="Special"> <- </span>get *sandbox, <span class="Constant">data:offset</span>
@@ -124,19 +123,17 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">}</span>
]
-<span class="muRecipe">recipe</span> empty-editor? [
+<span class="muRecipe">recipe</span> empty-editor? editor:address:editor-data<span class="muRecipe"> -> </span>result:boolean [
<span class="Constant">local-scope</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- head:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">data:offset</span>
- first:address:duplex-list<span class="Special"> <- </span>next-duplex head
- result:boolean<span class="Special"> <- </span>not first
- <span class="muControl">reply</span> result
+ <span class="Constant">load-ingredients</span>
+ head:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">data:offset</span>
+ first:address:duplex-list:character<span class="Special"> <- </span>next-duplex head
+ result<span class="Special"> <- </span>not first
]
-<span class="muRecipe">recipe</span> extract-sandbox [
+<span class="muRecipe">recipe</span> extract-sandbox env:address:programming-environment-data, click-row:number<span class="muRecipe"> -> </span>result:address:sandbox-data [
<span class="Constant">local-scope</span>
- env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- click-row:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
<span class="Comment"># assert click-row >= sandbox.starting-row-on-screen</span>
sandbox:address:address:sandbox-data<span class="Special"> <- </span>get-address *env, <span class="Constant">sandbox:offset</span>
start:number<span class="Special"> <- </span>get **sandbox, <span class="Constant">starting-row-on-screen:offset</span>
@@ -153,7 +150,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">loop</span>
<span class="Delimiter">}</span>
<span class="Comment"># snip sandbox out of its list</span>
- result:address:sandbox-data<span class="Special"> <- </span>copy *sandbox
+ result<span class="Special"> <- </span>copy *sandbox
*sandbox<span class="Special"> <- </span>copy next-sandbox
<span class="Comment"># position cursor in sandbox editor</span>
sandbox-in-focus?:address:boolean<span class="Special"> <- </span>get-address *env, <span class="Constant">sandbox-in-focus?:offset</span>
@@ -162,26 +159,24 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
<span class="muScenario">scenario</span> sandbox-with-print-can-be-edited [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">100/width</span>, <span class="Constant">20/height</span>
<span class="Comment"># left editor is empty</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span>
<span class="Comment"># right editor contains an instruction</span>
- <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[print-integer screen:address, 4]</span>
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[print-integer screen, 4]</span>
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
<span class="Comment"># run the sandbox</span>
assume-console [
press F4
]
- run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
- ]
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
screen-should-contain [
<span class="Constant"> . run (F4) .</span>
<span class="Constant"> . ┊ .</span>
<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
<span class="Constant"> . ┊ x.</span>
- <span class="Constant"> . ┊print-integer screen:address, 4 .</span>
+ <span class="Constant"> . ┊print-integer screen, 4 .</span>
<span class="Constant"> . ┊screen: .</span>
<span class="Constant"> . ┊ .4 . .</span>
<span class="Constant"> . ┊ . . .</span>
@@ -196,11 +191,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
left-click <span class="Constant">3</span>, <span class="Constant">70</span>
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
screen-should-contain [
<span class="Constant"> . run (F4) .</span>
- <span class="Constant"> . ┊print-integer screen:address, 4 .</span>
+ <span class="Constant"> . ┊print-integer screen, 4 .</span>
<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
<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 5f3cdfcf..f563b266 100644
--- a/html/edit/007-sandbox-delete.mu.html
+++ b/html/edit/007-sandbox-delete.mu.html
@@ -13,14 +13,14 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
+.muRecipe { color: #ff8700; }
.muScenario { color: #00af00; }
.Special { color: #ff6060; }
-.muRecipe { color: #ff8700; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.SalientComment { color: #00ffff; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
-->
</style>
@@ -35,11 +35,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="SalientComment">## deleting sandboxes</span>
<span class="muScenario">scenario</span> deleting-sandboxes [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span>
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span>
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
<span class="Comment"># run a few commands</span>
assume-console [
left-click <span class="Constant">1</span>, <span class="Constant">80</span>
@@ -48,9 +48,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[add 2, 2]</span>
press F4
]
- run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
- ]
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
screen-should-contain [
<span class="Constant"> . run (F4) .</span>
<span class="Constant"> . ┊ .</span>
@@ -71,7 +69,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
left-click <span class="Constant">7</span>, <span class="Constant">99</span>
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
screen-should-contain [
<span class="Constant"> . run (F4) .</span>
@@ -89,7 +87,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
left-click <span class="Constant">3</span>, <span class="Constant">99</span>
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
screen-should-contain [
<span class="Constant"> . run (F4) .</span>
@@ -113,11 +111,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">}</span>
]
-<span class="Comment"># was-deleted?:boolean <- delete-sandbox t:touch-event, env:address:programming-environment-data</span>
-<span class="muRecipe">recipe</span> delete-sandbox [
+<span class="muRecipe">recipe</span> delete-sandbox t:touch-event, env:address:programming-environment-data<span class="muRecipe"> -> </span>was-delete?:boolean [
<span class="Constant">local-scope</span>
- t:touch-event<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
click-column:number<span class="Special"> <- </span>get t, <span class="Constant">column:offset</span>
current-sandbox:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">current-sandbox:offset</span>
right:number<span class="Special"> <- </span>get *current-sandbox, <span class="Constant">right:offset</span>
diff --git a/html/edit/008-sandbox-test.mu.html b/html/edit/008-sandbox-test.mu.html
index 0cdd6a08..08b62ddc 100644
--- a/html/edit/008-sandbox-test.mu.html
+++ b/html/edit/008-sandbox-test.mu.html
@@ -13,14 +13,14 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
+.muRecipe { color: #ff8700; }
.muScenario { color: #00af00; }
.Special { color: #ff6060; }
-.muRecipe { color: #ff8700; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.SalientComment { color: #00ffff; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
-->
</style>
@@ -35,25 +35,25 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="SalientComment">## clicking on sandbox results to 'fix' them and turn sandboxes into tests</span>
<span class="muScenario">scenario</span> sandbox-click-on-result-toggles-color-to-green [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">40/width</span>, <span class="Constant">10/height</span>
<span class="Comment"># basic recipe</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span>
<span class="Constant">recipe foo [</span>
-<span class="Constant"> add 2, 2</span>
+<span class="Constant"> reply 4</span>
<span class="Constant">]</span>]
<span class="Comment"># run it</span>
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span>
assume-console [
press F4
]
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
screen-should-contain [
<span class="Constant"> . run (F4) .</span>
<span class="Constant"> . ┊ .</span>
<span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━.</span>
- <span class="Constant"> . add 2, 2 ┊ x.</span>
+ <span class="Constant"> . reply 4 ┊ x.</span>
<span class="Constant"> .] ┊foo .</span>
<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 .</span>
<span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━.</span>
@@ -64,7 +64,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
left-click <span class="Constant">5</span>, <span class="Constant">21</span>
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
<span class="Comment"># color toggles to green</span>
screen-should-contain-in-color <span class="Constant">2/green</span>, [
@@ -79,19 +79,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
<span class="Comment"># cursor should remain unmoved</span>
run [
- print-character screen:address, <span class="Constant">9251/␣/cursor</span>
+ print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span>
]
screen-should-contain [
<span class="Constant"> . run (F4) .</span>
<span class="Constant"> .␣ ┊ .</span>
<span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━.</span>
- <span class="Constant"> . add 2, 2 ┊ x.</span>
+ <span class="Constant"> . reply 4 ┊ x.</span>
<span class="Constant"> .] ┊foo .</span>
<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 .</span>
<span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━.</span>
<span class="Constant"> . ┊ .</span>
]
- <span class="Comment"># now change the second arg of the 'add'</span>
+ <span class="Comment"># now change the result</span>
<span class="Comment"># then rerun</span>
assume-console [
left-click <span class="Constant">3</span>, <span class="Constant">11</span> <span class="Comment"># cursor to end of line</span>
@@ -100,7 +100,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press F4
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
<span class="Comment"># result turns red</span>
screen-should-contain-in-color <span class="Constant">1/red</span>, [
@@ -109,7 +109,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> . .</span>
<span class="Constant"> . .</span>
<span class="Constant"> . .</span>
- <span class="Constant"> . 5 .</span>
+ <span class="Constant"> . 3 .</span>
<span class="Constant"> . .</span>
<span class="Constant"> . .</span>
]
@@ -117,7 +117,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<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"># right side of screen? check if it's inside the output of any sandbox</span>
+ <span class="Comment"># check if it's inside the output of any sandbox</span>
<span class="Delimiter">{</span>
sandbox-left-margin:number<span class="Special"> <- </span>get *current-sandbox, <span class="Constant">left:offset</span>
click-column:number<span class="Special"> <- </span>get *t, <span class="Constant">column:offset</span>
@@ -144,10 +144,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">}</span>
]
-<span class="muRecipe">recipe</span> find-click-in-sandbox-output [
+<span class="muRecipe">recipe</span> find-click-in-sandbox-output env:address:programming-environment-data, click-row:number<span class="muRecipe"> -> </span>sandbox:address:sandbox-data [
<span class="Constant">local-scope</span>
- env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- click-row:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
<span class="Comment"># assert click-row >= sandbox.starting-row-on-screen</span>
sandbox:address:sandbox-data<span class="Special"> <- </span>get *env, <span class="Constant">sandbox:offset</span>
start:number<span class="Special"> <- </span>get *sandbox, <span class="Constant">starting-row-on-screen:offset</span>
@@ -171,9 +170,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">reply</span> sandbox
]
-<span class="muRecipe">recipe</span> toggle-expected-response [
+<span class="muRecipe">recipe</span> toggle-expected-response sandbox:address:sandbox-data<span class="muRecipe"> -> </span>sandbox:address:sandbox-data [
<span class="Constant">local-scope</span>
- sandbox:address:sandbox-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
expected-response:address:address:array:character<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">expected-response:offset</span>
<span class="Delimiter">{</span>
<span class="Comment"># if expected-response is set, reset</span>
@@ -184,7 +183,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># if not, current response is the expected response</span>
response:address:array:character<span class="Special"> <- </span>get *sandbox, <span class="Constant">response:offset</span>
*expected-response<span class="Special"> <- </span>copy response
- <span class="muControl">reply</span> sandbox/same-as-ingredient:<span class="Constant">0</span>
]
<span class="Comment"># when rendering a sandbox, color it in red/green if expected response exists</span>
diff --git a/html/edit/009-sandbox-trace.mu.html b/html/edit/009-sandbox-trace.mu.html
index b73fbee6..071f62af 100644
--- a/html/edit/009-sandbox-trace.mu.html
+++ b/html/edit/009-sandbox-trace.mu.html
@@ -13,15 +13,15 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
+.muRecipe { color: #ff8700; }
.muScenario { color: #00af00; }
.muData { color: #ffff00; }
.Special { color: #ff6060; }
-.muRecipe { color: #ff8700; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.SalientComment { color: #00ffff; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
-->
</style>
@@ -36,7 +36,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="SalientComment">## clicking on the code typed into a sandbox toggles its trace</span>
<span class="muScenario">scenario</span> sandbox-click-on-code-toggles-app-trace [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">40/width</span>, <span class="Constant">10/height</span>
<span class="Comment"># basic recipe</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span>
@@ -48,8 +48,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-console [
press F4
]
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
screen-should-contain [
<span class="Constant"> . run (F4) .</span>
<span class="Constant"> . ┊ .</span>
@@ -59,13 +59,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━.</span>
<span class="Constant"> . ┊ .</span>
]
- <span class="Comment"># click on the 'foo' line in the sandbox</span>
+ <span class="Comment"># click on the code in the sandbox</span>
assume-console [
left-click <span class="Constant">4</span>, <span class="Constant">21</span>
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
- print-character screen:address, <span class="Constant">9251/␣/cursor</span>
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
+ print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span>
]
<span class="Comment"># trace now printed and cursor shouldn't have budged</span>
screen-should-contain [
@@ -93,8 +93,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
left-click <span class="Constant">4</span>, <span class="Constant">25</span>
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
- print-character screen:address, <span class="Constant">9251/␣/cursor</span>
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
+ print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span>
]
<span class="Comment"># trace hidden again</span>
screen-should-contain [
@@ -109,45 +109,45 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
<span class="muScenario">scenario</span> sandbox-shows-app-trace-and-result [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">40/width</span>, <span class="Constant">10/height</span>
<span class="Comment"># basic recipe</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span>
<span class="Constant">recipe foo [</span>
<span class="Constant"> stash [abc]</span>
- add <span class="Constant">2</span>, <span class="Constant">2</span>
+ <span class="muControl">reply</span> <span class="Constant">4</span>
]]
<span class="Comment"># run it</span>
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span>
assume-console [
press F4
]
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
screen-should-contain [
<span class="Constant"> . run (F4) .</span>
<span class="Constant"> . ┊ .</span>
<span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━.</span>
<span class="Constant"> . stash [abc] ┊ x.</span>
- <span class="Constant"> . add 2, 2 ┊foo .</span>
+ <span class="Constant"> . reply 4 ┊foo .</span>
<span class="Constant"> .] ┊4 .</span>
<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━.</span>
<span class="Constant"> . ┊ .</span>
]
- <span class="Comment"># click on the 'foo' line in the sandbox</span>
+ <span class="Comment"># click on the code in the sandbox</span>
assume-console [
left-click <span class="Constant">4</span>, <span class="Constant">21</span>
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
- <span class="Comment"># trace now printed</span>
+ <span class="Comment"># trace now printed above result</span>
screen-should-contain [
<span class="Constant"> . run (F4) .</span>
<span class="Constant"> . ┊ .</span>
<span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━.</span>
<span class="Constant"> . stash [abc] ┊ x.</span>
- <span class="Constant"> . add 2, 2 ┊foo .</span>
+ <span class="Constant"> . reply 4 ┊foo .</span>
<span class="Constant"> .] ┊abc .</span>
<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊4 .</span>
<span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━.</span>
@@ -161,9 +161,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
<span class="Comment"># replaced in a later layer</span>
-<span class="muRecipe">recipe!</span> update-sandbox [
+<span class="muRecipe">recipe!</span> update-sandbox sandbox:address:sandbox-data<span class="muRecipe"> -> </span>sandbox:address:sandbox-data [
<span class="Constant">local-scope</span>
- sandbox:address:sandbox-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
data:address:array:character<span class="Special"> <- </span>get *sandbox, <span class="Constant">data:offset</span>
response:address:address:array:character<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">response:offset</span>
trace:address:address:array:character<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">trace:offset</span>
@@ -173,7 +173,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># clicks on sandbox code toggle its display-trace? flag</span>
<span class="muRecipe">after</span> <span class="Constant"><global-touch></span> [
- <span class="Comment"># right side of screen? check if it's inside the code of any sandbox</span>
+ <span class="Comment"># check if it's inside the code of any sandbox</span>
<span class="Delimiter">{</span>
sandbox-left-margin:number<span class="Special"> <- </span>get *current-sandbox, <span class="Constant">left:offset</span>
click-column:number<span class="Special"> <- </span>get *t, <span class="Constant">column:offset</span>
@@ -200,12 +200,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">}</span>
]
-<span class="muRecipe">recipe</span> find-click-in-sandbox-code [
+<span class="muRecipe">recipe</span> find-click-in-sandbox-code env:address:programming-environment-data, click-row:number<span class="muRecipe"> -> </span>sandbox:address:sandbox-data [
<span class="Constant">local-scope</span>
- env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- click-row:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
<span class="Comment"># assert click-row >= sandbox.starting-row-on-screen</span>
- sandbox:address:sandbox-data<span class="Special"> <- </span>get *env, <span class="Constant">sandbox:offset</span>
+ sandbox<span class="Special"> <- </span>get *env, <span class="Constant">sandbox:offset</span>
start:number<span class="Special"> <- </span>get *sandbox, <span class="Constant">starting-row-on-screen:offset</span>
clicked-on-sandboxes?:boolean<span class="Special"> <- </span>greater-or-equal click-row, start
assert clicked-on-sandboxes?, <span class="Constant">[extract-sandbox called on click to sandbox editor]</span>
@@ -241,6 +240,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">break-unless</span> sandbox-trace <span class="Comment"># nothing to print; move on</span>
row, screen<span class="Special"> <- </span>render-string, screen, sandbox-trace, left, right, <span class="Constant">245/grey</span>, row
<span class="Delimiter">}</span>
+<span class="Constant"> <render-sandbox-trace-done></span>
]
</pre>
</body>
diff --git a/html/edit/010-warnings.mu.html b/html/edit/010-warnings.mu.html
index ca9008b7..335bfb42 100644
--- a/html/edit/010-warnings.mu.html
+++ b/html/edit/010-warnings.mu.html
@@ -13,15 +13,15 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
.muRecipe { color: #ff8700; }
-.muData { color: #ffff00; }
.Special { color: #ff6060; }
-.muScenario { color: #00af00; }
+.muData { color: #ffff00; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.SalientComment { color: #00ffff; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
+.muScenario { color: #00af00; }
-->
</style>
@@ -40,10 +40,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
<span class="Comment"># copy code from recipe editor, persist, load into mu, save any warnings</span>
-<span class="muRecipe">recipe!</span> update-recipes [
+<span class="muRecipe">recipe!</span> update-recipes env:address:programming-environment-data, screen:address:screen<span class="muRecipe"> -> </span>errors-found?:boolean, env:address:programming-environment-data, screen:address:screen [
<span class="Constant">local-scope</span>
- env:address:programming-environment-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- screen:address<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
recipes:address:editor-data<span class="Special"> <- </span>get *env, <span class="Constant">recipes:offset</span>
in:address:array:character<span class="Special"> <- </span>editor-contents recipes
save <span class="Constant">[recipes.mu]</span>, in
@@ -54,9 +53,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">break-unless</span> *recipe-warnings
status:address:array:character<span class="Special"> <- </span>new <span class="Constant">[errors found]</span>
update-status screen, status, <span class="Constant">1/red</span>
- <span class="muControl">reply</span> <span class="Constant">1/errors-found</span>, env/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>
+ errors-found?<span class="Special"> <- </span>copy <span class="Constant">1/true</span>
+ <span class="muControl">reply</span>
<span class="Delimiter">}</span>
- <span class="muControl">reply</span> <span class="Constant">0/no-errors-found</span>, env/same-as-ingredient:<span class="Constant">0</span>, screen/same-as-ingredient:<span class="Constant">1</span>
+ errors-found?<span class="Special"> <- </span>copy <span class="Constant">0/false</span>
]
<span class="muRecipe">before</span> <span class="Constant"><render-components-end></span> [
@@ -81,9 +81,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
warnings:address:array:character
]
-<span class="muRecipe">recipe!</span> update-sandbox [
+<span class="muRecipe">recipe!</span> update-sandbox sandbox:address:sandbox-data<span class="muRecipe"> -> </span>sandbox:address:sandbox-data [
<span class="Constant">local-scope</span>
- sandbox:address:sandbox-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
data:address:array:character<span class="Special"> <- </span>get *sandbox, <span class="Constant">data:offset</span>
response:address:address:array:character<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">response:offset</span>
warnings:address:address:array:character<span class="Special"> <- </span>get-address *sandbox, <span class="Constant">warnings:offset</span>
@@ -98,30 +98,32 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">}</span>
]
-<span class="muRecipe">after</span> <span class="Constant"><render-sandbox-results></span> [
+<span class="Comment"># make sure we render any trace</span>
+<span class="muRecipe">after</span> <span class="Constant"><render-sandbox-trace-done></span> [
<span class="Delimiter">{</span>
sandbox-warnings:address:array:character<span class="Special"> <- </span>get *sandbox, <span class="Constant">warnings:offset</span>
<span class="muControl">break-unless</span> sandbox-warnings
*response-starting-row<span class="Special"> <- </span>copy <span class="Constant">0</span> <span class="Comment"># no response</span>
row, screen<span class="Special"> <- </span>render-string screen, sandbox-warnings, left, right, <span class="Constant">1/red</span>, row
+ <span class="Comment"># don't try to print anything more for this sandbox</span>
<span class="muControl">jump</span> <span class="Constant">+render-sandbox-end:label</span>
<span class="Delimiter">}</span>
]
<span class="muScenario">scenario</span> run-shows-warnings-in-get [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span>
<span class="Constant">recipe foo [</span>
<span class="Constant"> get 123:number, foo:offset</span>
<span class="Constant">]</span>]
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span>
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
assume-console [
press F4
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
screen-should-contain [
<span class="Constant"> . errors found run (F4) .</span>
@@ -129,7 +131,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
<span class="Constant"> . get 123:number, foo:offset ┊ .</span>
<span class="Constant"> .] ┊ .</span>
- <span class="Constant"> .unknown element foo in container number ┊ .</span>
+ <span class="Constant"> .foo: unknown element foo in container number ┊ .</span>
+ <span class="Constant"> .foo: first ingredient of 'get' should be a contai↩┊ .</span>
+ <span class="Constant"> .ner, but got 123:number ┊ .</span>
<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊ .</span>
<span class="Constant"> . ┊ .</span>
]
@@ -139,25 +143,27 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> . .</span>
<span class="Constant"> . .</span>
<span class="Constant"> . .</span>
- <span class="Constant"> .unknown element foo in container number .</span>
+ <span class="Constant"> .foo: unknown element foo in container number .</span>
+ <span class="Constant"> .foo: first ingredient of 'get' should be a contai .</span>
+ <span class="Constant"> .ner, but got 123:number .</span>
<span class="Constant"> . .</span>
]
]
<span class="muScenario">scenario</span> run-shows-missing-type-warnings [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span>
<span class="Constant">recipe foo [</span>
<span class="Constant"> x <- copy 0</span>
<span class="Constant">]</span>]
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span>
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
assume-console [
press F4
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
screen-should-contain [
<span class="Constant"> . errors found run (F4) .</span>
@@ -165,14 +171,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
<span class="Constant"> . x <- copy 0 ┊ .</span>
<span class="Constant"> .] ┊ .</span>
- <span class="Constant"> .missing type in 'x <- copy 0' ┊ .</span>
- <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊ .</span>
- <span class="Constant"> . ┊ .</span>
+ <span class="Constant"> .foo: missing type for x in 'x <- copy 0' ┊ .</span>
]
]
<span class="muScenario">scenario</span> run-shows-unbalanced-bracket-warnings [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span>
<span class="Comment"># recipe is incomplete (unbalanced '[')</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span>
@@ -181,12 +185,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">]</span>
string-replace <span class="Constant">1</span>:address:array:character, <span class="Constant">171/«</span>, <span class="Constant">91</span> <span class="Comment"># '['</span>
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span>
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
assume-console [
press F4
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
screen-should-contain [
<span class="Constant"> . errors found run (F4) .</span>
@@ -201,7 +205,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
<span class="muScenario">scenario</span> run-shows-get-on-non-container-warnings [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span>
<span class="Constant">recipe foo [</span>
@@ -209,28 +213,29 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> get x:address:point, 1:offset</span>
<span class="Constant">]</span>]
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span>
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
assume-console [
press F4
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
screen-should-contain [
- <span class="Constant"> . run (F4) .</span>
- <span class="Constant"> . ┊ .</span>
+ <span class="Constant"> . errors found run (F4) .</span>
+ <span class="Constant"> . ┊foo .</span>
<span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
- <span class="Constant"> . x:address:point <- new point:type ┊ x.</span>
- <span class="Constant"> . get x:address:point, 1:offset ┊foo .</span>
- <span class="Constant"> .] ┊foo: first ingredient of 'get' should be a conta↩.</span>
- <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊iner, but got x:address:point .</span>
- <span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
+ <span class="Constant"> . x:address:point <- new point:type ┊ .</span>
+ <span class="Constant"> . get x:address:point, 1:offset ┊ .</span>
+ <span class="Constant"> .] ┊ .</span>
+ <span class="Constant"> .foo: first ingredient of 'get' should be a contai↩┊ .</span>
+ <span class="Constant"> .ner, but got x:address:point ┊ .</span>
+ <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊ .</span>
<span class="Constant"> . ┊ .</span>
]
]
<span class="muScenario">scenario</span> run-shows-non-literal-get-argument-warnings [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span>
<span class="Constant">recipe foo [</span>
@@ -239,12 +244,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> get *y:address:point, x:number</span>
<span class="Constant">]</span>]
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span>
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
assume-console [
press F4
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
screen-should-contain [
<span class="Constant"> . errors found run (F4) .</span>
@@ -256,13 +261,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> .] ┊ .</span>
<span class="Constant"> .foo: expected ingredient 1 of 'get' to have type ↩┊ .</span>
<span class="Constant"> .'offset'; got x:number ┊ .</span>
+ <span class="Constant"> .foo: second ingredient of 'get' should have type ↩┊ .</span>
+ <span class="Constant"> .'offset', but got x:number ┊ .</span>
<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊ .</span>
<span class="Constant"> . ┊ .</span>
]
]
<span class="muScenario">scenario</span> run-shows-warnings-everytime [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
<span class="Comment"># try to run a file with an error</span>
assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ </span>
@@ -270,12 +277,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> x:number <- copy y:number</span>
<span class="Constant">]</span>]
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span>
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
assume-console [
press F4
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
screen-should-contain [
<span class="Constant"> . errors found run (F4) .</span>
@@ -283,7 +290,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
<span class="Constant"> . x:number <- copy y:number ┊ .</span>
<span class="Constant"> .] ┊ .</span>
- <span class="Constant"> .use before set: y in foo ┊ .</span>
+ <span class="Constant"> .foo: use before set: y ┊ .</span>
<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊ .</span>
<span class="Constant"> . ┊ .</span>
]
@@ -292,7 +299,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press F4
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
screen-should-contain [
<span class="Constant"> . errors found run (F4) .</span>
@@ -300,26 +307,26 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> .recipe foo [ ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
<span class="Constant"> . x:number <- copy y:number ┊ .</span>
<span class="Constant"> .] ┊ .</span>
- <span class="Constant"> .use before set: y in foo ┊ .</span>
+ <span class="Constant"> .foo: use before set: y ┊ .</span>
<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊ .</span>
<span class="Constant"> . ┊ .</span>
]
]
<span class="muScenario">scenario</span> run-instruction-and-print-warnings [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">100/width</span>, <span class="Constant">10/height</span>
<span class="Comment"># left editor is empty</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span>
<span class="Comment"># right editor contains an illegal instruction</span>
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[get 1234:number, foo:offset]</span>
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
<span class="Comment"># run the code in the editors</span>
assume-console [
press F4
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
<span class="Comment"># check that screen prints error message in red</span>
screen-should-contain [
@@ -329,6 +336,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> . ┊ x.</span>
<span class="Constant"> . ┊get 1234:number, foo:offset .</span>
<span class="Constant"> . ┊unknown element foo in container number .</span>
+ <span class="Constant"> . ┊first ingredient of 'get' should be a container,↩.</span>
+ <span class="Constant"> . ┊ but got 1234:number .</span>
<span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
<span class="Constant"> . ┊ .</span>
]
@@ -349,6 +358,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> . .</span>
<span class="Constant"> . .</span>
<span class="Constant"> . unknown element foo in container number .</span>
+ <span class="Constant"> . first ingredient of 'get' should be a container, .</span>
+ <span class="Constant"> . but got 1234:number .</span>
<span class="Constant"> . .</span>
]
screen-should-contain-in-color <span class="Constant">245/grey</span>, [
@@ -358,26 +369,28 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> . ┊ x.</span>
<span class="Constant"> . ┊ .</span>
<span class="Constant"> . ┊ .</span>
+ <span class="Constant"> . ┊ ↩.</span>
+ <span class="Constant"> . ┊ .</span>
<span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
<span class="Constant"> . ┊ .</span>
]
]
<span class="muScenario">scenario</span> run-instruction-and-print-warnings-only-once [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">100/width</span>, <span class="Constant">10/height</span>
<span class="Comment"># left editor is empty</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span>
<span class="Comment"># right editor contains an illegal instruction</span>
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[get 1234:number, foo:offset]</span>
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
<span class="Comment"># run the code in the editors multiple times</span>
assume-console [
press F4
press F4
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
<span class="Comment"># check that screen prints error message just once</span>
screen-should-contain [
@@ -387,13 +400,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> . ┊ x.</span>
<span class="Constant"> . ┊get 1234:number, foo:offset .</span>
<span class="Constant"> . ┊unknown element foo in container number .</span>
+ <span class="Constant"> . ┊first ingredient of 'get' should be a container,↩.</span>
+ <span class="Constant"> . ┊ but got 1234:number .</span>
<span class="Constant"> . ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
<span class="Constant"> . ┊ .</span>
]
]
<span class="muScenario">scenario</span> sandbox-can-handle-infinite-loop [
- $close-trace <span class="Comment"># trace too long</span>
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
assume-screen <span class="Constant">100/width</span>, <span class="Constant">20/height</span>
<span class="Comment"># left editor is empty</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[recipe foo [</span>
@@ -403,13 +418,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">]</span>]
<span class="Comment"># right editor contains an instruction</span>
<span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo]</span>
- <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
<span class="Comment"># run the sandbox</span>
assume-console [
press F4
]
run [
- event-loop screen:address, console:address, <span class="Constant">3</span>:address:programming-environment-data
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
]
screen-should-contain [
<span class="Constant"> . run (F4) .</span>
@@ -422,6 +437,55 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant"> . ┊ .</span>
]
]
+
+<span class="muScenario">scenario</span> sandbox-with-warnings-shows-trace [
+ trace-until <span class="Constant">100/app</span> <span class="Comment"># trace too long</span>
+ assume-screen <span class="Constant">100/width</span>, <span class="Constant">10/height</span>
+ <span class="Comment"># generate a stash and a warning</span>
+ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[recipe foo [</span>
+<span class="Constant">local-scope</span>
+<span class="Constant">a:number <- next-ingredient</span>
+<span class="Constant">b:number <- next-ingredient</span>
+<span class="Constant">stash [dividing by]</span>, b
+_, c:number<span class="Special"> <- </span>divide-with-remainder a, b
+<span class="muControl">reply</span> b
+]]
+ <span class="Constant">2</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[foo 4, 0]</span>
+ <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> <- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+ <span class="Comment"># run</span>
+ assume-console [
+ press F4
+ ]
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
+ <span class="Comment"># screen prints error message</span>
+ screen-should-contain [
+ <span class="Constant"> . run (F4) .</span>
+ <span class="Constant"> .recipe foo \\\[ ┊ .</span>
+ <span class="Constant"> .local-scope ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
+ <span class="Constant"> .a:number <- next-ingredient ┊ x.</span>
+ <span class="Constant"> .b:number <- next-ingredient ┊foo 4, 0 .</span>
+ <span class="Constant"> .stash [dividing by], b ┊foo: divide by zero in '_, c:number <- divide-wi↩.</span>
+ <span class="Constant"> ._, c:number <- divide-with-remainder a, b ┊th-remainder a, b' .</span>
+ ]
+ <span class="Comment"># click on the call in the sandbox</span>
+ assume-console [
+ left-click <span class="Constant">4</span>, <span class="Constant">55</span>
+ ]
+ run [
+ event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
+ ]
+ <span class="Comment"># screen should expand trace</span>
+ screen-should-contain [
+ <span class="Constant"> . run (F4) .</span>
+ <span class="Constant"> .recipe foo \\\[ ┊ .</span>
+ <span class="Constant"> .local-scope ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
+ <span class="Constant"> .a:number <- next-ingredient ┊ x.</span>
+ <span class="Constant"> .b:number <- next-ingredient ┊foo 4, 0 .</span>
+ <span class="Constant"> .stash [dividing by], b ┊dividing by 0 .</span>
+ <span class="Constant"> ._, c:number <- divide-with-remainder a, b ┊foo: divide by zero in '_, c:number <- divide-wi↩.</span>
+ <span class="Constant"> .reply b ┊th-remainder a, b' .</span>
+ ]
+]
</pre>
</body>
</html>
diff --git a/html/edit/011-editor-undo.mu.html b/html/edit/011-editor-undo.mu.html
index 37417b7f..b50f0063 100644
--- a/html/edit/011-editor-undo.mu.html
+++ b/html/edit/011-editor-undo.mu.html
@@ -13,15 +13,15 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
.muRecipe { color: #ff8700; }
-.muData { color: #ffff00; }
.Special { color: #ff6060; }
-.muScenario { color: #00af00; }
+.muData { color: #ffff00; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.SalientComment { color: #00ffff; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
+.muScenario { color: #00af00; }
-->
</style>
@@ -100,11 +100,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">{</span>
undo?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">26/ctrl-z</span>
<span class="muControl">break-unless</span> undo?
- undo:address:address:list<span class="Special"> <- </span>get-address *editor, <span class="Constant">undo:offset</span>
+ undo:address:address:list:address:operation<span class="Special"> <- </span>get-address *editor, <span class="Constant">undo:offset</span>
<span class="muControl">break-unless</span> *undo
op:address:operation<span class="Special"> <- </span>first *undo
*undo<span class="Special"> <- </span>rest *undo
- redo:address:address:list<span class="Special"> <- </span>get-address *editor, <span class="Constant">redo:offset</span>
+ redo:address:address:list:address:operation<span class="Special"> <- </span>get-address *editor, <span class="Constant">redo:offset</span>
*redo<span class="Special"> <- </span>push op, *redo
<span class="Constant"> <handle-undo></span>
<span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span>
@@ -116,11 +116,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">{</span>
redo?:boolean<span class="Special"> <- </span>equal *c, <span class="Constant">25/ctrl-y</span>
<span class="muControl">break-unless</span> redo?
- redo:address:address:list<span class="Special"> <- </span>get-address *editor, <span class="Constant">redo:offset</span>
+ redo:address:address:list:address:operation<span class="Special"> <- </span>get-address *editor, <span class="Constant">redo:offset</span>
<span class="muControl">break-unless</span> *redo
op:address:operation<span class="Special"> <- </span>first *redo
*redo<span class="Special"> <- </span>rest *redo
- undo:address:address:list<span class="Special"> <- </span>get-address *editor, <span class="Constant">undo:offset</span>
+ undo:address:address:list:address:operation<span class="Special"> <- </span>get-address *editor, <span class="Constant">undo:offset</span>
*undo<span class="Special"> <- </span>push op, *undo
<span class="Constant"> <handle-redo></span>
<span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>, <span class="Constant">1/go-render</span>
@@ -133,18 +133,18 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># create an editor and type a character</span>
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
assume-console [
type <span class="Constant">[0]</span>
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># undo</span>
assume-console [
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># character should be gone</span>
screen-should-contain [
@@ -158,7 +158,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[1]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -170,12 +170,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># save operation to undo</span>
<span class="muRecipe">after</span> <span class="Constant"><insert-character-begin></span> [
- top-before:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
- cursor-before:address:duplex-list<span class="Special"> <- </span>copy *before-cursor
+ top-before:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ cursor-before:address:duplex-list:character<span class="Special"> <- </span>copy *before-cursor
]
<span class="muRecipe">before</span> <span class="Constant"><insert-character-end></span> [
- top-after:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
- undo:address:address:list<span class="Special"> <- </span>get-address *editor, <span class="Constant">undo:offset</span>
+ top-after:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ undo:address:address:list:address:operation<span class="Special"> <- </span>get-address *editor, <span class="Constant">undo:offset</span>
<span class="Delimiter">{</span>
<span class="Comment"># if previous operation was an insert, coalesce this operation with it</span>
<span class="muControl">break-unless</span> *undo
@@ -184,19 +184,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muControl">break-unless</span> typing
previous-coalesce-tag:number<span class="Special"> <- </span>get *typing, <span class="Constant">tag:offset</span>
<span class="muControl">break-unless</span> previous-coalesce-tag
- insert-until:address:address:duplex-list<span class="Special"> <- </span>get-address *typing, <span class="Constant">insert-until:offset</span>
+ insert-until:address:address:duplex-list:character<span class="Special"> <- </span>get-address *typing, <span class="Constant">insert-until:offset</span>
*insert-until<span class="Special"> <- </span>next-duplex *before-cursor
after-row:address:number<span class="Special"> <- </span>get-address *typing, <span class="Constant">after-row:offset</span>
*after-row<span class="Special"> <- </span>copy *cursor-row
after-column:address:number<span class="Special"> <- </span>get-address *typing, <span class="Constant">after-column:offset</span>
*after-column<span class="Special"> <- </span>copy *cursor-column
- after-top:address:number<span class="Special"> <- </span>get-address *typing, <span class="Constant">after-top-of-screen:offset</span>
+ after-top:address:address:duplex-list:character<span class="Special"> <- </span>get-address *typing, <span class="Constant">after-top-of-screen:offset</span>
*after-top<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
<span class="muControl">break</span> <span class="Constant">+done-adding-insert-operation:label</span>
<span class="Delimiter">}</span>
<span class="Comment"># if not, create a new operation</span>
- insert-from:address:duplex-list<span class="Special"> <- </span>next-duplex cursor-before
- insert-to:address:duplex-list<span class="Special"> <- </span>next-duplex insert-from
+ insert-from:address:duplex-list:character<span class="Special"> <- </span>next-duplex cursor-before
+ insert-to:address:duplex-list:character<span class="Special"> <- </span>next-duplex insert-from
op:address:operation<span class="Special"> <- </span>new <span class="Constant">operation:type</span>
*op<span class="Special"> <- </span>merge <span class="Constant">0/insert-operation</span>, save-row/<span class="muRecipe">before</span>, save-column/<span class="muRecipe">before</span>, top-before, *cursor-row/<span class="muRecipe">after</span>, *cursor-column/<span class="muRecipe">after</span>, top-after, insert-from, insert-to, <span class="Constant">1/coalesce</span>
editor<span class="Special"> <- </span>add-operation editor, op
@@ -207,14 +207,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muRecipe">after</span> <span class="Constant"><insert-enter-begin></span> [
cursor-row-before:number<span class="Special"> <- </span>copy *cursor-row
cursor-column-before:number<span class="Special"> <- </span>copy *cursor-column
- top-before:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
- cursor-before:address:duplex-list<span class="Special"> <- </span>copy *before-cursor
+ top-before:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ cursor-before:address:duplex-list:character<span class="Special"> <- </span>copy *before-cursor
]
<span class="muRecipe">before</span> <span class="Constant"><insert-enter-end></span> [
- top-after:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ top-after:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
<span class="Comment"># never coalesce</span>
- insert-from:address:duplex-list<span class="Special"> <- </span>next-duplex cursor-before
- insert-to:address:duplex-list<span class="Special"> <- </span>next-duplex *before-cursor
+ insert-from:address:duplex-list:character<span class="Special"> <- </span>next-duplex cursor-before
+ insert-to:address:duplex-list:character<span class="Special"> <- </span>next-duplex *before-cursor
op:address:operation<span class="Special"> <- </span>new <span class="Constant">operation:type</span>
*op<span class="Special"> <- </span>merge <span class="Constant">0/insert-operation</span>, cursor-row-before, cursor-column-before, top-before, *cursor-row/<span class="muRecipe">after</span>, *cursor-column/<span class="muRecipe">after</span>, top-after, insert-from, insert-to, <span class="Constant">0/never-coalesce</span>
editor<span class="Special"> <- </span>add-operation editor, op
@@ -224,10 +224,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># redo stack, because it's now obsolete.</span>
<span class="Comment"># Beware: since we're counting cursor moves as operations, this means just</span>
<span class="Comment"># moving the cursor can lose work on the undo stack.</span>
-<span class="muRecipe">recipe</span> add-operation [
+<span class="muRecipe">recipe</span> add-operation editor:address:editor-data, op:address:operation<span class="muRecipe"> -> </span>editor:address:editor-data [
<span class="Constant">local-scope</span>
- editor:address:editor-data<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
- op:address:operation<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
+ <span class="Constant">load-ingredients</span>
undo:address:address:list:address:operation<span class="Special"> <- </span>get-address *editor, <span class="Constant">undo:offset</span>
*undo<span class="Special"> <- </span>push op *undo
redo:address:address:list:address:operation<span class="Special"> <- </span>get-address *editor, <span class="Constant">redo:offset</span>
@@ -239,14 +238,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">{</span>
typing:address:insert-operation<span class="Special"> <- </span>maybe-convert *op, <span class="Constant">typing:variant</span>
<span class="muControl">break-unless</span> typing
- start:address:duplex-list<span class="Special"> <- </span>get *typing, <span class="Constant">insert-from:offset</span>
- end:address:duplex-list<span class="Special"> <- </span>get *typing, <span class="Constant">insert-until:offset</span>
+ start:address:duplex-list:character<span class="Special"> <- </span>get *typing, <span class="Constant">insert-from:offset</span>
+ end:address:duplex-list:character<span class="Special"> <- </span>get *typing, <span class="Constant">insert-until:offset</span>
<span class="Comment"># assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen</span>
*before-cursor<span class="Special"> <- </span>prev-duplex start
remove-duplex-between *before-cursor, end
*cursor-row<span class="Special"> <- </span>get *typing, <span class="Constant">before-row:offset</span>
*cursor-column<span class="Special"> <- </span>get *typing, <span class="Constant">before-column:offset</span>
- top:address:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ top:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
*top<span class="Special"> <- </span>get *typing, <span class="Constant">before-top-of-screen:offset</span>
<span class="Delimiter">}</span>
]
@@ -255,18 +254,18 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># create an editor and type multiple characters</span>
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
assume-console [
type <span class="Constant">[012]</span>
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># undo</span>
assume-console [
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># all characters must be gone</span>
screen-should-contain [
@@ -281,13 +280,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># create an editor with some text</span>
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># type some characters</span>
assume-console [
type <span class="Constant">[012]</span>
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> .012a .</span>
@@ -299,7 +298,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># back to original text</span>
screen-should-contain [
@@ -313,7 +312,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[3]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -327,14 +326,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># create an editor with some text</span>
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[ abc]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># new line</span>
assume-console [
left-click <span class="Constant">1</span>, <span class="Constant">8</span>
press enter
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> . abc .</span>
@@ -354,7 +353,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
@@ -374,7 +373,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[1]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -390,13 +389,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># create an editor, type something, undo</span>
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
assume-console [
type <span class="Constant">[012]</span>
press ctrl-z
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> .a .</span>
@@ -408,7 +407,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-y
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># all characters must be back</span>
screen-should-contain [
@@ -422,7 +421,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[3]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -436,13 +435,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">{</span>
typing:address:insert-operation<span class="Special"> <- </span>maybe-convert *op, <span class="Constant">typing:variant</span>
<span class="muControl">break-unless</span> typing
- insert-from:address:duplex-list<span class="Special"> <- </span>get *typing, <span class="Constant">insert-from:offset</span> <span class="Comment"># ignore insert-to because it's already been spliced away</span>
+ insert-from:address:duplex-list:character<span class="Special"> <- </span>get *typing, <span class="Constant">insert-from:offset</span> <span class="Comment"># ignore insert-to because it's already been spliced away</span>
<span class="Comment"># assert insert-to matches next-duplex(*before-cursor)</span>
insert-duplex-range *before-cursor, insert-from
<span class="Comment"># assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen</span>
*cursor-row<span class="Special"> <- </span>get *typing, <span class="Constant">after-row:offset</span>
*cursor-column<span class="Special"> <- </span>get *typing, <span class="Constant">after-column:offset</span>
- top:address:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ top:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
*top<span class="Special"> <- </span>get *typing, <span class="Constant">after-top-of-screen:offset</span>
<span class="Delimiter">}</span>
]
@@ -451,13 +450,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># create an editor, type something, undo</span>
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
assume-console [
type <span class="Constant">[012]</span>
press ctrl-z
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> . .</span>
@@ -469,7 +468,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-y
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># all characters must be back</span>
screen-should-contain [
@@ -483,7 +482,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[3]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -499,18 +498,18 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def</span>
<span class="Constant">ghi]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
assume-console [
type <span class="Constant">[1]</span>
press ctrl-z
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># do some more work</span>
assume-console [
type <span class="Constant">[0]</span>
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> .0abc .</span>
@@ -523,7 +522,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-y
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># nothing should happen</span>
screen-should-contain [
@@ -539,7 +538,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># create an editor</span>
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># insert some text and tabs, hit enter, some more text and tabs</span>
assume-console [
@@ -551,7 +550,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press tab
type <span class="Constant">[efg]</span>
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> . ab cd .</span>
@@ -570,7 +569,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># typing in second line deleted, but not indent</span>
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
@@ -591,7 +590,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># indent and newline deleted</span>
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
@@ -611,7 +610,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># empty screen</span>
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
@@ -631,7 +630,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-y
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># first line inserted</span>
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
@@ -651,7 +650,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-y
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># newline and indent inserted</span>
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
@@ -672,7 +671,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-y
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># indent and newline deleted</span>
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
@@ -698,19 +697,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def</span>
<span class="Constant">ghi]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># move the cursor</span>
assume-console [
left-click <span class="Constant">3</span>, <span class="Constant">1</span>
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># undo</span>
assume-console [
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -724,7 +723,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[1]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -738,17 +737,17 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="muRecipe">after</span> <span class="Constant"><move-cursor-begin></span> [
before-cursor-row:number<span class="Special"> <- </span>get *editor, <span class="Constant">cursor-row:offset</span>
before-cursor-column:number<span class="Special"> <- </span>get *editor, <span class="Constant">cursor-column:offset</span>
- before-top-of-screen:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ before-top-of-screen:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
]
<span class="muRecipe">before</span> <span class="Constant"><move-cursor-end></span> [
after-cursor-row:number<span class="Special"> <- </span>get *editor, <span class="Constant">cursor-row:offset</span>
after-cursor-column:number<span class="Special"> <- </span>get *editor, <span class="Constant">cursor-column:offset</span>
- after-top-of-screen:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ after-top-of-screen:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
<span class="Delimiter">{</span>
<span class="muControl">break-unless</span> undo-coalesce-tag
<span class="Comment"># if previous operation was also a move, and also had the same coalesce</span>
<span class="Comment"># tag, coalesce with it</span>
- undo:address:address:list<span class="Special"> <- </span>get-address *editor, <span class="Constant">undo:offset</span>
+ undo:address:address:list:address:operation<span class="Special"> <- </span>get-address *editor, <span class="Constant">undo:offset</span>
<span class="muControl">break-unless</span> *undo
op:address:operation<span class="Special"> <- </span>first *undo
move:address:move-operation<span class="Special"> <- </span>maybe-convert *op, <span class="Constant">move:variant</span>
@@ -760,7 +759,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
*after-row<span class="Special"> <- </span>copy after-cursor-row
after-column:address:number<span class="Special"> <- </span>get-address *move, <span class="Constant">after-column:offset</span>
*after-column<span class="Special"> <- </span>copy after-cursor-column
- after-top:address:number<span class="Special"> <- </span>get-address *move, <span class="Constant">after-top-of-screen:offset</span>
+ after-top:address:address:duplex-list:character<span class="Special"> <- </span>get-address *move, <span class="Constant">after-top-of-screen:offset</span>
*after-top<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
<span class="muControl">break</span> <span class="Constant">+done-adding-move-operation:label</span>
<span class="Delimiter">}</span>
@@ -775,7 +774,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
move:address:move-operation<span class="Special"> <- </span>maybe-convert *op, <span class="Constant">move:variant</span>
<span class="muControl">break-unless</span> move
<span class="Comment"># assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen</span>
- top:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
+ top:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
*cursor-row<span class="Special"> <- </span>get *move, <span class="Constant">before-row:offset</span>
*cursor-column<span class="Special"> <- </span>get *move, <span class="Constant">before-column:offset</span>
*top<span class="Special"> <- </span>get *move, <span class="Constant">before-top-of-screen:offset</span>
@@ -789,13 +788,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[a</span>
<span class="Constant">b</span>
<span class="Constant">cdefgh]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">5/right</span>
<span class="Comment"># position cursor at end of screen and try to move right</span>
assume-console [
left-click <span class="Constant">3</span>, <span class="Constant">3</span>
press right-arrow
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
<span class="Comment"># screen scrolls</span>
@@ -814,7 +813,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -835,7 +834,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[1]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -851,20 +850,20 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def</span>
<span class="Constant">ghi]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># move the cursor</span>
assume-console [
left-click <span class="Constant">3</span>, <span class="Constant">1</span>
press left-arrow
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># undo</span>
assume-console [
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -878,7 +877,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[1]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -895,14 +894,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def</span>
<span class="Constant">ghi]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># move the cursor</span>
assume-console [
left-click <span class="Constant">3</span>, <span class="Constant">1</span>
press up-arrow
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
memory-should-contain [
@@ -914,7 +913,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -928,7 +927,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[1]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -945,20 +944,20 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def</span>
<span class="Constant">ghi]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># move the cursor</span>
assume-console [
left-click <span class="Constant">2</span>, <span class="Constant">1</span>
press down-arrow
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># undo</span>
assume-console [
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -972,7 +971,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[1]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -992,19 +991,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">d</span>
<span class="Constant">e</span>
<span class="Constant">f]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># scroll the page</span>
assume-console [
press ctrl-f
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># undo</span>
assume-console [
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1027,19 +1026,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">d</span>
<span class="Constant">e</span>
<span class="Constant">f]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># scroll the page</span>
assume-console [
press page-down
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># undo</span>
assume-console [
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1062,20 +1061,20 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">d</span>
<span class="Constant">e</span>
<span class="Constant">f]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># scroll the page down and up</span>
assume-console [
press page-down
press ctrl-b
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># undo</span>
assume-console [
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1098,20 +1097,20 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">d</span>
<span class="Constant">e</span>
<span class="Constant">f]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># scroll the page down and up</span>
assume-console [
press page-down
press page-up
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># undo</span>
assume-console [
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1131,20 +1130,20 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def</span>
<span class="Constant">ghi]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># move the cursor, then to start of line</span>
assume-console [
left-click <span class="Constant">2</span>, <span class="Constant">1</span>
press ctrl-a
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># undo</span>
assume-console [
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1158,7 +1157,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[1]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -1175,20 +1174,20 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def</span>
<span class="Constant">ghi]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># move the cursor, then to start of line</span>
assume-console [
left-click <span class="Constant">2</span>, <span class="Constant">1</span>
press home
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># undo</span>
assume-console [
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1202,7 +1201,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[1]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -1219,20 +1218,20 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def</span>
<span class="Constant">ghi]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># move the cursor, then to start of line</span>
assume-console [
left-click <span class="Constant">2</span>, <span class="Constant">1</span>
press ctrl-e
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># undo</span>
assume-console [
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1246,7 +1245,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[1]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -1263,20 +1262,20 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def</span>
<span class="Constant">ghi]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># move the cursor, then to start of line</span>
assume-console [
left-click <span class="Constant">2</span>, <span class="Constant">1</span>
press end
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># undo</span>
assume-console [
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1290,7 +1289,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[1]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -1305,14 +1304,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># create an editor, type some text, move the cursor, type some more text</span>
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
assume-console [
type <span class="Constant">[abc]</span>
left-click <span class="Constant">1</span>, <span class="Constant">1</span>
type <span class="Constant">[d]</span>
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
screen-should-contain [
@@ -1330,7 +1329,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1350,7 +1349,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1370,7 +1369,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1390,7 +1389,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-y
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1410,7 +1409,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-y
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1430,7 +1429,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-y
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1453,7 +1452,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def</span>
<span class="Constant">ghi]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># move the cursor</span>
assume-console [
@@ -1462,7 +1461,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press right-arrow
press up-arrow
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
memory-should-contain [
@@ -1474,7 +1473,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1488,7 +1487,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1507,19 +1506,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def</span>
<span class="Constant">ghi]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
assume-console [
left-click <span class="Constant">3</span>, <span class="Constant">1</span>
press ctrl-z
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># redo</span>
assume-console [
press ctrl-y
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
]
@@ -1533,7 +1532,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[1]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -1551,7 +1550,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen</span>
*cursor-row<span class="Special"> <- </span>get *move, <span class="Constant">after-row:offset</span>
*cursor-column<span class="Special"> <- </span>get *move, <span class="Constant">after-column:offset</span>
- top:address:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ top:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
*top<span class="Special"> <- </span>get *move, <span class="Constant">after-top-of-screen:offset</span>
<span class="Delimiter">}</span>
]
@@ -1562,7 +1561,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># create an editor</span>
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># insert some text and hit backspace</span>
assume-console [
@@ -1570,7 +1569,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press backspace
press backspace
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> .a .</span>
@@ -1588,7 +1587,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
@@ -1607,7 +1606,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-y
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
@@ -1625,13 +1624,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># save operation to undo</span>
<span class="muRecipe">after</span> <span class="Constant"><backspace-character-begin></span> [
- top-before:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ top-before:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
]
<span class="muRecipe">before</span> <span class="Constant"><backspace-character-end></span> [
<span class="Delimiter">{</span>
<span class="muControl">break-unless</span> backspaced-cell <span class="Comment"># backspace failed; don't add an undo operation</span>
- top-after:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
- undo:address:address:list<span class="Special"> <- </span>get-address *editor, <span class="Constant">undo:offset</span>
+ top-after:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ undo:address:address:list:address:operation<span class="Special"> <- </span>get-address *editor, <span class="Constant">undo:offset</span>
<span class="Delimiter">{</span>
<span class="Comment"># if previous operation was an insert, coalesce this operation with it</span>
<span class="muControl">break-unless</span> *undo
@@ -1641,22 +1640,22 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
previous-coalesce-tag:number<span class="Special"> <- </span>get *deletion, <span class="Constant">tag:offset</span>
coalesce?:boolean<span class="Special"> <- </span>equal previous-coalesce-tag, <span class="Constant">1/coalesce-backspace</span>
<span class="muControl">break-unless</span> coalesce?
- delete-from:address:address:duplex-list<span class="Special"> <- </span>get-address *deletion, <span class="Constant">delete-from:offset</span>
+ delete-from:address:address:duplex-list:character<span class="Special"> <- </span>get-address *deletion, <span class="Constant">delete-from:offset</span>
*delete-from<span class="Special"> <- </span>copy *before-cursor
- backspaced-so-far:address:address:duplex-list<span class="Special"> <- </span>get-address *deletion, <span class="Constant">deleted-text:offset</span>
+ backspaced-so-far:address:address:duplex-list:character<span class="Special"> <- </span>get-address *deletion, <span class="Constant">deleted-text:offset</span>
insert-duplex-range backspaced-cell, *backspaced-so-far
*backspaced-so-far<span class="Special"> <- </span>copy backspaced-cell
after-row:address:number<span class="Special"> <- </span>get-address *deletion, <span class="Constant">after-row:offset</span>
*after-row<span class="Special"> <- </span>copy *cursor-row
after-column:address:number<span class="Special"> <- </span>get-address *deletion, <span class="Constant">after-column:offset</span>
*after-column<span class="Special"> <- </span>copy *cursor-column
- after-top:address:number<span class="Special"> <- </span>get-address *deletion, <span class="Constant">after-top-of-screen:offset</span>
+ after-top:address:address:duplex-list:character<span class="Special"> <- </span>get-address *deletion, <span class="Constant">after-top-of-screen:offset</span>
*after-top<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
<span class="muControl">break</span> <span class="Constant">+done-adding-backspace-operation:label</span>
<span class="Delimiter">}</span>
<span class="Comment"># if not, create a new operation</span>
op:address:operation<span class="Special"> <- </span>new <span class="Constant">operation:type</span>
- deleted-until:address:duplex-list<span class="Special"> <- </span>next-duplex *before-cursor
+ deleted-until:address:duplex-list:character<span class="Special"> <- </span>next-duplex *before-cursor
*op<span class="Special"> <- </span>merge <span class="Constant">2/delete-operation</span>, save-row/<span class="muRecipe">before</span>, save-column/<span class="muRecipe">before</span>, top-before, *cursor-row/<span class="muRecipe">after</span>, *cursor-column/<span class="muRecipe">after</span>, top-after, backspaced-cell/deleted, *before-cursor/delete-from, deleted-until, <span class="Constant">1/coalesce-backspace</span>
editor<span class="Special"> <- </span>add-operation editor, op
<span class="Constant"> +done-adding-backspace-operation</span>
@@ -1667,17 +1666,17 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">{</span>
deletion:address:delete-operation<span class="Special"> <- </span>maybe-convert *op, <span class="Constant">delete:variant</span>
<span class="muControl">break-unless</span> deletion
- start2:address:address:duplex-list<span class="Special"> <- </span>get-address *editor, <span class="Constant">data:offset</span>
- anchor:address:duplex-list<span class="Special"> <- </span>get *deletion, <span class="Constant">delete-from:offset</span>
+ start2:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">data:offset</span>
+ anchor:address:duplex-list:character<span class="Special"> <- </span>get *deletion, <span class="Constant">delete-from:offset</span>
<span class="muControl">break-unless</span> anchor
- deleted:address:duplex-list<span class="Special"> <- </span>get *deletion, <span class="Constant">deleted-text:offset</span>
- old-cursor:address:duplex-list<span class="Special"> <- </span>last-duplex deleted
+ deleted:address:duplex-list:character<span class="Special"> <- </span>get *deletion, <span class="Constant">deleted-text:offset</span>
+ old-cursor:address:duplex-list:character<span class="Special"> <- </span>last-duplex deleted
insert-duplex-range anchor, deleted
<span class="Comment"># assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen</span>
*before-cursor<span class="Special"> <- </span>copy old-cursor
*cursor-row<span class="Special"> <- </span>get *deletion, <span class="Constant">before-row:offset</span>
*cursor-column<span class="Special"> <- </span>get *deletion, <span class="Constant">before-column:offset</span>
- top:address:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ top:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
*top<span class="Special"> <- </span>get *deletion, <span class="Constant">before-top-of-screen:offset</span>
<span class="Delimiter">}</span>
]
@@ -1686,13 +1685,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Delimiter">{</span>
deletion:address:delete-operation<span class="Special"> <- </span>maybe-convert *op, <span class="Constant">delete:variant</span>
<span class="muControl">break-unless</span> deletion
- start:address:duplex-list<span class="Special"> <- </span>get *deletion, <span class="Constant">delete-from:offset</span>
- end:address:duplex-list<span class="Special"> <- </span>get *deletion, <span class="Constant">delete-until:offset</span>
+ start:address:duplex-list:character<span class="Special"> <- </span>get *deletion, <span class="Constant">delete-from:offset</span>
+ end:address:duplex-list:character<span class="Special"> <- </span>get *deletion, <span class="Constant">delete-until:offset</span>
remove-duplex-between start, end
<span class="Comment"># assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen</span>
*cursor-row<span class="Special"> <- </span>get *deletion, <span class="Constant">after-row:offset</span>
*cursor-column<span class="Special"> <- </span>get *deletion, <span class="Constant">after-column:offset</span>
- top:address:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ top:address:address:duplex-list:character<span class="Special"> <- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
*top<span class="Special"> <- </span>get *deletion, <span class="Constant">after-top-of-screen:offset</span>
<span class="Delimiter">}</span>
]
@@ -1703,7 +1702,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Comment"># create an editor</span>
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># insert some text and hit delete and backspace a few times</span>
assume-console [
@@ -1714,7 +1713,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press delete
press delete
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> .af .</span>
@@ -1732,7 +1731,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
@@ -1751,7 +1750,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
@@ -1770,7 +1769,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
<span class="Constant">4</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-column:offset</span>
@@ -1789,7 +1788,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-y
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># first line inserted</span>
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
@@ -1809,7 +1808,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-y
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># first line inserted</span>
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
@@ -1829,7 +1828,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-y
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># first line inserted</span>
<span class="Constant">3</span>:number<span class="Special"> <- </span>get *<span class="Constant">2</span>:address:editor-data, <span class="Constant">cursor-row:offset</span>
@@ -1847,13 +1846,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
<span class="muRecipe">after</span> <span class="Constant"><delete-character-begin></span> [
- top-before:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ top-before:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
]
<span class="muRecipe">before</span> <span class="Constant"><delete-character-end></span> [
<span class="Delimiter">{</span>
<span class="muControl">break-unless</span> deleted-cell <span class="Comment"># delete failed; don't add an undo operation</span>
- top-after:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
- undo:address:address:list<span class="Special"> <- </span>get-address *editor, <span class="Constant">undo:offset</span>
+ top-after:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ undo:address:address:list:address:operation<span class="Special"> <- </span>get-address *editor, <span class="Constant">undo:offset</span>
<span class="Delimiter">{</span>
<span class="Comment"># if previous operation was an insert, coalesce this operation with it</span>
<span class="muControl">break-unless</span> *undo
@@ -1863,21 +1862,21 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
previous-coalesce-tag:number<span class="Special"> <- </span>get *deletion, <span class="Constant">tag:offset</span>
coalesce?:boolean<span class="Special"> <- </span>equal previous-coalesce-tag, <span class="Constant">2/coalesce-delete</span>
<span class="muControl">break-unless</span> coalesce?
- delete-until:address:address:duplex-list<span class="Special"> <- </span>get-address *deletion, <span class="Constant">delete-until:offset</span>
+ delete-until:address:address:duplex-list:character<span class="Special"> <- </span>get-address *deletion, <span class="Constant">delete-until:offset</span>
*delete-until<span class="Special"> <- </span>next-duplex *before-cursor
- deleted-so-far:address:address:duplex-list<span class="Special"> <- </span>get-address *deletion, <span class="Constant">deleted-text:offset</span>
+ deleted-so-far:address:address:duplex-list:character<span class="Special"> <- </span>get-address *deletion, <span class="Constant">deleted-text:offset</span>
*deleted-so-far<span class="Special"> <- </span>append-duplex *deleted-so-far, deleted-cell
after-row:address:number<span class="Special"> <- </span>get-address *deletion, <span class="Constant">after-row:offset</span>
*after-row<span class="Special"> <- </span>copy *cursor-row
after-column:address:number<span class="Special"> <- </span>get-address *deletion, <span class="Constant">after-column:offset</span>
*after-column<span class="Special"> <- </span>copy *cursor-column
- after-top:address:number<span class="Special"> <- </span>get-address *deletion, <span class="Constant">after-top-of-screen:offset</span>
+ after-top:address:address:duplex-list:character<span class="Special"> <- </span>get-address *deletion, <span class="Constant">after-top-of-screen:offset</span>
*after-top<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
<span class="muControl">break</span> <span class="Constant">+done-adding-delete-operation:label</span>
<span class="Delimiter">}</span>
<span class="Comment"># if not, create a new operation</span>
op:address:operation<span class="Special"> <- </span>new <span class="Constant">operation:type</span>
- deleted-until:address:duplex-list<span class="Special"> <- </span>next-duplex *before-cursor
+ deleted-until:address:duplex-list:character<span class="Special"> <- </span>next-duplex *before-cursor
*op<span class="Special"> <- </span>merge <span class="Constant">2/delete-operation</span>, save-row/<span class="muRecipe">before</span>, save-column/<span class="muRecipe">before</span>, top-before, *cursor-row/<span class="muRecipe">after</span>, *cursor-column/<span class="muRecipe">after</span>, top-after, deleted-cell/deleted, *before-cursor/delete-from, deleted-until, <span class="Constant">2/coalesce-delete</span>
editor<span class="Special"> <- </span>add-operation editor, op
<span class="Constant"> +done-adding-delete-operation</span>
@@ -1891,14 +1890,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># insert some text and hit delete and backspace a few times</span>
assume-console [
left-click <span class="Constant">1</span>, <span class="Constant">1</span>
press ctrl-k
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> .a .</span>
@@ -1917,7 +1916,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -1937,7 +1936,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-y
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># first line inserted</span>
screen-should-contain [
@@ -1958,7 +1957,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[1]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -1970,15 +1969,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
<span class="muRecipe">after</span> <span class="Constant"><delete-to-end-of-line-begin></span> [
- top-before:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ top-before:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
]
<span class="muRecipe">before</span> <span class="Constant"><delete-to-end-of-line-end></span> [
<span class="Delimiter">{</span>
<span class="muControl">break-unless</span> deleted-cells <span class="Comment"># delete failed; don't add an undo operation</span>
- top-after:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
- undo:address:address:list<span class="Special"> <- </span>get-address *editor, <span class="Constant">undo:offset</span>
+ top-after:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ undo:address:address:list:address:operation<span class="Special"> <- </span>get-address *editor, <span class="Constant">undo:offset</span>
op:address:operation<span class="Special"> <- </span>new <span class="Constant">operation:type</span>
- deleted-until:address:duplex-list<span class="Special"> <- </span>next-duplex *before-cursor
+ deleted-until:address:duplex-list:character<span class="Special"> <- </span>next-duplex *before-cursor
*op<span class="Special"> <- </span>merge <span class="Constant">2/delete-operation</span>, save-row/<span class="muRecipe">before</span>, save-column/<span class="muRecipe">before</span>, top-before, *cursor-row/<span class="muRecipe">after</span>, *cursor-column/<span class="muRecipe">after</span>, top-after, deleted-cells/deleted, *before-cursor/delete-from, deleted-until, <span class="Constant">0/never-coalesce</span>
editor<span class="Special"> <- </span>add-operation editor, op
<span class="Constant"> +done-adding-delete-operation</span>
@@ -1992,14 +1991,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
<span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[abc</span>
<span class="Constant">def]</span>
- <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
editor-render screen, <span class="Constant">2</span>:address:editor-data
<span class="Comment"># insert some text and hit delete and backspace a few times</span>
assume-console [
left-click <span class="Constant">1</span>, <span class="Constant">2</span>
press ctrl-u
]
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
screen-should-contain [
<span class="Constant"> . .</span>
<span class="Constant"> .c .</span>
@@ -2018,7 +2017,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-z
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -2038,7 +2037,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
press ctrl-y
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
<span class="Comment"># first line inserted</span>
screen-should-contain [
@@ -2059,7 +2058,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
type <span class="Constant">[1]</span>
]
run [
- editor-event-loop screen:address, console:address, <span class="Constant">2</span>:address:editor-data
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
]
screen-should-contain [
<span class="Constant"> . .</span>
@@ -2071,21 +2070,42 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
]
<span class="muRecipe">after</span> <span class="Constant"><delete-to-start-of-line-begin></span> [
- top-before:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ top-before:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
]
<span class="muRecipe">before</span> <span class="Constant"><delete-to-start-of-line-end></span> [
<span class="Delimiter">{</span>
<span class="muControl">break-unless</span> deleted-cells <span class="Comment"># delete failed; don't add an undo operation</span>
- top-after:address:duplex-list<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
- undo:address:address:list<span class="Special"> <- </span>get-address *editor, <span class="Constant">undo:offset</span>
+ top-after:address:duplex-list:character<span class="Special"> <- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
+ undo:address:address:list:address:operation<span class="Special"> <- </span>get-address *editor, <span class="Constant">undo:offset</span>
op:address:operation<span class="Special"> <- </span>new <span class="Constant">operation:type</span>
- deleted-until:address:duplex-list<span class="Special"> <- </span>next-duplex *before-cursor
+ deleted-until:address:duplex-list:character<span class="Special"> <- </span>next-duplex *before-cursor
*op<span class="Special"> <- </span>merge <span class="Constant">2/delete-operation</span>, save-row/<span class="muRecipe">before</span>, save-column/<span class="muRecipe">before</span>, top-before, *cursor-row/<span class="muRecipe">after</span>, *cursor-column/<span class="muRecipe">after</span>, top-after, deleted-cells/deleted, *before-cursor/delete-from, deleted-until, <span class="Constant">0/never-coalesce</span>
editor<span class="Special"> <- </span>add-operation editor, op
<span class="Constant"> +done-adding-delete-operation</span>
<span class="Delimiter">}</span>
]
+<span class="muScenario">scenario</span> editor-can-undo-and-redo-ctrl-u-2 [
+ <span class="Comment"># create an editor</span>
+ assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
+ <span class="Constant">1</span>:address:array:character<span class="Special"> <- </span>new <span class="Constant">[]</span>
+ <span class="Constant">2</span>:address:editor-data<span class="Special"> <- </span>new-editor <span class="Constant">1</span>:address:array:character, screen:address:screen, <span class="Constant">0/left</span>, <span class="Constant">10/right</span>
+ editor-render screen, <span class="Constant">2</span>:address:editor-data
+ <span class="Comment"># insert some text and hit delete and backspace a few times</span>
+ assume-console [
+ type <span class="Constant">[abc]</span>
+ press ctrl-u
+ press ctrl-z
+ ]
+ editor-event-loop screen:address:screen, console:address:console, <span class="Constant">2</span>:address:editor-data
+ screen-should-contain [
+ <span class="Constant"> . .</span>
+ <span class="Constant"> .abc .</span>
+<span class="Constant"> .┈┈┈┈┈┈┈┈┈┈.</span>
+ <span class="Constant"> . .</span>
+ ]
+]
+
<span class="Comment"># todo:</span>
<span class="Comment"># operations for recipe side and each sandbox-data</span>
<span class="Comment"># undo delete sandbox as a separate primitive on the status bar</span>
diff --git a/html/factorial.mu.html b/html/factorial.mu.html
index d3837c22..31ac9c26 100644
--- a/html/factorial.mu.html
+++ b/html/factorial.mu.html
@@ -13,13 +13,13 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
.muRecipe { color: #ff8700; }
.muScenario { color: #00af00; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.Special { color: #ff6060; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
-->
</style>
diff --git a/html/fork.mu.html b/html/fork.mu.html
index 09d02860..69dc4e30 100644
--- a/html/fork.mu.html
+++ b/html/fork.mu.html
@@ -13,11 +13,11 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
.muRecipe { color: #ff8700; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
-->
</style>
diff --git a/html/static_dispatch.mu.html b/html/static_dispatch.mu.html
new file mode 100644
index 00000000..c3ed60ef
--- /dev/null
+++ b/html/static_dispatch.mu.html
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>Mu - static_dispatch.mu</title>
+<meta name="Generator" content="Vim/7.4">
+<meta name="plugin-version" content="vim7.4_v1">
+<meta name="syntax" content="none">
+<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
+<meta name="colorscheme" content="minimal">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
+body { font-family: monospace; color: #eeeeee; background-color: #080808; }
+* { font-size: 1.05em; }
+.muRecipe { color: #ff8700; }
+.Comment { color: #9090ff; }
+.Constant { color: #00a0a0; }
+.Special { color: #ff6060; }
+-->
+</style>
+
+<script type='text/javascript'>
+<!--
+
+-->
+</script>
+</head>
+<body>
+<pre id='vimCodeElement'>
+<span class="muRecipe">recipe</span> test a:number<span class="muRecipe"> -> </span>b:number [
+ <span class="Constant">local-scope</span>
+ <span class="Constant">load-ingredients</span>
+ b<span class="Special"> <- </span>add a, <span class="Constant">1</span>
+]
+
+<span class="muRecipe">recipe</span> test a:number, b:number<span class="muRecipe"> -> </span>c:number [
+ <span class="Constant">local-scope</span>
+ <span class="Constant">load-ingredients</span>
+ c<span class="Special"> <- </span>add a, b
+]
+
+<span class="muRecipe">recipe</span> main [
+ <span class="Constant">local-scope</span>
+ a:number<span class="Special"> <- </span>test <span class="Constant">3</span> <span class="Comment"># selects single-ingredient version</span>
+ $print a, <span class="Constant">10/newline</span>
+ b:number<span class="Special"> <- </span>test <span class="Constant">3</span>, <span class="Constant">4</span> <span class="Comment"># selects double-ingredient version</span>
+ $print b, <span class="Constant">10/newline</span>
+ c:number<span class="Special"> <- </span>test <span class="Constant">3</span>, <span class="Constant">4</span>, <span class="Constant">5</span> <span class="Comment"># prefers double- to single-ingredient version</span>
+ $print c, <span class="Constant">10/newline</span>
+]
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/html/tangle.mu.html b/html/tangle.mu.html
index e3dba023..118b2386 100644
--- a/html/tangle.mu.html
+++ b/html/tangle.mu.html
@@ -13,12 +13,12 @@
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 1.05em; }
+.muControl { color: #c0a020; }
.muRecipe { color: #ff8700; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.Special { color: #ff6060; }
.Delimiter { color: #a04060; }
-.muControl { color: #c0a020; }
-->
</style>
@@ -42,19 +42,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
<span class="Constant">local-scope</span>
n:number<span class="Special"> <- </span><span class="Constant">next-ingredient</span>
<span class="Delimiter">{</span>
-<span class="Constant"> +base-case</span>
+<span class="Constant"> <base-case></span>
<span class="Delimiter">}</span>
-<span class="Constant"> +recursive-case</span>
+<span class="Constant"> <recursive-case></span>
]
-<span class="muRecipe">after</span> +base-case [
+<span class="muRecipe">after</span> <span class="Constant"><base-case></span> [
<span class="Comment"># if n=0 return 1</span>
zero?:boolean<span class="Special"> <- </span>equal n, <span class="Constant">0</span>
<span class="muControl">break-unless</span> zero?
<span class="muControl">reply</span> <span class="Constant">1</span>
]
-<span class="muRecipe">after</span> +recursive-case [
+<span class="muRecipe">after</span> <span class="Constant"><recursive-case></span> [
<span class="Comment"># return n * factorial(n - 1)</span>
x:number<span class="Special"> <- </span>subtract n, <span class="Constant">1</span>
subresult:number<span class="Special"> <- </span>factorial x
|