diff options
Diffstat (limited to 'html')
47 files changed, 1549 insertions, 702 deletions
diff --git a/html/000organization.cc.html b/html/000organization.cc.html index d34e80f2..35282386 100644 --- a/html/000organization.cc.html +++ b/html/000organization.cc.html @@ -126,10 +126,20 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="Comment">// Types</span> <span class="Comment">// End Types</span> -<span class="Comment">// prototypes are auto-generated in the makefile; define your functions in any order</span> +<span class="Comment">// Prototypes are auto-generated in the makefile; define your functions in any</span> +<span class="Comment">// order. Just be sure to declare each function header all on one line. Our</span> +<span class="Comment">// auto-generation scripts are too minimal and simple-minded to handle</span> +<span class="Comment">// anything else.</span> <span class="PreProc">#include </span><span class="Constant">"function_list"</span> <span class="Comment">// by convention, files ending with '_list' are auto-generated</span> <span class="Comment">// Globals</span> +<span class="Comment">//</span> +<span class="Comment">// All statements in this section should always define a single variable on a</span> +<span class="Comment">// single line. The makefile will simple-mindedly auto-generate extern</span> +<span class="Comment">// declarations for them. Don't forget to define (not just declare) constants</span> +<span class="Comment">// with extern linkage in this section, since C++ global constants have</span> +<span class="Comment">// internal linkage by default.</span> +<span class="Comment">//</span> <span class="Comment">// End Globals</span> <span class="Normal">int</span> main<span class="Delimiter">(</span><span class="Normal">int</span> argc<span class="Delimiter">,</span> <span class="Normal">char</span>* argv[]<span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -143,6 +153,9 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Comment">// End Main</span> <span class="Delimiter">}</span> +<span class="Comment">// Unit Tests</span> +<span class="Comment">// End Unit Tests</span> + <span class="Comment">//: our first directive; will move the include above the program</span> <span class="Delimiter">:(before "End Includes")</span> <span class="PreProc">#include </span><span class="Constant"><stdlib.h></span> diff --git a/html/001help.cc.html b/html/001help.cc.html index 2c8bcce4..84c836c5 100644 --- a/html/001help.cc.html +++ b/html/001help.cc.html @@ -207,7 +207,8 @@ feenableexcept<span class="Delimiter">(</span>FE_OVERFLOW | FE_UNDERFLOW<span cl <span class="CommentedCode">//? assert(sizeof(int) == 4 && sizeof(float) == 4);</span> <span class="CommentedCode">//? // | exp | mantissa</span> <span class="CommentedCode">//? int smallest_subnormal = 0b00000000000000000000000000000001;</span> -<span class="CommentedCode">//? float smallest_subnormal_f = *reinterpret_cast<int*>(&smallest_subnormal);</span> +<span class="CommentedCode">//? float smallest_subnormal_f = *reinterpret_cast<float*>(&smallest_subnormal);</span> +<span class="CommentedCode">//? cerr << "ε: " << smallest_subnormal_f << '\n';</span> <span class="CommentedCode">//? cerr << "ε/2: " << smallest_subnormal_f/2 << " (underflow)\n"; // test SIGFPE</span> <span class="Delimiter">:(before "End Includes")</span> <span class="PreProc">#include </span><span class="Constant"><fenv.h></span> @@ -215,7 +216,7 @@ feenableexcept<span class="Delimiter">(</span>FE_OVERFLOW | FE_UNDERFLOW<span cl <span class="PreProc">#ifdef __APPLE__</span> <span class="Comment">// Public domain polyfill for feenableexcept on OS X</span> <span class="Comment">// <a href="http://www-personal.umich.edu/~williams/archive/computation/fe-handling-example.c">http://www-personal.umich.edu/~williams/archive/computation/fe-handling-example.c</a></span> -<span class="Normal">inline</span> <span class="Normal">int</span> feenableexcept <span class="Delimiter">(</span><span class="Normal">unsigned</span> <span class="Normal">int</span> excepts<span class="Delimiter">)</span> <span class="Delimiter">{</span> +<span class="Normal">int</span> feenableexcept <span class="Delimiter">(</span><span class="Normal">unsigned</span> <span class="Normal">int</span> excepts<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">static</span> fenv_t fenv<span class="Delimiter">;</span> <span class="Normal">unsigned</span> <span class="Normal">int</span> new_excepts = excepts & FE_ALL_EXCEPT<span class="Delimiter">;</span> <span class="Normal">unsigned</span> <span class="Normal">int</span> old_excepts<span class="Delimiter">;</span> diff --git a/html/002test.cc.html b/html/002test.cc.html index 3afbc33d..43b362de 100644 --- a/html/002test.cc.html +++ b/html/002test.cc.html @@ -44,18 +44,20 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="Delimiter">:(before "End Types")</span> <span class="Normal">typedef</span> <span class="Normal">void</span> <span class="Delimiter">(</span>*test_fn<span class="Delimiter">)(</span><span class="Normal">void</span><span class="Delimiter">);</span> - -<span class="Delimiter">:(before "End Globals")</span> +<span class="Delimiter">:(before "Globals")</span> +<span class="Comment">// move a global ahead into types that we can't generate an extern declaration for</span> <span class="Normal">const</span> test_fn Tests[] = <span class="Delimiter">{</span> <span class="PreProc"> #include </span><span class="Constant">"test_list"</span> <span class="Comment">// auto-generated; see makefile</span> <span class="Delimiter">};</span> +<span class="Delimiter">:(before "End Globals")</span> <span class="Normal">bool</span> Run_tests = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Normal">bool</span> Passed = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Comment">// set this to false inside any test to indicate failure</span> <span class="Normal">long</span> Num_failures = <span class="Constant">0</span><span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Includes")</span> <span class="PreProc">#define CHECK(X) \</span> -<span class="PreProc"> </span><span class="Normal">if</span><span class="PreProc"> (!(X)) </span><span class="Delimiter">{</span><span class="PreProc"> \</span> +<span class="PreProc"> </span><span class="Normal">if</span><span class="PreProc"> (Passed && !(X)) </span><span class="Delimiter">{</span><span class="PreProc"> \</span> <span class="PreProc"> ++Num_failures</span><span class="Delimiter">;</span><span class="PreProc"> \</span> <span class="PreProc"> cerr << </span><span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span><span class="PreProc"> << __FUNCTION__ << </span><span class="Constant">"("</span><span class="PreProc"> << </span><span class="Constant">__FILE__</span><span class="PreProc"> << </span><span class="Constant">":"</span><span class="PreProc"> << </span><span class="Constant">__LINE__</span><span class="PreProc"> << </span><span class="Constant">"): "</span><span class="PreProc"> << #X << </span><span class="cSpecial">'\n'</span><span class="Delimiter">;</span><span class="PreProc"> \</span> <span class="PreProc"> Passed = </span><span class="Constant">false</span><span class="Delimiter">;</span><span class="PreProc"> \</span> @@ -63,7 +65,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="PreProc"> </span><span class="Delimiter">}</span> <span class="PreProc">#define CHECK_EQ(X</span><span class="Delimiter">,</span><span class="PreProc"> Y) \</span> -<span class="PreProc"> </span><span class="Normal">if</span><span class="PreProc"> ((X) != (Y)) </span><span class="Delimiter">{</span><span class="PreProc"> \</span> +<span class="PreProc"> </span><span class="Normal">if</span><span class="PreProc"> (Passed && (X) != (Y)) </span><span class="Delimiter">{</span><span class="PreProc"> \</span> <span class="PreProc"> ++Num_failures</span><span class="Delimiter">;</span><span class="PreProc"> \</span> <span class="PreProc"> cerr << </span><span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span><span class="PreProc"> << __FUNCTION__ << </span><span class="Constant">"("</span><span class="PreProc"> << </span><span class="Constant">__FILE__</span><span class="PreProc"> << </span><span class="Constant">":"</span><span class="PreProc"> << </span><span class="Constant">__LINE__</span><span class="PreProc"> << </span><span class="Constant">"): "</span><span class="PreProc"> << #X << </span><span class="Constant">" == "</span><span class="PreProc"> << #Y << </span><span class="cSpecial">'\n'</span><span class="Delimiter">;</span><span class="PreProc"> \</span> <span class="PreProc"> cerr << </span><span class="Constant">" got "</span><span class="PreProc"> << (X) << </span><span class="cSpecial">'\n'</span><span class="Delimiter">;</span><span class="PreProc"> </span><span class="Comment">/*</span><span class="Comment"> BEWARE: multiple eval </span><span class="Comment">*/</span><span class="PreProc"> \</span> diff --git a/html/003trace.cc.html b/html/003trace.cc.html index 9011e3eb..0e35ce97 100644 --- a/html/003trace.cc.html +++ b/html/003trace.cc.html @@ -110,9 +110,6 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="Comment">//: programmers form a mental model, rather than as production of a program."</span> <span class="Comment">//: -- Peter Naur (<a href="http://alistair.cockburn.us/ASD+book+extract%3A+%22Naur,+Ehn,+Musashi%22)">http://alistair.cockburn.us/ASD+book+extract%3A+%22Naur,+Ehn,+Musashi%22)</a></span> -<span class="Delimiter">:(before "int main")</span> -<span class="Comment">// End Tracing // hack to ensure most code in this layer comes before anything else</span> - <span class="Delimiter">:(before "End Types")</span> <span class="Normal">struct</span> trace_line <span class="Delimiter">{</span> <span class="Normal">int</span> depth<span class="Delimiter">;</span> <span class="Comment">// optional field just to help browse traces later</span> @@ -123,15 +120,18 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="Delimiter">};</span> <span class="Delimiter">:(before "End Globals")</span> -<span class="Normal">const</span> <span class="Normal">int</span> Max_depth = <span class="Constant">9999</span><span class="Delimiter">;</span> -<span class="Normal">const</span> <span class="Normal">int</span> Error_depth = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Comment">// definitely always print errors</span> -<span class="Normal">const</span> <span class="Normal">int</span> App_depth = <span class="Constant">2</span><span class="Delimiter">;</span> <span class="Comment">// temporarily where all mu code will trace to</span> -<span class="Delimiter">:(before "End Tracing")</span> <span class="Normal">bool</span> Hide_errors = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End Setup")</span> Hide_errors = <span class="Constant">false</span><span class="Delimiter">;</span> -<span class="Delimiter">:(before "End Tracing")</span> +<span class="Delimiter">:(before "End Types")</span> +<span class="Comment">// Pre-define some global constants that trace_stream needs to know about.</span> +<span class="Comment">// Since they're in the Types section, they'll be included in any cleaved</span> +<span class="Comment">// compilation units. So no extern linkage.</span> +<span class="Normal">const</span> <span class="Normal">int</span> Max_depth = <span class="Constant">9999</span><span class="Delimiter">;</span> +<span class="Normal">const</span> <span class="Normal">int</span> Error_depth = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Comment">// definitely always print errors</span> +<span class="Normal">const</span> <span class="Normal">int</span> App_depth = <span class="Constant">2</span><span class="Delimiter">;</span> <span class="Comment">// temporarily where all mu code will trace to</span> + <span class="Normal">struct</span> trace_stream <span class="Delimiter">{</span> vector<trace_line> past_lines<span class="Delimiter">;</span> <span class="Comment">// accumulator for current line</span> @@ -157,41 +157,52 @@ Hide_errors = <span class="Constant">false</span><span class="Delimiter">;</span <span class="Delimiter">}</span> <span class="Comment">// be sure to call this before messing with curr_stream or curr_label</span> - <span class="Normal">void</span> newline<span class="Delimiter">()</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!curr_stream<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> - string curr_contents = curr_stream<span class="Delimiter">-></span>str<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr_contents<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> - past_lines<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>trace_line<span class="Delimiter">(</span>curr_depth<span class="Delimiter">,</span> trim<span class="Delimiter">(</span>curr_label<span class="Delimiter">),</span> curr_contents<span class="Delimiter">));</span> <span class="Comment">// preserve indent in contents</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Hide_errors && curr_label == <span class="Constant">"error"</span><span class="Delimiter">)</span> - cerr << curr_label << <span class="Constant">": "</span> << curr_contents << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> - <span class="Normal">delete</span> curr_stream<span class="Delimiter">;</span> - curr_stream = <span class="Constant">NULL</span><span class="Delimiter">;</span> - curr_label<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> - curr_depth = Max_depth<span class="Delimiter">;</span> - <span class="Delimiter">}</span> - + <span class="Normal">void</span> newline<span class="Delimiter">();</span> <span class="Comment">// useful for debugging</span> - string readable_contents<span class="Delimiter">(</span>string label<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// empty label = show everything</span> - ostringstream output<span class="Delimiter">;</span> - label = trim<span class="Delimiter">(</span>label<span class="Delimiter">);</span> - <span class="Normal">for</span> <span class="Delimiter">(</span>vector<trace_line>::iterator p = past_lines<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != past_lines<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>label<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> || label == p<span class="Delimiter">-></span>label<span class="Delimiter">)</span> <span class="Delimiter">{</span> - output << std::setw<span class="Delimiter">(</span><span class="Constant">4</span><span class="Delimiter">)</span> << p<span class="Delimiter">-></span>depth << <span class="Constant">' '</span> << p<span class="Delimiter">-></span>label << <span class="Constant">": "</span> << p<span class="Delimiter">-></span>contents << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> - <span class="Delimiter">}</span> - <span class="Identifier">return</span> output<span class="Delimiter">.</span>str<span class="Delimiter">();</span> - <span class="Delimiter">}</span> + string readable_contents<span class="Delimiter">(</span>string label<span class="Delimiter">);</span> <span class="Comment">// empty label = show everything</span> <span class="Delimiter">};</span> -^L +<span class="Delimiter">:(code)</span> +<span class="Normal">void</span> trace_stream::newline<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!curr_stream<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + string curr_contents = curr_stream<span class="Delimiter">-></span>str<span class="Delimiter">();</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>curr_contents<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + past_lines<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>trace_line<span class="Delimiter">(</span>curr_depth<span class="Delimiter">,</span> trim<span class="Delimiter">(</span>curr_label<span class="Delimiter">),</span> curr_contents<span class="Delimiter">));</span> <span class="Comment">// preserve indent in contents</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!Hide_errors && curr_label == <span class="Constant">"error"</span><span class="Delimiter">)</span> + cerr << curr_label << <span class="Constant">": "</span> << curr_contents << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + <span class="Normal">delete</span> curr_stream<span class="Delimiter">;</span> + curr_stream = <span class="Constant">NULL</span><span class="Delimiter">;</span> + curr_label<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> + curr_depth = Max_depth<span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +string trace_stream::readable_contents<span class="Delimiter">(</span>string label<span class="Delimiter">)</span> <span class="Delimiter">{</span> + ostringstream output<span class="Delimiter">;</span> + label = trim<span class="Delimiter">(</span>label<span class="Delimiter">);</span> + <span class="Normal">for</span> <span class="Delimiter">(</span>vector<trace_line>::iterator p = past_lines<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != past_lines<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>label<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> || label == p<span class="Delimiter">-></span>label<span class="Delimiter">)</span> <span class="Delimiter">{</span> + output << std::setw<span class="Delimiter">(</span><span class="Constant">4</span><span class="Delimiter">)</span> << p<span class="Delimiter">-></span>depth << <span class="Constant">' '</span> << p<span class="Delimiter">-></span>label << <span class="Constant">": "</span> << p<span class="Delimiter">-></span>contents << <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Identifier">return</span> output<span class="Delimiter">.</span>str<span class="Delimiter">();</span> +<span class="Delimiter">}</span> +<span class="Delimiter">:(before "End Globals")</span> trace_stream* Trace_stream = <span class="Constant">NULL</span><span class="Delimiter">;</span> <span class="Normal">int</span> Trace_errors = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Comment">// used only when Trace_stream is NULL</span> +<span class="Delimiter">:(before "End Includes")</span> +<span class="PreProc">#define CLEAR_TRACE </span><span class="Normal">delete</span><span class="PreProc"> Trace_stream</span><span class="Delimiter">,</span><span class="PreProc"> Trace_stream = </span><span class="Normal">new</span><span class="PreProc"> trace_stream</span><span class="Delimiter">;</span> + <span class="Comment">// Top-level helper. IMPORTANT: can't nest</span> <span class="PreProc">#define trace(</span><span class="Delimiter">...</span><span class="PreProc">) !Trace_stream ? cerr </span><span class="Comment">/*</span><span class="Comment">print nothing</span><span class="Comment">*/</span><span class="PreProc"> : Trace_stream</span><span class="Delimiter">-></span><span class="PreProc">stream(__VA_ARGS__)</span> +<span class="Comment">// Just for debugging; 'git log' should never show any calls to 'dbg'.</span> +<span class="PreProc">#define dbg trace(</span><span class="Constant">0</span><span class="Delimiter">,</span><span class="PreProc"> </span><span class="Constant">"a"</span><span class="PreProc">)</span> +<span class="PreProc">#define DUMP(label) </span><span class="Normal">if</span><span class="PreProc"> (Trace_stream) cerr << Trace_stream</span><span class="Delimiter">-></span><span class="PreProc">readable_contents(label)</span><span class="Delimiter">;</span> + <span class="Comment">// Errors are a special layer.</span> <span class="PreProc">#define raise (!Trace_stream ? (tb_shutdown()</span><span class="Delimiter">,</span><span class="PreProc">++Trace_errors</span><span class="Delimiter">,</span><span class="PreProc">cerr) </span><span class="Comment">/*</span><span class="Comment">do print</span><span class="Comment">*/</span><span class="PreProc"> : Trace_stream</span><span class="Delimiter">-></span><span class="PreProc">stream(Error_depth</span><span class="Delimiter">,</span><span class="PreProc"> </span><span class="Constant">"error"</span><span class="PreProc">))</span> + <span class="Comment">// Inside tests, fail any tests that displayed (unexpected) errors.</span> <span class="Comment">// Expected errors in tests should always be hidden and silently checked for.</span> <span class="Delimiter">:(before "End Test Teardown")</span> @@ -200,37 +211,35 @@ trace_stream* Trace_stream = <span class="Constant">NULL</span><span class="Deli ++Num_failures<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Comment">// Just for debugging.</span> -<span class="PreProc">#define dbg trace(</span><span class="Constant">0</span><span class="Delimiter">,</span><span class="PreProc"> </span><span class="Constant">"a"</span><span class="PreProc">)</span> - <span class="Delimiter">:(before "End Types")</span> <span class="Normal">struct</span> end <span class="Delimiter">{};</span> -<span class="Delimiter">:(before "End Tracing")</span> +<span class="Delimiter">:(code)</span> ostream& <span class="Normal">operator</span><<<span class="Delimiter">(</span>ostream& os<span class="Delimiter">,</span> unused end<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">)</span> Trace_stream<span class="Delimiter">-></span>newline<span class="Delimiter">();</span> <span class="Identifier">return</span> os<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="PreProc">#define CLEAR_TRACE </span><span class="Normal">delete</span><span class="PreProc"> Trace_stream</span><span class="Delimiter">,</span><span class="PreProc"> Trace_stream = </span><span class="Normal">new</span><span class="PreProc"> trace_stream</span><span class="Delimiter">;</span> - -<span class="PreProc">#define DUMP(label) </span><span class="Normal">if</span><span class="PreProc"> (Trace_stream) cerr << Trace_stream</span><span class="Delimiter">-></span><span class="PreProc">readable_contents(label)</span><span class="Delimiter">;</span> - +<span class="Delimiter">:(before "End Globals")</span> <span class="Normal">bool</span> Save_trace = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Comment">// Trace_stream is a resource, lease_tracer uses RAII to manage it.</span> +<span class="Delimiter">:(before "End Types")</span> <span class="Normal">struct</span> lease_tracer <span class="Delimiter">{</span> - lease_tracer<span class="Delimiter">()</span> <span class="Delimiter">{</span> Trace_stream = <span class="Normal">new</span> trace_stream<span class="Delimiter">;</span> <span class="Delimiter">}</span> - ~lease_tracer<span class="Delimiter">()</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!Trace_stream<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// in case tests close Trace_stream</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>Save_trace<span class="Delimiter">)</span> <span class="Delimiter">{</span> - ofstream fout<span class="Delimiter">(</span><span class="Constant">"last_trace"</span><span class="Delimiter">);</span> - fout << Trace_stream<span class="Delimiter">-></span>readable_contents<span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">);</span> - fout<span class="Delimiter">.</span>close<span class="Delimiter">();</span> - <span class="Delimiter">}</span> - <span class="Normal">delete</span> Trace_stream<span class="Delimiter">,</span> Trace_stream = <span class="Constant">NULL</span><span class="Delimiter">;</span> - <span class="Delimiter">}</span> + lease_tracer<span class="Delimiter">();</span> + ~lease_tracer<span class="Delimiter">();</span> <span class="Delimiter">};</span> - +<span class="Delimiter">:(code)</span> +lease_tracer::lease_tracer<span class="Delimiter">()</span> <span class="Delimiter">{</span> Trace_stream = <span class="Normal">new</span> trace_stream<span class="Delimiter">;</span> <span class="Delimiter">}</span> +lease_tracer::~lease_tracer<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!Trace_stream<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// in case tests close Trace_stream</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>Save_trace<span class="Delimiter">)</span> <span class="Delimiter">{</span> + ofstream fout<span class="Delimiter">(</span><span class="Constant">"last_trace"</span><span class="Delimiter">);</span> + fout << Trace_stream<span class="Delimiter">-></span>readable_contents<span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">);</span> + fout<span class="Delimiter">.</span>close<span class="Delimiter">();</span> + <span class="Delimiter">}</span> + <span class="Normal">delete</span> Trace_stream<span class="Delimiter">,</span> Trace_stream = <span class="Constant">NULL</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> +<span class="Delimiter">:(before "End Includes")</span> <span class="PreProc">#define START_TRACING_UNTIL_END_OF_SCOPE lease_tracer leased_tracer</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End Test Setup")</span> START_TRACING_UNTIL_END_OF_SCOPE @@ -238,8 +247,31 @@ START_TRACING_UNTIL_END_OF_SCOPE <span class="Delimiter">:(before "End Includes")</span> <span class="PreProc">#define CHECK_TRACE_CONTENTS(</span><span class="Delimiter">...</span><span class="PreProc">) check_trace_contents(__FUNCTION__</span><span class="Delimiter">,</span><span class="PreProc"> </span><span class="Constant">__FILE__</span><span class="Delimiter">,</span><span class="PreProc"> </span><span class="Constant">__LINE__</span><span class="Delimiter">,</span><span class="PreProc"> __VA_ARGS__)</span> -<span class="Delimiter">:(before "End Tracing")</span> +<span class="PreProc">#define CHECK_TRACE_CONTAINS_ERROR() CHECK(trace_count(</span><span class="Constant">"error"</span><span class="PreProc">) > </span><span class="Constant">0</span><span class="PreProc">)</span> +<span class="PreProc">#define CHECK_TRACE_DOESNT_CONTAIN_ERROR() \</span> +<span class="PreProc"> </span><span class="Normal">if</span><span class="PreProc"> (Passed && trace_count(</span><span class="Constant">"error"</span><span class="PreProc">) > </span><span class="Constant">0</span><span class="PreProc">) </span><span class="Delimiter">{</span><span class="PreProc"> \</span> +<span class="PreProc"> ++Num_failures</span><span class="Delimiter">;</span><span class="PreProc"> \</span> +<span class="PreProc"> cerr << </span><span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span><span class="PreProc"> << __FUNCTION__ << </span><span class="Constant">"("</span><span class="PreProc"> << </span><span class="Constant">__FILE__</span><span class="PreProc"> << </span><span class="Constant">":"</span><span class="PreProc"> << </span><span class="Constant">__LINE__</span><span class="PreProc"> << </span><span class="Constant">"): unexpected errors</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span><span class="PreProc"> \</span> +<span class="PreProc"> DUMP(</span><span class="Constant">"error"</span><span class="PreProc">)</span><span class="Delimiter">;</span><span class="PreProc"> \</span> +<span class="PreProc"> Passed = </span><span class="Constant">false</span><span class="Delimiter">;</span><span class="PreProc"> \</span> +<span class="PreProc"> </span><span class="Identifier">return</span><span class="Delimiter">;</span><span class="PreProc"> \</span> +<span class="PreProc"> </span><span class="Delimiter">}</span> + +<span class="PreProc">#define CHECK_TRACE_COUNT(label</span><span class="Delimiter">,</span><span class="PreProc"> count) \</span> +<span class="PreProc"> </span><span class="Normal">if</span><span class="PreProc"> (Passed && trace_count(label) != (count)) </span><span class="Delimiter">{</span><span class="PreProc"> \</span> +<span class="PreProc"> ++Num_failures</span><span class="Delimiter">;</span><span class="PreProc"> \</span> +<span class="PreProc"> cerr << </span><span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span><span class="PreProc"> << __FUNCTION__ << </span><span class="Constant">"("</span><span class="PreProc"> << </span><span class="Constant">__FILE__</span><span class="PreProc"> << </span><span class="Constant">":"</span><span class="PreProc"> << </span><span class="Constant">__LINE__</span><span class="PreProc"> << </span><span class="Constant">"): trace_count of "</span><span class="PreProc"> << label << </span><span class="Constant">" should be "</span><span class="PreProc"> << count << </span><span class="cSpecial">'\n'</span><span class="Delimiter">;</span><span class="PreProc"> \</span> +<span class="PreProc"> cerr << </span><span class="Constant">" got "</span><span class="PreProc"> << trace_count(label) << </span><span class="cSpecial">'\n'</span><span class="Delimiter">;</span><span class="PreProc"> </span><span class="Comment">/*</span><span class="Comment"> multiple eval </span><span class="Comment">*/</span><span class="PreProc"> \</span> +<span class="PreProc"> DUMP(label)</span><span class="Delimiter">;</span><span class="PreProc"> \</span> +<span class="PreProc"> Passed = </span><span class="Constant">false</span><span class="Delimiter">;</span><span class="PreProc"> \</span> +<span class="PreProc"> </span><span class="Identifier">return</span><span class="Delimiter">;</span><span class="PreProc"> </span><span class="Comment">/*</span><span class="Comment"> Currently we stop at the very first failure. </span><span class="Comment">*/</span><span class="PreProc"> \</span> +<span class="PreProc"> </span><span class="Delimiter">}</span> + +<span class="PreProc">#define CHECK_TRACE_DOESNT_CONTAIN(</span><span class="Delimiter">...</span><span class="PreProc">) CHECK(trace_doesnt_contain(__VA_ARGS__))</span> + +<span class="Delimiter">:(code)</span> <span class="Normal">bool</span> check_trace_contents<span class="Delimiter">(</span>string FUNCTION<span class="Delimiter">,</span> string <span class="Normal">FILE</span><span class="Delimiter">,</span> <span class="Normal">int</span> LINE<span class="Delimiter">,</span> string expected<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!Trace_stream<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> vector<string> expected_lines = split<span class="Delimiter">(</span>expected<span class="Delimiter">,</span> <span class="Constant">"^D"</span><span class="Delimiter">);</span> <span class="Normal">int</span> curr_expected_line = <span class="Constant">0</span><span class="Delimiter">;</span> @@ -292,8 +324,6 @@ START_TRACING_UNTIL_END_OF_SCOPE <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -^L - <span class="Normal">int</span> trace_count<span class="Delimiter">(</span>string label<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> trace_count<span class="Delimiter">(</span>label<span class="Delimiter">,</span> <span class="Constant">""</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> @@ -322,26 +352,6 @@ START_TRACING_UNTIL_END_OF_SCOPE <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="PreProc">#define CHECK_TRACE_CONTAINS_ERROR() CHECK(trace_count(</span><span class="Constant">"error"</span><span class="PreProc">) > </span><span class="Constant">0</span><span class="PreProc">)</span> -<span class="PreProc">#define CHECK_TRACE_DOESNT_CONTAIN_ERROR() \</span> -<span class="PreProc"> </span><span class="Normal">if</span><span class="PreProc"> (trace_count(</span><span class="Constant">"error"</span><span class="PreProc">) > </span><span class="Constant">0</span><span class="PreProc">) </span><span class="Delimiter">{</span><span class="PreProc"> \</span> -<span class="PreProc"> ++Num_failures</span><span class="Delimiter">;</span><span class="PreProc"> \</span> -<span class="PreProc"> cerr << </span><span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span><span class="PreProc"> << __FUNCTION__ << </span><span class="Constant">"("</span><span class="PreProc"> << </span><span class="Constant">__FILE__</span><span class="PreProc"> << </span><span class="Constant">":"</span><span class="PreProc"> << </span><span class="Constant">__LINE__</span><span class="PreProc"> << </span><span class="Constant">"): unexpected errors</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">;</span><span class="PreProc"> \</span> -<span class="PreProc"> DUMP(</span><span class="Constant">"error"</span><span class="PreProc">)</span><span class="Delimiter">;</span><span class="PreProc"> \</span> -<span class="PreProc"> Passed = </span><span class="Constant">false</span><span class="Delimiter">;</span><span class="PreProc"> \</span> -<span class="PreProc"> </span><span class="Identifier">return</span><span class="Delimiter">;</span><span class="PreProc"> \</span> -<span class="PreProc"> </span><span class="Delimiter">}</span> - -<span class="PreProc">#define CHECK_TRACE_COUNT(label</span><span class="Delimiter">,</span><span class="PreProc"> count) \</span> -<span class="PreProc"> </span><span class="Normal">if</span><span class="PreProc"> (trace_count(label) != (count)) </span><span class="Delimiter">{</span><span class="PreProc"> \</span> -<span class="PreProc"> ++Num_failures</span><span class="Delimiter">;</span><span class="PreProc"> \</span> -<span class="PreProc"> cerr << </span><span class="Constant">"</span><span class="cSpecial">\n</span><span class="Constant">F - "</span><span class="PreProc"> << __FUNCTION__ << </span><span class="Constant">"("</span><span class="PreProc"> << </span><span class="Constant">__FILE__</span><span class="PreProc"> << </span><span class="Constant">":"</span><span class="PreProc"> << </span><span class="Constant">__LINE__</span><span class="PreProc"> << </span><span class="Constant">"): trace_count of "</span><span class="PreProc"> << label << </span><span class="Constant">" should be "</span><span class="PreProc"> << count << </span><span class="cSpecial">'\n'</span><span class="Delimiter">;</span><span class="PreProc"> \</span> -<span class="PreProc"> cerr << </span><span class="Constant">" got "</span><span class="PreProc"> << trace_count(label) << </span><span class="cSpecial">'\n'</span><span class="Delimiter">;</span><span class="PreProc"> </span><span class="Comment">/*</span><span class="Comment"> multiple eval </span><span class="Comment">*/</span><span class="PreProc"> \</span> -<span class="PreProc"> DUMP(label)</span><span class="Delimiter">;</span><span class="PreProc"> \</span> -<span class="PreProc"> Passed = </span><span class="Constant">false</span><span class="Delimiter">;</span><span class="PreProc"> \</span> -<span class="PreProc"> </span><span class="Identifier">return</span><span class="Delimiter">;</span><span class="PreProc"> </span><span class="Comment">/*</span><span class="Comment"> Currently we stop at the very first failure. </span><span class="Comment">*/</span><span class="PreProc"> \</span> -<span class="PreProc"> </span><span class="Delimiter">}</span> - <span class="Normal">bool</span> trace_doesnt_contain<span class="Delimiter">(</span>string label<span class="Delimiter">,</span> string line<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> trace_count<span class="Delimiter">(</span>label<span class="Delimiter">,</span> line<span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -351,10 +361,6 @@ START_TRACING_UNTIL_END_OF_SCOPE <span class="Identifier">return</span> trace_doesnt_contain<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">),</span> tmp<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">));</span> <span class="Delimiter">}</span> -<span class="PreProc">#define CHECK_TRACE_DOESNT_CONTAIN(</span><span class="Delimiter">...</span><span class="PreProc">) CHECK(trace_doesnt_contain(__VA_ARGS__))</span> - -^L - vector<string> split<span class="Delimiter">(</span>string s<span class="Delimiter">,</span> string delim<span class="Delimiter">)</span> <span class="Delimiter">{</span> vector<string> result<span class="Delimiter">;</span> <span class="Normal">size_t</span> begin=<span class="Constant">0</span><span class="Delimiter">,</span> end=s<span class="Delimiter">.</span>find<span class="Delimiter">(</span>delim<span class="Delimiter">);</span> @@ -419,8 +425,8 @@ string trim<span class="Delimiter">(</span><span class="Normal">const</span> str <span class="Comment">//: Errors will be depth 0.</span> <span class="Comment">//: Mu 'applications' will be able to use depths 1-100 as they like.</span> <span class="Comment">//: Primitive statements will occupy 101-9989</span> -<span class="Normal">const</span> <span class="Normal">int</span> Initial_callstack_depth = <span class="Constant">101</span><span class="Delimiter">;</span> -<span class="Normal">const</span> <span class="Normal">int</span> Max_callstack_depth = <span class="Constant">9989</span><span class="Delimiter">;</span> +<span class="Normal">extern</span> <span class="Normal">const</span> <span class="Normal">int</span> Initial_callstack_depth = <span class="Constant">101</span><span class="Delimiter">;</span> +<span class="Normal">extern</span> <span class="Normal">const</span> <span class="Normal">int</span> Max_callstack_depth = <span class="Constant">9989</span><span class="Delimiter">;</span> <span class="Comment">//: Finally, details of primitive mu statements will occupy depth 9990-9999 (more on that later as well)</span> <span class="Comment">//:</span> <span class="Comment">//: This framework should help us hide some details at each level, mixing</span> diff --git a/html/003trace.test.cc.html b/html/003trace.test.cc.html index 439e8613..6c1c6e53 100644 --- a/html/003trace.test.cc.html +++ b/html/003trace.test.cc.html @@ -43,8 +43,8 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="Normal">void</span> test_trace_check_ignores_leading_whitespace<span class="Delimiter">()</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">)</span> << <span class="Constant">" foo"</span> << end<span class="Delimiter">();</span> - CHECK<span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">too little whitespace</span><span class="Comment">*/</span><span class="Constant">"foo"</span><span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">);</span> - CHECK<span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">too much whitespace</span><span class="Comment">*/</span><span class="Constant">" foo"</span><span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">too little whitespace</span><span class="Comment">*/</span><span class="Constant">"foo"</span><span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">,</span> <span class="Comment">/*</span><span class="Comment">too much whitespace</span><span class="Comment">*/</span><span class="Constant">" foo"</span><span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">void</span> test_trace_check_ignores_other_lines<span class="Delimiter">()</span> <span class="Delimiter">{</span> @@ -90,7 +90,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="Normal">void</span> test_trace_count_ignores_trailing_whitespace<span class="Delimiter">()</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">)</span> << <span class="Constant">"foo</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> - CHECK<span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">,</span> <span class="Constant">"foo"</span><span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>trace_count<span class="Delimiter">(</span><span class="Constant">"test layer 1"</span><span class="Delimiter">,</span> <span class="Constant">"foo"</span><span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Comment">// pending: DUMP tests</span> @@ -102,8 +102,6 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="Comment">// pending: raise prints to stderr if Trace_stream is NULL even if Hide_errors is set.</span> <span class="Comment">// pending: raise << ... die() doesn't die if Hide_errors is set.</span> -^L - <span class="Comment">// can't check trace because trace methods call 'split'</span> <span class="Normal">void</span> test_split_returns_at_least_one_elem<span class="Delimiter">()</span> <span class="Delimiter">{</span> diff --git a/html/010vm.cc.html b/html/010vm.cc.html index cc6b5360..e539a833 100644 --- a/html/010vm.cc.html +++ b/html/010vm.cc.html @@ -21,6 +21,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color .Identifier { color: #fcb165; } .Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } .PreProc { color: #800080; } +.CommentedCode { color: #6c6c6c; } --> </style> @@ -104,40 +105,41 @@ recipe_ordinal Next_recipe_ordinal = <span class="Constant">1</span><span class= <span class="Comment">// Types can range from a simple type ordinal, to arbitrarily complex trees of</span> <span class="Comment">// type parameters, like (map (address array character) (list number))</span> <span class="Normal">struct</span> type_tree <span class="Delimiter">{</span> - string name<span class="Delimiter">;</span> - type_ordinal value<span class="Delimiter">;</span> - type_tree* left<span class="Delimiter">;</span> - type_tree* right<span class="Delimiter">;</span> + <span class="Normal">bool</span> atom<span class="Delimiter">;</span> + string name<span class="Delimiter">;</span> <span class="Comment">// only if atom</span> + type_ordinal value<span class="Delimiter">;</span> <span class="Comment">// only if atom</span> + type_tree* left<span class="Delimiter">;</span> <span class="Comment">// only if !atom</span> + type_tree* right<span class="Delimiter">;</span> <span class="Comment">// only if !atom</span> ~type_tree<span class="Delimiter">();</span> type_tree<span class="Delimiter">(</span><span class="Normal">const</span> type_tree& old<span class="Delimiter">);</span> - <span class="Comment">// simple: type ordinal</span> + <span class="Comment">// atomic type ordinal</span> <span class="Normal">explicit</span> type_tree<span class="Delimiter">(</span>string name<span class="Delimiter">);</span> - type_tree<span class="Delimiter">(</span>string name<span class="Delimiter">,</span> type_ordinal v<span class="Delimiter">)</span> :name<span class="Delimiter">(</span>name<span class="Delimiter">),</span> value<span class="Delimiter">(</span>v<span class="Delimiter">),</span> left<span class="Delimiter">(</span><span class="Constant">NULL</span><span class="Delimiter">),</span> right<span class="Delimiter">(</span><span class="Constant">NULL</span><span class="Delimiter">)</span> <span class="Delimiter">{}</span> - <span class="Comment">// intermediate: list of type ordinals</span> - type_tree<span class="Delimiter">(</span>string name<span class="Delimiter">,</span> type_ordinal v<span class="Delimiter">,</span> type_tree* r<span class="Delimiter">)</span> :name<span class="Delimiter">(</span>name<span class="Delimiter">),</span> value<span class="Delimiter">(</span>v<span class="Delimiter">),</span> left<span class="Delimiter">(</span><span class="Constant">NULL</span><span class="Delimiter">),</span> right<span class="Delimiter">(</span>r<span class="Delimiter">)</span> <span class="Delimiter">{}</span> - type_tree<span class="Delimiter">(</span>string name<span class="Delimiter">,</span> type_tree* r<span class="Delimiter">);</span> - <span class="Comment">// advanced: tree containing type ordinals</span> - type_tree<span class="Delimiter">(</span>type_tree* l<span class="Delimiter">,</span> type_tree* r<span class="Delimiter">)</span> :value<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">),</span> left<span class="Delimiter">(</span>l<span class="Delimiter">),</span> right<span class="Delimiter">(</span>r<span class="Delimiter">)</span> <span class="Delimiter">{}</span> + type_tree<span class="Delimiter">(</span>string name<span class="Delimiter">,</span> type_ordinal v<span class="Delimiter">)</span> :atom<span class="Delimiter">(</span><span class="Constant">true</span><span class="Delimiter">),</span> name<span class="Delimiter">(</span>name<span class="Delimiter">),</span> value<span class="Delimiter">(</span>v<span class="Delimiter">),</span> left<span class="Delimiter">(</span><span class="Constant">NULL</span><span class="Delimiter">),</span> right<span class="Delimiter">(</span><span class="Constant">NULL</span><span class="Delimiter">)</span> <span class="Delimiter">{}</span> + <span class="Comment">// tree of type ordinals</span> + type_tree<span class="Delimiter">(</span>type_tree* l<span class="Delimiter">,</span> type_tree* r<span class="Delimiter">)</span> :atom<span class="Delimiter">(</span><span class="Constant">false</span><span class="Delimiter">),</span> value<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">),</span> left<span class="Delimiter">(</span>l<span class="Delimiter">),</span> right<span class="Delimiter">(</span>r<span class="Delimiter">)</span> <span class="Delimiter">{}</span> + type_tree& <span class="Normal">operator</span>=<span class="Delimiter">(</span><span class="Normal">const</span> type_tree& old<span class="Delimiter">);</span> + <span class="Normal">bool</span> <span class="Normal">operator</span>==<span class="Delimiter">(</span><span class="Normal">const</span> type_tree& other<span class="Delimiter">)</span> <span class="Normal">const</span><span class="Delimiter">;</span> + <span class="Normal">bool</span> <span class="Normal">operator</span>!=<span class="Delimiter">(</span><span class="Normal">const</span> type_tree& other<span class="Delimiter">)</span> <span class="Normal">const</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> !<span class="Normal">operator</span>==<span class="Delimiter">(</span>other<span class="Delimiter">);</span> <span class="Delimiter">}</span> + <span class="Normal">bool</span> <span class="Normal">operator</span><<span class="Delimiter">(</span><span class="Normal">const</span> type_tree& other<span class="Delimiter">)</span> <span class="Normal">const</span><span class="Delimiter">;</span> + <span class="Normal">bool</span> <span class="Normal">operator</span>><span class="Delimiter">(</span><span class="Normal">const</span> type_tree& other<span class="Delimiter">)</span> <span class="Normal">const</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> other<span class="Delimiter">.</span><span class="Normal">operator</span><<span class="Delimiter">(</span>*<span class="Normal">this</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">};</span> <span class="Normal">struct</span> string_tree <span class="Delimiter">{</span> - string value<span class="Delimiter">;</span> - string_tree* left<span class="Delimiter">;</span> - string_tree* right<span class="Delimiter">;</span> + <span class="Normal">bool</span> atom<span class="Delimiter">;</span> + string value<span class="Delimiter">;</span> <span class="Comment">// only if atom</span> + string_tree* left<span class="Delimiter">;</span> <span class="Comment">// only if !atom</span> + string_tree* right<span class="Delimiter">;</span> <span class="Comment">// only if !atom</span> ~string_tree<span class="Delimiter">();</span> string_tree<span class="Delimiter">(</span><span class="Normal">const</span> string_tree& old<span class="Delimiter">);</span> - <span class="Comment">// simple: flat string</span> - <span class="Normal">explicit</span> string_tree<span class="Delimiter">(</span>string v<span class="Delimiter">)</span> :value<span class="Delimiter">(</span>v<span class="Delimiter">),</span> left<span class="Delimiter">(</span><span class="Constant">NULL</span><span class="Delimiter">),</span> right<span class="Delimiter">(</span><span class="Constant">NULL</span><span class="Delimiter">)</span> <span class="Delimiter">{}</span> - <span class="Comment">// intermediate: list of strings</span> - string_tree<span class="Delimiter">(</span>string v<span class="Delimiter">,</span> string_tree* r<span class="Delimiter">)</span> :value<span class="Delimiter">(</span>v<span class="Delimiter">),</span> left<span class="Delimiter">(</span><span class="Constant">NULL</span><span class="Delimiter">),</span> right<span class="Delimiter">(</span>r<span class="Delimiter">)</span> <span class="Delimiter">{}</span> - <span class="Comment">// advanced: tree containing strings</span> - string_tree<span class="Delimiter">(</span>string_tree* l<span class="Delimiter">,</span> string_tree* r<span class="Delimiter">)</span> :left<span class="Delimiter">(</span>l<span class="Delimiter">),</span> right<span class="Delimiter">(</span>r<span class="Delimiter">)</span> <span class="Delimiter">{}</span> + <span class="Comment">// atomic string</span> + <span class="Normal">explicit</span> string_tree<span class="Delimiter">(</span>string v<span class="Delimiter">)</span> :atom<span class="Delimiter">(</span><span class="Constant">true</span><span class="Delimiter">),</span> value<span class="Delimiter">(</span>v<span class="Delimiter">),</span> left<span class="Delimiter">(</span><span class="Constant">NULL</span><span class="Delimiter">),</span> right<span class="Delimiter">(</span><span class="Constant">NULL</span><span class="Delimiter">)</span> <span class="Delimiter">{}</span> + <span class="Comment">// tree of strings</span> + string_tree<span class="Delimiter">(</span>string_tree* l<span class="Delimiter">,</span> string_tree* r<span class="Delimiter">)</span> :atom<span class="Delimiter">(</span><span class="Constant">false</span><span class="Delimiter">),</span> left<span class="Delimiter">(</span>l<span class="Delimiter">),</span> right<span class="Delimiter">(</span>r<span class="Delimiter">)</span> <span class="Delimiter">{}</span> <span class="Delimiter">};</span> <span class="Comment">// End type_tree Definition</span> <span class="Delimiter">:(code)</span> -type_tree::type_tree<span class="Delimiter">(</span>string name<span class="Delimiter">)</span> :name<span class="Delimiter">(</span>name<span class="Delimiter">),</span> value<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">)),</span> left<span class="Delimiter">(</span><span class="Constant">NULL</span><span class="Delimiter">),</span> right<span class="Delimiter">(</span><span class="Constant">NULL</span><span class="Delimiter">)</span> <span class="Delimiter">{}</span> -type_tree::type_tree<span class="Delimiter">(</span>string name<span class="Delimiter">,</span> type_tree* r<span class="Delimiter">)</span> :name<span class="Delimiter">(</span>name<span class="Delimiter">),</span> value<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">)),</span> left<span class="Delimiter">(</span><span class="Constant">NULL</span><span class="Delimiter">),</span> right<span class="Delimiter">(</span>r<span class="Delimiter">)</span> <span class="Delimiter">{}</span> +type_tree::type_tree<span class="Delimiter">(</span>string name<span class="Delimiter">)</span> :atom<span class="Delimiter">(</span><span class="Constant">true</span><span class="Delimiter">),</span> name<span class="Delimiter">(</span>name<span class="Delimiter">),</span> value<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">)),</span> left<span class="Delimiter">(</span><span class="Constant">NULL</span><span class="Delimiter">),</span> right<span class="Delimiter">(</span><span class="Constant">NULL</span><span class="Delimiter">)</span> <span class="Delimiter">{}</span> <span class="Delimiter">:(before "End Globals")</span> <span class="Comment">// Locations refer to a common 'memory'. Each location can store a number.</span> @@ -281,8 +283,6 @@ restore_snapshots<span class="Delimiter">();</span> <span class="Comment">// End restore_snapshots</span> <span class="Delimiter">}</span> -^L - <span class="SalientComment">//:: Helpers</span> <span class="Delimiter">:(code)</span> @@ -306,6 +306,7 @@ reagent::reagent<span class="Delimiter">(</span><span class="Normal">const</span first_row >> std::noskipws<span class="Delimiter">;</span> name = slurp_until<span class="Delimiter">(</span>first_row<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">);</span> string_tree* type_names = parse_property_list<span class="Delimiter">(</span>first_row<span class="Delimiter">);</span> + <span class="Comment">// End Parsing Reagent Type Property(type_names)</span> type = new_type_tree<span class="Delimiter">(</span>type_names<span class="Delimiter">);</span> <span class="Normal">delete</span> type_names<span class="Delimiter">;</span> <span class="Comment">// special cases</span> @@ -331,26 +332,29 @@ reagent::reagent<span class="Delimiter">(</span><span class="Normal">const</span string_tree* parse_property_list<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> skip_whitespace_but_not_newline<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span> - string_tree* result = <span class="Normal">new</span> string_tree<span class="Delimiter">(</span>slurp_until<span class="Delimiter">(</span>in<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">));</span> - result<span class="Delimiter">-></span>right = parse_property_list<span class="Delimiter">(</span>in<span class="Delimiter">);</span> - <span class="Identifier">return</span> result<span class="Delimiter">;</span> + string_tree* left = <span class="Normal">new</span> string_tree<span class="Delimiter">(</span>slurp_until<span class="Delimiter">(</span>in<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">));</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Identifier">return</span> left<span class="Delimiter">;</span> + string_tree* right = parse_property_list<span class="Delimiter">(</span>in<span class="Delimiter">);</span> + <span class="Identifier">return</span> <span class="Normal">new</span> string_tree<span class="Delimiter">(</span>left<span class="Delimiter">,</span> right<span class="Delimiter">);</span> <span class="Delimiter">}</span> type_tree* new_type_tree<span class="Delimiter">(</span><span class="Normal">const</span> string_tree* properties<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!properties<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span> - type_tree* result = <span class="Normal">new</span> type_tree<span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!properties<span class="Delimiter">-></span>value<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> - <span class="Normal">const</span> string& type_name = result<span class="Delimiter">-></span>name = properties<span class="Delimiter">-></span>value<span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>properties<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">const</span> string& type_name = properties<span class="Delimiter">-></span>value<span class="Delimiter">;</span> + <span class="Normal">int</span> value = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type_name<span class="Delimiter">))</span> - result<span class="Delimiter">-></span>value = get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type_name<span class="Delimiter">);</span> + value = get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type_name<span class="Delimiter">);</span> <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>type_name<span class="Delimiter">))</span> <span class="Comment">// sometimes types will contain non-type tags, like numbers for the size of an array</span> - result<span class="Delimiter">-></span>value = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>properties<span class="Delimiter">-></span>value != <span class="Constant">"->"</span><span class="Delimiter">)</span> <span class="Comment">// used in recipe types</span> - result<span class="Delimiter">-></span>value = -<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Comment">// should never happen; will trigger errors later</span> + value = <span class="Constant">0</span><span class="Delimiter">;</span> + <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>properties<span class="Delimiter">-></span>value == <span class="Constant">"->"</span><span class="Delimiter">)</span> <span class="Comment">// used in recipe types</span> + value = <span class="Constant">0</span><span class="Delimiter">;</span> + <span class="Normal">else</span> + value = -<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Comment">// should never happen; will trigger errors later</span> + <span class="Identifier">return</span> <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>type_name<span class="Delimiter">,</span> value<span class="Delimiter">);</span> <span class="Delimiter">}</span> - result<span class="Delimiter">-></span>left = new_type_tree<span class="Delimiter">(</span>properties<span class="Delimiter">-></span>left<span class="Delimiter">);</span> - result<span class="Delimiter">-></span>right = new_type_tree<span class="Delimiter">(</span>properties<span class="Delimiter">-></span>right<span class="Delimiter">);</span> - <span class="Identifier">return</span> result<span class="Delimiter">;</span> + <span class="Identifier">return</span> <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>new_type_tree<span class="Delimiter">(</span>properties<span class="Delimiter">-></span>left<span class="Delimiter">),</span> + new_type_tree<span class="Delimiter">(</span>properties<span class="Delimiter">-></span>right<span class="Delimiter">));</span> <span class="Delimiter">}</span> <span class="Comment">//: avoid memory leaks for the type tree</span> @@ -369,13 +373,103 @@ reagent::reagent<span class="Delimiter">(</span><span class="Normal">const</span <span class="Delimiter">}</span> type_tree::type_tree<span class="Delimiter">(</span><span class="Normal">const</span> type_tree& old<span class="Delimiter">)</span> <span class="Delimiter">{</span> + atom = old<span class="Delimiter">.</span>atom<span class="Delimiter">;</span> + name = old<span class="Delimiter">.</span>name<span class="Delimiter">;</span> + value = old<span class="Delimiter">.</span>value<span class="Delimiter">;</span> + left = old<span class="Delimiter">.</span>left ? <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*old<span class="Delimiter">.</span>left<span class="Delimiter">)</span> : <span class="Constant">NULL</span><span class="Delimiter">;</span> + right = old<span class="Delimiter">.</span>right ? <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*old<span class="Delimiter">.</span>right<span class="Delimiter">)</span> : <span class="Constant">NULL</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +type_tree& type_tree::<span class="Normal">operator</span>=<span class="Delimiter">(</span><span class="Normal">const</span> type_tree& old<span class="Delimiter">)</span> <span class="Delimiter">{</span> + atom = old<span class="Delimiter">.</span>atom<span class="Delimiter">;</span> name = old<span class="Delimiter">.</span>name<span class="Delimiter">;</span> value = old<span class="Delimiter">.</span>value<span class="Delimiter">;</span> left = old<span class="Delimiter">.</span>left ? <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*old<span class="Delimiter">.</span>left<span class="Delimiter">)</span> : <span class="Constant">NULL</span><span class="Delimiter">;</span> right = old<span class="Delimiter">.</span>right ? <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*old<span class="Delimiter">.</span>right<span class="Delimiter">)</span> : <span class="Constant">NULL</span><span class="Delimiter">;</span> + <span class="Identifier">return</span> *<span class="Normal">this</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +<span class="Normal">bool</span> type_tree::<span class="Normal">operator</span>==<span class="Delimiter">(</span><span class="Normal">const</span> type_tree& other<span class="Delimiter">)</span> <span class="Normal">const</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>atom != other<span class="Delimiter">.</span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>atom<span class="Delimiter">)</span> + <span class="Identifier">return</span> name == other<span class="Delimiter">.</span>name && value == other<span class="Delimiter">.</span>value<span class="Delimiter">;</span> + <span class="Identifier">return</span> <span class="Delimiter">(</span>left == other<span class="Delimiter">.</span>left || *left == *other<span class="Delimiter">.</span>left<span class="Delimiter">)</span> + && <span class="Delimiter">(</span>right == other<span class="Delimiter">.</span>right || *right == *other<span class="Delimiter">.</span>right<span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Comment">// only constraint we care about: if a < b then !(b < a)</span> +<span class="Normal">bool</span> type_tree::<span class="Normal">operator</span><<span class="Delimiter">(</span><span class="Normal">const</span> type_tree& other<span class="Delimiter">)</span> <span class="Normal">const</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>atom != other<span class="Delimiter">.</span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> atom > other<span class="Delimiter">.</span>atom<span class="Delimiter">;</span> <span class="Comment">// atoms before non-atoms</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> name < other<span class="Delimiter">.</span>name<span class="Delimiter">;</span> <span class="Comment">// sort atoms in lexical order</span> + <span class="Comment">// first location in one that's missing in the other makes that side 'smaller'</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>left && !other<span class="Delimiter">.</span>left<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!left && other<span class="Delimiter">.</span>left<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>right && !other<span class="Delimiter">.</span>right<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!right && other<span class="Delimiter">.</span>right<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + <span class="Comment">// if one side is equal that's easy</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>left == other<span class="Delimiter">.</span>left || *left == *other<span class="Delimiter">.</span>left<span class="Delimiter">)</span> <span class="Identifier">return</span> *right < *other<span class="Delimiter">.</span>right<span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>right == other<span class="Delimiter">.</span>right || *right == *other<span class="Delimiter">.</span>right<span class="Delimiter">)</span> <span class="Identifier">return</span> *left < *other<span class="Delimiter">.</span>left<span class="Delimiter">;</span> + <span class="Comment">// if the two sides criss-cross, pick the side with the smaller lhs</span> + <span class="Normal">if</span> <span class="Delimiter">((</span>left == other<span class="Delimiter">.</span>right || *left == *other<span class="Delimiter">.</span>right<span class="Delimiter">)</span> + && <span class="Delimiter">(</span>right == other<span class="Delimiter">.</span>left || *right == *other<span class="Delimiter">.</span>left<span class="Delimiter">))</span> + <span class="Identifier">return</span> *left < *other<span class="Delimiter">.</span>left<span class="Delimiter">;</span> + <span class="Comment">// now the hard case: both sides are not equal</span> + <span class="Comment">// make sure we stay consistent between (a < b) and (b < a)</span> + <span class="Comment">// just return the side with the smallest of the 4 branches</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>*left < *other<span class="Delimiter">.</span>left && *left < *other<span class="Delimiter">.</span>right<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>*right < *other<span class="Delimiter">.</span>left && *right < *other<span class="Delimiter">.</span>right<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> +<span class="Delimiter">:(before "End Unit Tests")</span> +<span class="Comment">// These unit tests don't always use valid types.</span> +<span class="Normal">void</span> test_compare_atom_types<span class="Delimiter">()</span> <span class="Delimiter">{</span> + reagent a<span class="Delimiter">(</span><span class="Constant">"a:address"</span><span class="Delimiter">),</span> b<span class="Delimiter">(</span><span class="Constant">"b:boolean"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>*a<span class="Delimiter">.</span>type < *b<span class="Delimiter">.</span>type<span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>!<span class="Delimiter">(</span>*b<span class="Delimiter">.</span>type < *a<span class="Delimiter">.</span>type<span class="Delimiter">));</span> +<span class="Delimiter">}</span> +<span class="Normal">void</span> test_compare_equal_atom_types<span class="Delimiter">()</span> <span class="Delimiter">{</span> + reagent a<span class="Delimiter">(</span><span class="Constant">"a:address"</span><span class="Delimiter">),</span> b<span class="Delimiter">(</span><span class="Constant">"b:address"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>!<span class="Delimiter">(</span>*a<span class="Delimiter">.</span>type < *b<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + CHECK<span class="Delimiter">(</span>!<span class="Delimiter">(</span>*b<span class="Delimiter">.</span>type < *a<span class="Delimiter">.</span>type<span class="Delimiter">));</span> +<span class="Delimiter">}</span> +<span class="Normal">void</span> test_compare_atom_with_non_atom<span class="Delimiter">()</span> <span class="Delimiter">{</span> + reagent a<span class="Delimiter">(</span><span class="Constant">"a:address:number"</span><span class="Delimiter">),</span> b<span class="Delimiter">(</span><span class="Constant">"b:boolean"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>!<span class="Delimiter">(</span>*a<span class="Delimiter">.</span>type < *b<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + CHECK<span class="Delimiter">(</span>*b<span class="Delimiter">.</span>type < *a<span class="Delimiter">.</span>type<span class="Delimiter">);</span> +<span class="Delimiter">}</span> +<span class="Normal">void</span> test_compare_lists_with_identical_structure<span class="Delimiter">()</span> <span class="Delimiter">{</span> + reagent a<span class="Delimiter">(</span><span class="Constant">"a:address:address"</span><span class="Delimiter">),</span> b<span class="Delimiter">(</span><span class="Constant">"b:address:boolean"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>*a<span class="Delimiter">.</span>type < *b<span class="Delimiter">.</span>type<span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>!<span class="Delimiter">(</span>*b<span class="Delimiter">.</span>type < *a<span class="Delimiter">.</span>type<span class="Delimiter">));</span> +<span class="Delimiter">}</span> +<span class="Normal">void</span> test_compare_identical_lists<span class="Delimiter">()</span> <span class="Delimiter">{</span> + reagent a<span class="Delimiter">(</span><span class="Constant">"a:address:boolean"</span><span class="Delimiter">),</span> b<span class="Delimiter">(</span><span class="Constant">"b:address:boolean"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>!<span class="Delimiter">(</span>*a<span class="Delimiter">.</span>type < *b<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + CHECK<span class="Delimiter">(</span>!<span class="Delimiter">(</span>*b<span class="Delimiter">.</span>type < *a<span class="Delimiter">.</span>type<span class="Delimiter">));</span> +<span class="Delimiter">}</span> +<span class="Normal">void</span> test_compare_list_with_extra_element<span class="Delimiter">()</span> <span class="Delimiter">{</span> + reagent a<span class="Delimiter">(</span><span class="Constant">"a:address:address"</span><span class="Delimiter">),</span> b<span class="Delimiter">(</span><span class="Constant">"b:address:address:number"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>*a<span class="Delimiter">.</span>type < *b<span class="Delimiter">.</span>type<span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>!<span class="Delimiter">(</span>*b<span class="Delimiter">.</span>type < *a<span class="Delimiter">.</span>type<span class="Delimiter">));</span> +<span class="Delimiter">}</span> +<span class="Normal">void</span> test_compare_list_with_smaller_left_but_larger_right<span class="Delimiter">()</span> <span class="Delimiter">{</span> + reagent a<span class="Delimiter">(</span><span class="Constant">"a:address:number"</span><span class="Delimiter">),</span> b<span class="Delimiter">(</span><span class="Constant">"b:character:array"</span><span class="Delimiter">);</span> + assert<span class="Delimiter">(</span>a<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom && a<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + assert<span class="Delimiter">(</span>b<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom && b<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>*a<span class="Delimiter">.</span>type < *b<span class="Delimiter">.</span>type<span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>!<span class="Delimiter">(</span>*b<span class="Delimiter">.</span>type < *a<span class="Delimiter">.</span>type<span class="Delimiter">));</span> +<span class="Delimiter">}</span> +<span class="Normal">void</span> test_compare_list_with_smaller_left_but_larger_right_identical_types<span class="Delimiter">()</span> <span class="Delimiter">{</span> + reagent a<span class="Delimiter">(</span><span class="Constant">"a:address:boolean"</span><span class="Delimiter">),</span> b<span class="Delimiter">(</span><span class="Constant">"b:boolean:address"</span><span class="Delimiter">);</span> + assert<span class="Delimiter">(</span>a<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom && a<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + assert<span class="Delimiter">(</span>b<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom && b<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>*a<span class="Delimiter">.</span>type < *b<span class="Delimiter">.</span>type<span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>!<span class="Delimiter">(</span>*b<span class="Delimiter">.</span>type < *a<span class="Delimiter">.</span>type<span class="Delimiter">));</span> <span class="Delimiter">}</span> -string_tree::string_tree<span class="Delimiter">(</span><span class="Normal">const</span> string_tree& old<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// :value(old.value) {</span> +<span class="Delimiter">:(code)</span> +string_tree::string_tree<span class="Delimiter">(</span><span class="Normal">const</span> string_tree& old<span class="Delimiter">)</span> <span class="Delimiter">{</span> + atom = old<span class="Delimiter">.</span>atom<span class="Delimiter">;</span> value = old<span class="Delimiter">.</span>value<span class="Delimiter">;</span> left = old<span class="Delimiter">.</span>left ? <span class="Normal">new</span> string_tree<span class="Delimiter">(</span>*old<span class="Delimiter">.</span>left<span class="Delimiter">)</span> : <span class="Constant">NULL</span><span class="Delimiter">;</span> right = old<span class="Delimiter">.</span>right ? <span class="Normal">new</span> string_tree<span class="Delimiter">(</span>*old<span class="Delimiter">.</span>right<span class="Delimiter">)</span> : <span class="Constant">NULL</span><span class="Delimiter">;</span> @@ -420,6 +514,26 @@ string_tree::~string_tree<span class="Delimiter">()</span> <span class="Delimite <span class="Normal">delete</span> right<span class="Delimiter">;</span> <span class="Delimiter">}</span> +<span class="Normal">void</span> append<span class="Delimiter">(</span>type_tree*& base<span class="Delimiter">,</span> type_tree* extra<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!base<span class="Delimiter">)</span> <span class="Delimiter">{</span> + base = extra<span class="Delimiter">;</span> + <span class="Identifier">return</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + type_tree* curr = base<span class="Delimiter">;</span> + <span class="Normal">while</span> <span class="Delimiter">(</span>curr<span class="Delimiter">-></span>right<span class="Delimiter">)</span> curr = curr<span class="Delimiter">-></span>right<span class="Delimiter">;</span> + curr<span class="Delimiter">-></span>right = extra<span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> append<span class="Delimiter">(</span>string_tree*& base<span class="Delimiter">,</span> string_tree* extra<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!base<span class="Delimiter">)</span> <span class="Delimiter">{</span> + base = extra<span class="Delimiter">;</span> + <span class="Identifier">return</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + string_tree* curr = base<span class="Delimiter">;</span> + <span class="Normal">while</span> <span class="Delimiter">(</span>curr<span class="Delimiter">-></span>right<span class="Delimiter">)</span> curr = curr<span class="Delimiter">-></span>right<span class="Delimiter">;</span> + curr<span class="Delimiter">-></span>right = extra<span class="Delimiter">;</span> +<span class="Delimiter">}</span> + string slurp_until<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> <span class="Normal">char</span> delim<span class="Delimiter">)</span> <span class="Delimiter">{</span> ostringstream out<span class="Delimiter">;</span> <span class="Normal">char</span> c<span class="Delimiter">;</span> @@ -449,7 +563,7 @@ string_tree* property<span class="Delimiter">(</span><span class="Normal">const< <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Globals")</span> -<span class="Normal">const</span> string Ignore<span class="Delimiter">(</span><span class="Constant">","</span><span class="Delimiter">);</span> <span class="Comment">// commas are ignored in mu except within [] strings</span> +<span class="Normal">extern</span> <span class="Normal">const</span> string Ignore<span class="Delimiter">(</span><span class="Constant">","</span><span class="Delimiter">);</span> <span class="Comment">// commas are ignored in mu except within [] strings</span> <span class="Delimiter">:(code)</span> <span class="Normal">void</span> skip_whitespace_but_not_newline<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">while</span> <span class="Delimiter">(</span><span class="Constant">true</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -545,7 +659,7 @@ string to_string<span class="Delimiter">(</span><span class="Normal">const</span <span class="Delimiter">}</span> <span class="Comment">// special name for ignoring some products</span> -<span class="Normal">inline</span> <span class="Normal">bool</span> is_dummy<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> +<span class="Normal">bool</span> is_dummy<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> x<span class="Delimiter">.</span>name == <span class="Constant">"_"</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -558,27 +672,25 @@ string debug_string<span class="Delimiter">(</span><span class="Normal">const</s string to_string<span class="Delimiter">(</span><span class="Normal">const</span> string_tree* property<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!property<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">"()"</span><span class="Delimiter">;</span> ostringstream out<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!property<span class="Delimiter">-></span>left && !property<span class="Delimiter">-></span>right<span class="Delimiter">)</span> - <span class="Comment">// abbreviate a single-node tree to just its contents</span> - out << <span class="Constant">'"'</span> << property<span class="Delimiter">-></span>value << <span class="Constant">'"'</span><span class="Delimiter">;</span> - <span class="Normal">else</span> - dump<span class="Delimiter">(</span>property<span class="Delimiter">,</span> out<span class="Delimiter">);</span> + dump<span class="Delimiter">(</span>property<span class="Delimiter">,</span> out<span class="Delimiter">);</span> <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Normal">void</span> dump<span class="Delimiter">(</span><span class="Normal">const</span> string_tree* x<span class="Delimiter">,</span> ostream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!x<span class="Delimiter">-></span>left && !x<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> - out << x<span class="Delimiter">-></span>value<span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!x<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> + out << <span class="Constant">'"'</span> << x<span class="Delimiter">-></span>value << <span class="Constant">'"'</span><span class="Delimiter">;</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> out << <span class="Constant">'('</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">const</span> string_tree* curr = x<span class="Delimiter">;</span> curr<span class="Delimiter">;</span> curr = curr<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr != x<span class="Delimiter">)</span> out << <span class="Constant">' '</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">-></span>left<span class="Delimiter">)</span> - dump<span class="Delimiter">(</span>curr<span class="Delimiter">-></span>left<span class="Delimiter">,</span> out<span class="Delimiter">);</span> - <span class="Normal">else</span> - out << <span class="Constant">'"'</span> << curr<span class="Delimiter">-></span>value << <span class="Constant">'"'</span><span class="Delimiter">;</span> + <span class="Normal">const</span> string_tree* curr = x<span class="Delimiter">;</span> + <span class="Normal">while</span> <span class="Delimiter">(</span>curr && !curr<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> + dump<span class="Delimiter">(</span>curr<span class="Delimiter">-></span>left<span class="Delimiter">,</span> out<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">-></span>right<span class="Delimiter">)</span> out << <span class="Constant">' '</span><span class="Delimiter">;</span> + curr = curr<span class="Delimiter">-></span>right<span class="Delimiter">;</span> <span class="Delimiter">}</span> + <span class="Comment">// final right</span> + dump<span class="Delimiter">(</span>curr<span class="Delimiter">,</span> out<span class="Delimiter">);</span> out << <span class="Constant">')'</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -591,18 +703,20 @@ string to_string<span class="Delimiter">(</span><span class="Normal">const</span <span class="Delimiter">}</span> <span class="Normal">void</span> dump<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* x<span class="Delimiter">,</span> ostream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!x<span class="Delimiter">-></span>left && !x<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!x<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> dump<span class="Delimiter">(</span>x<span class="Delimiter">-></span>value<span class="Delimiter">,</span> out<span class="Delimiter">);</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> out << <span class="Constant">'('</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">const</span> type_tree* curr = x<span class="Delimiter">;</span> curr<span class="Delimiter">;</span> curr = curr<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr != x<span class="Delimiter">)</span> out << <span class="Constant">' '</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">-></span>left<span class="Delimiter">)</span> - dump<span class="Delimiter">(</span>curr<span class="Delimiter">-></span>left<span class="Delimiter">,</span> out<span class="Delimiter">);</span> - <span class="Normal">else</span> - dump<span class="Delimiter">(</span>curr<span class="Delimiter">-></span>value<span class="Delimiter">,</span> out<span class="Delimiter">);</span> + <span class="Normal">const</span> type_tree* curr = x<span class="Delimiter">;</span> + <span class="Normal">while</span> <span class="Delimiter">(</span>curr && !curr<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> + dump<span class="Delimiter">(</span>curr<span class="Delimiter">-></span>left<span class="Delimiter">,</span> out<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">-></span>right<span class="Delimiter">)</span> out << <span class="Constant">' '</span><span class="Delimiter">;</span> + curr = curr<span class="Delimiter">-></span>right<span class="Delimiter">;</span> <span class="Delimiter">}</span> + <span class="Comment">// final right</span> + dump<span class="Delimiter">(</span>curr<span class="Delimiter">,</span> out<span class="Delimiter">);</span> out << <span class="Constant">')'</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -621,19 +735,21 @@ string names_to_string<span class="Delimiter">(</span><span class="Normal">const <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> dump_names<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">,</span> ostream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>left && !type<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> - out << <span class="Constant">'"'</span> << type<span class="Delimiter">-></span>name << <span class="Constant">'"'</span><span class="Delimiter">;</span> +<span class="Normal">void</span> dump_names<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* x<span class="Delimiter">,</span> ostream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!x<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> + out << <span class="Constant">'"'</span> << x<span class="Delimiter">-></span>name << <span class="Constant">'"'</span><span class="Delimiter">;</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> out << <span class="Constant">'('</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">const</span> type_tree* curr = type<span class="Delimiter">;</span> curr<span class="Delimiter">;</span> curr = curr<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr != type<span class="Delimiter">)</span> out << <span class="Constant">' '</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">-></span>left<span class="Delimiter">)</span> - dump_names<span class="Delimiter">(</span>curr<span class="Delimiter">-></span>left<span class="Delimiter">,</span> out<span class="Delimiter">);</span> - <span class="Normal">else</span> - out << <span class="Constant">'"'</span> << curr<span class="Delimiter">-></span>name << <span class="Constant">'"'</span><span class="Delimiter">;</span> + <span class="Normal">const</span> type_tree* curr = x<span class="Delimiter">;</span> + <span class="Normal">while</span> <span class="Delimiter">(</span>curr && !curr<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> + dump_names<span class="Delimiter">(</span>curr<span class="Delimiter">-></span>left<span class="Delimiter">,</span> out<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">-></span>right<span class="Delimiter">)</span> out << <span class="Constant">' '</span><span class="Delimiter">;</span> + curr = curr<span class="Delimiter">-></span>right<span class="Delimiter">;</span> <span class="Delimiter">}</span> + <span class="Comment">// final right</span> + dump_names<span class="Delimiter">(</span>curr<span class="Delimiter">,</span> out<span class="Delimiter">);</span> out << <span class="Constant">')'</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -645,19 +761,21 @@ string names_to_string_without_quotes<span class="Delimiter">(</span><span class <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> dump_names_without_quotes<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">,</span> ostream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>left && !type<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> - out << type<span class="Delimiter">-></span>name<span class="Delimiter">;</span> +<span class="Normal">void</span> dump_names_without_quotes<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* x<span class="Delimiter">,</span> ostream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!x<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> + out << x<span class="Delimiter">-></span>name<span class="Delimiter">;</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> out << <span class="Constant">'('</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">const</span> type_tree* curr = type<span class="Delimiter">;</span> curr<span class="Delimiter">;</span> curr = curr<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr != type<span class="Delimiter">)</span> out << <span class="Constant">' '</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">-></span>left<span class="Delimiter">)</span> - dump_names_without_quotes<span class="Delimiter">(</span>curr<span class="Delimiter">-></span>left<span class="Delimiter">,</span> out<span class="Delimiter">);</span> - <span class="Normal">else</span> - out << curr<span class="Delimiter">-></span>name<span class="Delimiter">;</span> + <span class="Normal">const</span> type_tree* curr = x<span class="Delimiter">;</span> + <span class="Normal">while</span> <span class="Delimiter">(</span>curr && !curr<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> + dump_names_without_quotes<span class="Delimiter">(</span>curr<span class="Delimiter">-></span>left<span class="Delimiter">,</span> out<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">-></span>right<span class="Delimiter">)</span> out << <span class="Constant">' '</span><span class="Delimiter">;</span> + curr = curr<span class="Delimiter">-></span>right<span class="Delimiter">;</span> <span class="Delimiter">}</span> + <span class="Comment">// final right</span> + dump_names_without_quotes<span class="Delimiter">(</span>curr<span class="Delimiter">,</span> out<span class="Delimiter">);</span> out << <span class="Constant">')'</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -677,6 +795,8 @@ ostream& <span class="Normal">operator</span><<<span class="Delimiter" <span class="Identifier">return</span> os<span class="Delimiter">;</span> <span class="Delimiter">}</span> ostringstream tmp<span class="Delimiter">;</span> + <span class="Comment">// more accurate, but too slow</span> +<span class="CommentedCode">//? tmp.precision(308); // for 64-bit numbers</span> tmp << std::fixed << x<span class="Delimiter">.</span>x<span class="Delimiter">;</span> os << trim_floating_point<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>str<span class="Delimiter">());</span> <span class="Identifier">return</span> os<span class="Delimiter">;</span> @@ -684,28 +804,31 @@ ostream& <span class="Normal">operator</span><<<span class="Delimiter" string trim_floating_point<span class="Delimiter">(</span><span class="Normal">const</span> string& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">""</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>in<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="Identifier">return</span> in<span class="Delimiter">;</span> <span class="Normal">int</span> length = SIZE<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Normal">while</span> <span class="Delimiter">(</span>length > <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>at<span class="Delimiter">(</span>length-<span class="Constant">1</span><span class="Delimiter">)</span> != <span class="Constant">'0'</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> --length<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>at<span class="Delimiter">(</span>length-<span class="Constant">1</span><span class="Delimiter">)</span> == <span class="Constant">'.'</span><span class="Delimiter">)</span> --length<span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>length == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">"0"</span><span class="Delimiter">;</span> <span class="Identifier">return</span> in<span class="Delimiter">.</span>substr<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">,</span> length<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">void</span> test_trim_floating_point<span class="Delimiter">()</span> <span class="Delimiter">{</span> - CHECK_EQ<span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">,</span> trim_floating_point<span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">));</span> - CHECK_EQ<span class="Delimiter">(</span><span class="Constant">"0"</span><span class="Delimiter">,</span> trim_floating_point<span class="Delimiter">(</span><span class="Constant">"000000000"</span><span class="Delimiter">));</span> - CHECK_EQ<span class="Delimiter">(</span><span class="Constant">"1.5"</span><span class="Delimiter">,</span> trim_floating_point<span class="Delimiter">(</span><span class="Constant">"1.5000"</span><span class="Delimiter">));</span> - CHECK_EQ<span class="Delimiter">(</span><span class="Constant">"1.000001"</span><span class="Delimiter">,</span> trim_floating_point<span class="Delimiter">(</span><span class="Constant">"1.000001"</span><span class="Delimiter">));</span> - CHECK_EQ<span class="Delimiter">(</span><span class="Constant">"23"</span><span class="Delimiter">,</span> trim_floating_point<span class="Delimiter">(</span><span class="Constant">"23.000000"</span><span class="Delimiter">));</span> - CHECK_EQ<span class="Delimiter">(</span><span class="Constant">"23"</span><span class="Delimiter">,</span> trim_floating_point<span class="Delimiter">(</span><span class="Constant">"23.0"</span><span class="Delimiter">));</span> - CHECK_EQ<span class="Delimiter">(</span><span class="Constant">"23"</span><span class="Delimiter">,</span> trim_floating_point<span class="Delimiter">(</span><span class="Constant">"23."</span><span class="Delimiter">));</span> - CHECK_EQ<span class="Delimiter">(</span><span class="Constant">"23"</span><span class="Delimiter">,</span> trim_floating_point<span class="Delimiter">(</span><span class="Constant">"23"</span><span class="Delimiter">));</span> - CHECK_EQ<span class="Delimiter">(</span><span class="Constant">"3"</span><span class="Delimiter">,</span> trim_floating_point<span class="Delimiter">(</span><span class="Constant">"3.000000"</span><span class="Delimiter">));</span> - CHECK_EQ<span class="Delimiter">(</span><span class="Constant">"3"</span><span class="Delimiter">,</span> trim_floating_point<span class="Delimiter">(</span><span class="Constant">"3.0"</span><span class="Delimiter">));</span> - CHECK_EQ<span class="Delimiter">(</span><span class="Constant">"3"</span><span class="Delimiter">,</span> trim_floating_point<span class="Delimiter">(</span><span class="Constant">"3."</span><span class="Delimiter">));</span> - CHECK_EQ<span class="Delimiter">(</span><span class="Constant">"3"</span><span class="Delimiter">,</span> trim_floating_point<span class="Delimiter">(</span><span class="Constant">"3"</span><span class="Delimiter">));</span> + CHECK_EQ<span class="Delimiter">(</span>trim_floating_point<span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">),</span> <span class="Constant">""</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>trim_floating_point<span class="Delimiter">(</span><span class="Constant">".0"</span><span class="Delimiter">),</span> <span class="Constant">"0"</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>trim_floating_point<span class="Delimiter">(</span><span class="Constant">"1.5000"</span><span class="Delimiter">),</span> <span class="Constant">"1.5"</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>trim_floating_point<span class="Delimiter">(</span><span class="Constant">"1.000001"</span><span class="Delimiter">),</span> <span class="Constant">"1.000001"</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>trim_floating_point<span class="Delimiter">(</span><span class="Constant">"23.000000"</span><span class="Delimiter">),</span> <span class="Constant">"23"</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>trim_floating_point<span class="Delimiter">(</span><span class="Constant">"23.0"</span><span class="Delimiter">),</span> <span class="Constant">"23"</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>trim_floating_point<span class="Delimiter">(</span><span class="Constant">"23."</span><span class="Delimiter">),</span> <span class="Constant">"23"</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>trim_floating_point<span class="Delimiter">(</span><span class="Constant">"23"</span><span class="Delimiter">),</span> <span class="Constant">"23"</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>trim_floating_point<span class="Delimiter">(</span><span class="Constant">"230"</span><span class="Delimiter">),</span> <span class="Constant">"230"</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>trim_floating_point<span class="Delimiter">(</span><span class="Constant">"3.000000"</span><span class="Delimiter">),</span> <span class="Constant">"3"</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>trim_floating_point<span class="Delimiter">(</span><span class="Constant">"3.0"</span><span class="Delimiter">),</span> <span class="Constant">"3"</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>trim_floating_point<span class="Delimiter">(</span><span class="Constant">"3."</span><span class="Delimiter">),</span> <span class="Constant">"3"</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>trim_floating_point<span class="Delimiter">(</span><span class="Constant">"3"</span><span class="Delimiter">),</span> <span class="Constant">"3"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Includes")</span> diff --git a/html/011load.cc.html b/html/011load.cc.html index 16f666e4..0a232b80 100644 --- a/html/011load.cc.html +++ b/html/011load.cc.html @@ -192,7 +192,7 @@ string next_word<span class="Delimiter">(</span>istream& in<span class="Deli <span class="Delimiter">:(before "End Globals")</span> <span class="Comment">// word boundaries</span> -<span class="Normal">const</span> string Terminators<span class="Delimiter">(</span><span class="Constant">"(){}"</span><span class="Delimiter">);</span> +<span class="Normal">extern</span> <span class="Normal">const</span> string Terminators<span class="Delimiter">(</span><span class="Constant">"(){}"</span><span class="Delimiter">);</span> <span class="Delimiter">:(code)</span> <span class="Normal">void</span> slurp_word<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> ostream& out<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">char</span> c<span class="Delimiter">;</span> diff --git a/html/014literal_string.cc.html b/html/014literal_string.cc.html index 6aa8050a..199ac486 100644 --- a/html/014literal_string.cc.html +++ b/html/014literal_string.cc.html @@ -43,7 +43,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="Delimiter">:(scenarios load)</span> <span class="Delimiter">:(scenario string_literal)</span> def 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="Constant">1</span>:address:array:character<span class="Special"> <- </span>copy [abc def] ] <span class="traceContains">+parse: ingredient: {"abc def": "literal-string"}</span> diff --git a/html/016dilated_reagent.cc.html b/html/016dilated_reagent.cc.html index 67bf9462..60593460 100644 --- a/html/016dilated_reagent.cc.html +++ b/html/016dilated_reagent.cc.html @@ -143,17 +143,17 @@ string slurp_balanced_bracket<span class="Delimiter">(</span>istream& in<spa <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">{</span> - string_tree* value = <span class="Normal">new</span> string_tree<span class="Delimiter">(</span>next_word<span class="Delimiter">(</span>in<span class="Delimiter">));</span> - <span class="Comment">// End Parsing Reagent Type Property(value)</span> - type = new_type_tree<span class="Delimiter">(</span>value<span class="Delimiter">);</span> - <span class="Normal">delete</span> value<span class="Delimiter">;</span> + string_tree* type_names = <span class="Normal">new</span> string_tree<span class="Delimiter">(</span>next_word<span class="Delimiter">(</span>in<span class="Delimiter">));</span> + <span class="Comment">// End Parsing Dilated Reagent Type Property(type_names)</span> + type = new_type_tree<span class="Delimiter">(</span>type_names<span class="Delimiter">);</span> + <span class="Normal">delete</span> type_names<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">while</span> <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span> string key = slurp_key<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>key<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>key == <span class="Constant">"}"</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> string_tree* value = <span class="Normal">new</span> 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> + <span class="Comment">// End Parsing Dilated 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="Identifier">return</span><span class="Delimiter">;</span> diff --git a/html/017parse_tree.cc.html b/html/017parse_tree.cc.html index 015ffe60..0acbc8cc 100644 --- a/html/017parse_tree.cc.html +++ b/html/017parse_tree.cc.html @@ -35,6 +35,11 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <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="Comment">//</span> +<span class="Comment">// Type trees aren't as general as s-expressions even if they look like them:</span> +<span class="Comment">// the first element of a type tree is always an atom, and left and right</span> +<span class="Comment">// pointers of non-atoms are never NULL. All type trees are 'dotted' in lisp</span> +<span class="Comment">// parlance.</span> <span class="Delimiter">:(scenarios load)</span> <span class="Delimiter">:(scenario dilated_reagent_with_nested_brackets)</span> @@ -43,14 +48,14 @@ def main [ ] <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">:(before "End Parsing Reagent Type Property(value)")</span> +<span class="Delimiter">:(before "End Parsing Dilated Reagent Property(value)")</span> value = parse_string_tree<span class="Delimiter">(</span>value<span class="Delimiter">);</span> +<span class="Delimiter">:(before "End Parsing Dilated Reagent Type Property(type_names)")</span> +type_names = parse_string_tree<span class="Delimiter">(</span>type_names<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> + assert<span class="Delimiter">(</span>s<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> <span class="Normal">if</span> <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> <span class="Normal">delete</span> s<span class="Delimiter">;</span> @@ -77,17 +82,30 @@ string_tree* parse_string_tree<span class="Delimiter">(</span>istream& in<sp 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> - <span class="Normal">while</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="Constant">')'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - assert<span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">));</span> - *curr = <span class="Normal">new</span> string_tree<span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">);</span> + <span class="Normal">while</span> <span class="Delimiter">(</span><span class="Constant">true</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> skip_whitespace_but_not_newline<span class="Delimiter">(</span>in<span class="Delimiter">);</span> + assert<span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">));</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">')'</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> + *curr = <span class="Normal">new</span> string_tree<span class="Delimiter">(</span><span class="Constant">NULL</span><span class="Delimiter">,</span> <span class="Constant">NULL</span><span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'('</span><span class="Delimiter">)</span> <span class="Delimiter">(</span>*curr<span class="Delimiter">)-></span>left = parse_string_tree<span class="Delimiter">(</span>in<span class="Delimiter">);</span> <span class="Normal">else</span> - <span class="Delimiter">(</span>*curr<span class="Delimiter">)-></span>value = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span> + <span class="Delimiter">(</span>*curr<span class="Delimiter">)-></span>left = <span class="Normal">new</span> string_tree<span class="Delimiter">(</span>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> + assert<span class="Delimiter">(</span>*curr == <span class="Constant">NULL</span><span class="Delimiter">);</span> + <span class="Comment">// standardize the final element to always be on the right if it's an atom</span> + <span class="Comment">// (a b c) => (a b . c) in s-expression parlance</span> + string_tree* tmp = result<span class="Delimiter">;</span> + <span class="Normal">while</span> <span class="Delimiter">(</span>tmp<span class="Delimiter">-></span>right && tmp<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">)</span> tmp = tmp<span class="Delimiter">-></span>right<span class="Delimiter">;</span> + assert<span class="Delimiter">(</span>!tmp<span class="Delimiter">-></span>right<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!tmp<span class="Delimiter">-></span>right<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> + string_tree* tmp2 = tmp<span class="Delimiter">-></span>right<span class="Delimiter">;</span> + tmp<span class="Delimiter">-></span>right = tmp2<span class="Delimiter">-></span>left<span class="Delimiter">;</span> + tmp2<span class="Delimiter">-></span>left = <span class="Constant">NULL</span><span class="Delimiter">;</span> + assert<span class="Delimiter">(</span>tmp2<span class="Delimiter">-></span>right == <span class="Constant">NULL</span><span class="Delimiter">);</span> + <span class="Normal">delete</span> tmp2<span class="Delimiter">;</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> diff --git a/html/018type_abbreviations.cc.html b/html/018type_abbreviations.cc.html new file mode 100644 index 00000000..5f2ff869 --- /dev/null +++ b/html/018type_abbreviations.cc.html @@ -0,0 +1,129 @@ +<!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 - 018type_abbreviations.cc</title> +<meta name="Generator" content="Vim/7.4"> +<meta name="plugin-version" content="vim7.4_v2"> +<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-size: 12pt; font-family: monospace; color: #eeeeee; background-color: #080808; } +* { font-size: 12pt; font-size: 1em; } +.Constant { color: #00a0a0; } +.Special { color: #c00000; } +.traceContains { color: #008000; } +.cSpecial { color: #008000; } +.Comment { color: #9090ff; } +.Delimiter { color: #800080; } +.SalientComment { color: #00ffff; } +.Identifier { color: #fcb165; } +.Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +--> +</style> + +<script type='text/javascript'> +<!-- + +--> +</script> +</head> +<body> +<pre id='vimCodeElement'> +<span class="Comment">//: For convenience, make some common types shorter.</span> +<span class="Comment">//:</span> +<span class="Comment">//: a) Rewrite '&t' to 'address:t' and '@t' to 'array:type' (with the</span> +<span class="Comment">//: ability to chain any combination of the two). This is not extensible.</span> +<span class="Comment">//:</span> +<span class="Comment">//: b) Provide a facility to create new type names out of old ones.</span> + +<span class="SalientComment">//:: a) expanding '&' and '@'</span> + +<span class="Delimiter">:(scenarios load)</span> +<span class="Delimiter">:(scenario abbreviations_for_address_and_array)</span> +def main [ + f <span class="Constant">1</span>:&number <span class="Comment"># abbreviation for 'address:number'</span> + f <span class="Constant">2</span>:@number <span class="Comment"># abbreviation for 'array:number'</span> + f <span class="Constant">3</span>:&@number <span class="Comment"># combining '&' and '@'</span> + f <span class="Constant">4</span>:&&@&@number <span class="Comment"># ..any number of times</span> + f <span class="Constant">5</span>:array:&number:<span class="Constant">3</span> <span class="Comment"># abbreviations take precedence over ':'</span> + f <span class="Delimiter">{</span><span class="Constant">6</span>: <span class="Delimiter">(</span>array &number <span class="Constant">3</span><span class="Delimiter">)}</span> <span class="Comment"># support for dilated reagents and more complex parse trees</span> + f <span class="Constant">7</span>:@number:<span class="Constant">3</span> <span class="Comment"># *not* the same as array:number:3</span> +] +<span class="traceContains">+parse: ingredient: {1: ("address" "number")}</span> +<span class="traceContains">+parse: ingredient: {2: ("array" "number")}</span> +<span class="traceContains">+parse: ingredient: {3: ("address" "array" "number")}</span> +<span class="traceContains">+parse: ingredient: {4: ("address" "address" "array" "address" "array" "number")}</span> +<span class="traceContains">+parse: ingredient: {5: ("array" ("address" "number") "3")}</span> +<span class="traceContains">+parse: ingredient: {6: ("array" ("address" "number") "3")}</span> +<span class="Comment"># not what you want</span> +<span class="traceContains">+parse: ingredient: {7: (("array" "number") "3")}</span> + +<span class="Delimiter">:(scenario abbreviation_error)</span> +<span class="Special">% Hide_errors = true;</span> +def main [ + f <span class="Constant">1</span>:&&@& <span class="Comment"># abbreviations without payload</span> +] +<span class="traceContains">+error: invalid type abbreviation &&@&</span> + +<span class="Delimiter">:(before "End Parsing Reagent Type Property(type_names)")</span> +string_tree* new_type_names = replace_address_and_array_symbols<span class="Delimiter">(</span>type_names<span class="Delimiter">);</span> +<span class="Normal">delete</span> type_names<span class="Delimiter">;</span> +type_names = new_type_names<span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Parsing Dilated Reagent Type Property(type_names)")</span> +string_tree* new_type_names = replace_address_and_array_symbols<span class="Delimiter">(</span>type_names<span class="Delimiter">);</span> +<span class="Normal">delete</span> type_names<span class="Delimiter">;</span> +type_names = new_type_names<span class="Delimiter">;</span> + +<span class="Delimiter">:(code)</span> +<span class="Comment">// simple version; lots of unnecessary allocations; always creates a new pointer</span> +string_tree* replace_address_and_array_symbols<span class="Delimiter">(</span>string_tree* orig<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>orig == <span class="Constant">NULL</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>orig<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> + <span class="Identifier">return</span> replace_address_and_array_symbols<span class="Delimiter">(</span>orig<span class="Delimiter">-></span>value<span class="Delimiter">);</span> + <span class="Identifier">return</span> <span class="Normal">new</span> string_tree<span class="Delimiter">(</span>replace_address_and_array_symbols<span class="Delimiter">(</span>orig<span class="Delimiter">-></span>left<span class="Delimiter">),</span> + replace_address_and_array_symbols<span class="Delimiter">(</span>orig<span class="Delimiter">-></span>right<span class="Delimiter">));</span> +<span class="Delimiter">}</span> + +<span class="Comment">// todo: unicode</span> +string_tree* replace_address_and_array_symbols<span class="Delimiter">(</span><span class="Normal">const</span> string& type_name<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>type_name<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <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> && 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="Identifier">return</span> <span class="Normal">new</span> string_tree<span class="Delimiter">(</span>type_name<span class="Delimiter">);</span> + string_tree* result = <span class="Constant">NULL</span><span class="Delimiter">;</span> + string_tree* curr = <span class="Constant">NULL</span><span class="Delimiter">;</span> + <span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> + <span class="Normal">while</span> <span class="Delimiter">(</span>i < SIZE<span class="Delimiter">(</span>type_name<span class="Delimiter">))</span> <span class="Delimiter">{</span> + string_tree* new_node = <span class="Constant">NULL</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>type_name<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == <span class="Constant">'&'</span><span class="Delimiter">)</span> + new_node = <span class="Normal">new</span> string_tree<span class="Delimiter">(</span><span class="Constant">"address"</span><span class="Delimiter">);</span> + <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>type_name<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == <span class="Constant">'@'</span><span class="Delimiter">)</span> + new_node = <span class="Normal">new</span> string_tree<span class="Delimiter">(</span><span class="Constant">"array"</span><span class="Delimiter">);</span> + <span class="Normal">else</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>result == <span class="Constant">NULL</span><span class="Delimiter">)</span> + result = curr = <span class="Normal">new</span> string_tree<span class="Delimiter">(</span>new_node<span class="Delimiter">,</span> <span class="Constant">NULL</span><span class="Delimiter">);</span> + <span class="Normal">else</span> <span class="Delimiter">{</span> + curr<span class="Delimiter">-></span>right = <span class="Normal">new</span> string_tree<span class="Delimiter">(</span>new_node<span class="Delimiter">,</span> <span class="Constant">NULL</span><span class="Delimiter">);</span> + curr = curr<span class="Delimiter">-></span>right<span class="Delimiter">;</span> + <span class="Delimiter">}</span> + ++i<span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>i < SIZE<span class="Delimiter">(</span>type_name<span class="Delimiter">))</span> + curr<span class="Delimiter">-></span>right = <span class="Normal">new</span> string_tree<span class="Delimiter">(</span>type_name<span class="Delimiter">.</span>substr<span class="Delimiter">(</span>i<span class="Delimiter">));</span> + <span class="Normal">else</span> + raise << <span class="Constant">"invalid type abbreviation "</span> << type_name << <span class="Constant">"</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="SalientComment">//:: b) extensible type abbreviations</span> + +<span class="Delimiter">:(before "End Globals")</span> +map<string<span class="Delimiter">,</span> type_tree*> Type_abbreviations<span class="Delimiter">;</span> +</pre> +</body> +</html> +<!-- vim: set foldmethod=manual : --> diff --git a/html/020run.cc.html b/html/020run.cc.html index 31a8e9ad..bf415da3 100644 --- a/html/020run.cc.html +++ b/html/020run.cc.html @@ -149,23 +149,23 @@ map<string<span class="Delimiter">,</span> <span class="Normal">int</span>> <span class="Comment">//: We'll need to override these later as we change the definition of routine.</span> <span class="Comment">//: Important that they return referrences into the routine.</span> -<span class="Normal">inline</span> <span class="Normal">int</span>& current_step_index<span class="Delimiter">()</span> <span class="Delimiter">{</span> +<span class="Normal">int</span>& current_step_index<span class="Delimiter">()</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> Current_routine<span class="Delimiter">-></span>running_step_index<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">inline</span> <span class="Normal">const</span> string& current_recipe_name<span class="Delimiter">()</span> <span class="Delimiter">{</span> +<span class="Normal">const</span> string& current_recipe_name<span class="Delimiter">()</span> <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> -<span class="Normal">inline</span> <span class="Normal">const</span> instruction& current_instruction<span class="Delimiter">()</span> <span class="Delimiter">{</span> +<span class="Normal">const</span> instruction& current_instruction<span class="Delimiter">()</span> <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> -<span class="Normal">inline</span> <span class="Normal">bool</span> routine::completed<span class="Delimiter">()</span> <span class="Normal">const</span> <span class="Delimiter">{</span> +<span class="Normal">bool</span> routine::completed<span class="Delimiter">()</span> <span class="Normal">const</span> <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="Normal">inline</span> <span class="Normal">const</span> vector<instruction>& routine::steps<span class="Delimiter">()</span> <span class="Normal">const</span> <span class="Delimiter">{</span> +<span class="Normal">const</span> vector<instruction>& routine::steps<span class="Delimiter">()</span> <span class="Normal">const</span> <span class="Delimiter">{</span> <span class="Identifier">return</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> @@ -363,17 +363,19 @@ vector<<span class="Normal">double</span>> read_memory<span class="Delimit <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>x<span class="Delimiter">)</span> != SIZE<span class="Delimiter">(</span>data<span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">inline</span> <span class="Normal">bool</span> is_literal<span class="Delimiter">(</span><span class="Normal">const</span> reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <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> - <span class="Normal">if</span> <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="Normal">bool</span> is_literal<span class="Delimiter">(</span><span class="Normal">const</span> reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Identifier">return</span> is_literal<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">);</span> +<span class="Delimiter">}</span> +<span class="Normal">bool</span> is_literal<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <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="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Identifier">return</span> type<span class="Delimiter">-></span>value == <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">inline</span> <span class="Normal">bool</span> scalar<span class="Delimiter">(</span><span class="Normal">const</span> vector<<span class="Normal">int</span>>& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> +<span class="Normal">bool</span> scalar<span class="Delimiter">(</span><span class="Normal">const</span> vector<<span class="Normal">int</span>>& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> SIZE<span class="Delimiter">(</span>x<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">inline</span> <span class="Normal">bool</span> scalar<span class="Delimiter">(</span><span class="Normal">const</span> vector<<span class="Normal">double</span>>& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> +<span class="Normal">bool</span> scalar<span class="Delimiter">(</span><span class="Normal">const</span> vector<<span class="Normal">double</span>>& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> <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> diff --git a/html/021check_instruction.cc.html b/html/021check_instruction.cc.html index c96bd6ab..801c60f6 100644 --- a/html/021check_instruction.cc.html +++ b/html/021check_instruction.cc.html @@ -136,7 +136,6 @@ $error: <span class="Constant">0</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>from<span class="Delimiter">)</span> && is_mu_number<span class="Delimiter">(</span>to<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_boolean<span class="Delimiter">(</span>from<span class="Delimiter">)</span> && is_mu_number<span class="Delimiter">(</span>to<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_number<span class="Delimiter">(</span>from<span class="Delimiter">)</span> && is_mu_boolean<span class="Delimiter">(</span>to<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Comment">// End types_coercible Special-cases</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -150,20 +149,13 @@ $error: <span class="Constant">0</span> <span class="Comment">// allow writing 0 to any address</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>to<span class="Delimiter">))</span> <span class="Identifier">return</span> from<span class="Delimiter">.</span>name == <span class="Constant">"0"</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!to<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>to<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"boolean"</span><span class="Delimiter">))</span> - <span class="Identifier">return</span> boolean_matches_literal<span class="Delimiter">(</span>to<span class="Delimiter">,</span> from<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>to<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom && to<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"boolean"</span><span class="Delimiter">))</span> + <span class="Identifier">return</span> from<span class="Delimiter">.</span>name == <span class="Constant">"0"</span> || from<span class="Delimiter">.</span>name == <span class="Constant">"1"</span><span class="Delimiter">;</span> <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>to<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">;</span> <span class="Comment">// literals are always scalars</span> <span class="Delimiter">}</span> <span class="Identifier">return</span> types_strictly_match<span class="Delimiter">(</span>to<span class="Delimiter">,</span> from<span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">bool</span> boolean_matches_literal<span class="Delimiter">(</span><span class="Normal">const</span> reagent& to<span class="Delimiter">,</span> <span class="Normal">const</span> reagent& from<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>from<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!to<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>to<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"boolean"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Identifier">return</span> from<span class="Delimiter">.</span>name == <span class="Constant">"0"</span> || from<span class="Delimiter">.</span>name == <span class="Constant">"1"</span><span class="Delimiter">;</span> -<span class="Delimiter">}</span> - <span class="Comment">// copy arguments because later layers will want to make changes to them</span> <span class="Comment">// without perturbing the caller</span> <span class="Normal">bool</span> types_strictly_match<span class="Delimiter">(</span>reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> to<span class="Delimiter">,</span> reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> from<span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -181,10 +173,14 @@ $error: <span class="Constant">0</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> <span class="Normal">bool</span> types_strictly_match<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* to<span class="Delimiter">,</span> <span class="Normal">const</span> type_tree* from<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!to<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!from<span class="Delimiter">)</span> <span class="Identifier">return</span> to<span class="Delimiter">-></span>value == <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>from<span class="Delimiter">-></span>value == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Identifier">return</span> from<span class="Delimiter">-></span>name == to<span class="Delimiter">-></span>name<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>to<span class="Delimiter">-></span>value != from<span class="Delimiter">-></span>value<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>from == to<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!from<span class="Delimiter">)</span> <span class="Identifier">return</span> to<span class="Delimiter">-></span>atom && to<span class="Delimiter">-></span>value == <span class="Constant">0</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>to<span class="Delimiter">-></span>atom && !from<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> from<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom && from<span class="Delimiter">-></span>left<span class="Delimiter">-></span>name == to<span class="Delimiter">-></span>name<span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>from<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!to<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>from<span class="Delimiter">-></span>value == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Identifier">return</span> from<span class="Delimiter">-></span>name == to<span class="Delimiter">-></span>name<span class="Delimiter">;</span> + <span class="Identifier">return</span> from<span class="Delimiter">-></span>value == to<span class="Delimiter">-></span>value<span class="Delimiter">;</span> + <span class="Delimiter">}</span> <span class="Identifier">return</span> types_strictly_match<span class="Delimiter">(</span>to<span class="Delimiter">-></span>left<span class="Delimiter">,</span> from<span class="Delimiter">-></span>left<span class="Delimiter">)</span> && types_strictly_match<span class="Delimiter">(</span>to<span class="Delimiter">-></span>right<span class="Delimiter">,</span> from<span class="Delimiter">-></span>right<span class="Delimiter">);</span> <span class="Delimiter">}</span> @@ -206,30 +202,43 @@ $error: <span class="Constant">0</span> <span class="Normal">bool</span> is_mu_array<span class="Delimiter">(</span>reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> r<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// End Preprocess is_mu_array(reagent r)</span> - <span class="Normal">if</span> <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> - <span class="Normal">if</span> <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="Identifier">return</span> is_mu_array<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">bool</span> is_mu_array<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <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="Normal">if</span> <span class="Delimiter">(</span>is_literal<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="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + assert<span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + <span class="Identifier">return</span> type<span class="Delimiter">-></span>left<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> <span class="Normal">bool</span> is_mu_address<span class="Delimiter">(</span>reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> r<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// End Preprocess is_mu_address(reagent r)</span> - <span class="Normal">if</span> <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> - <span class="Normal">if</span> <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="Identifier">return</span> is_mu_address<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">bool</span> is_mu_address<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <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="Normal">if</span> <span class="Delimiter">(</span>is_literal<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="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + assert<span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + <span class="Identifier">return</span> type<span class="Delimiter">-></span>left<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> <span class="Normal">bool</span> is_mu_boolean<span class="Delimiter">(</span>reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> r<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// End Preprocess is_mu_boolean(reagent r)</span> <span class="Normal">if</span> <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> <span class="Normal">if</span> <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="Normal">if</span> <span class="Delimiter">(</span>!r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Identifier">return</span> r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"boolean"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">bool</span> is_mu_number<span class="Delimiter">(</span>reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> r<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// End Preprocess is_mu_number(reagent r)</span> <span class="Normal">if</span> <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> + <span class="Normal">if</span> <span class="Delimiter">(</span>!r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>r<span class="Delimiter">))</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <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> <span class="Identifier">return</span> r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name == <span class="Constant">"literal-fractional-number"</span> || r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name == <span class="Constant">"literal"</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -239,17 +248,26 @@ $error: <span class="Constant">0</span> <span class="Normal">bool</span> is_mu_character<span class="Delimiter">(</span>reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> r<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// End Preprocess is_mu_character(reagent r)</span> - <span class="Normal">if</span> <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> - <span class="Normal">if</span> <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">"character"</span><span class="Delimiter">);</span> + <span class="Identifier">return</span> is_mu_character<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">);</span> +<span class="Delimiter">}</span> +<span class="Normal">bool</span> is_mu_character<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <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="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<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="Identifier">return</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="Delimiter">}</span> <span class="Normal">bool</span> is_mu_scalar<span class="Delimiter">(</span>reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> r<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <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> - <span class="Normal">if</span> <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>type || r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name != <span class="Constant">"literal-string"</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <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="Identifier">return</span> is_mu_scalar<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">bool</span> is_mu_scalar<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <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="Normal">if</span> <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>type<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>type<span class="Delimiter">))</span> + <span class="Identifier">return</span> type<span class="Delimiter">-></span>name != <span class="Constant">"literal-string"</span><span class="Delimiter">;</span> + <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>type<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> </pre> </body> diff --git a/html/026call.cc.html b/html/026call.cc.html index 6acdb8a6..ca151665 100644 --- a/html/026call.cc.html +++ b/html/026call.cc.html @@ -103,29 +103,29 @@ routine::routine<span class="Delimiter">(</span>recipe_ordinal r<span class="Del <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -<span class="Normal">inline</span> call& current_call<span class="Delimiter">()</span> <span class="Delimiter">{</span> +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 int& current_step_index()")</span> -<span class="Normal">inline</span> <span class="Normal">int</span>& current_step_index<span class="Delimiter">()</span> <span class="Delimiter">{</span> +<span class="Delimiter">:(replace{} "int& current_step_index()")</span> +<span class="Normal">int</span>& 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_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> -<span class="Normal">inline</span> <span class="Normal">const</span> string& current_recipe_name<span class="Delimiter">()</span> <span class="Delimiter">{</span> +<span class="Delimiter">:(replace{} "const string& current_recipe_name()")</span> +<span class="Normal">const</span> 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> 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> -<span class="Normal">inline</span> <span class="Normal">const</span> instruction& current_instruction<span class="Delimiter">()</span> <span class="Delimiter">{</span> +<span class="Delimiter">:(replace{} "const instruction& current_instruction()")</span> +<span class="Normal">const</span> 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> to_instruction<span class="Delimiter">(</span>current_call<span class="Delimiter">());</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -<span class="Normal">inline</span> <span class="Normal">const</span> instruction& to_instruction<span class="Delimiter">(</span><span class="Normal">const</span> call& call<span class="Delimiter">)</span> <span class="Delimiter">{</span> +<span class="Normal">const</span> instruction& to_instruction<span class="Delimiter">(</span><span class="Normal">const</span> 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> @@ -174,13 +174,13 @@ def main [ <span class="SalientComment">//:: finally, we need to fix the termination conditions for the run loop</span> -<span class="Delimiter">:(replace{} "inline bool routine::completed() const")</span> -<span class="Normal">inline</span> <span class="Normal">bool</span> routine::completed<span class="Delimiter">()</span> <span class="Normal">const</span> <span class="Delimiter">{</span> +<span class="Delimiter">:(replace{} "bool routine::completed() const")</span> +<span class="Normal">bool</span> routine::completed<span class="Delimiter">()</span> <span class="Normal">const</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> calls<span class="Delimiter">.</span>empty<span class="Delimiter">();</span> <span class="Delimiter">}</span> -<span class="Delimiter">:(replace{} "inline const vector<instruction>& routine::steps() const")</span> -<span class="Normal">inline</span> <span class="Normal">const</span> vector<instruction>& routine::steps<span class="Delimiter">()</span> <span class="Normal">const</span> <span class="Delimiter">{</span> +<span class="Delimiter">:(replace{} "const vector<instruction>& routine::steps() const")</span> +<span class="Normal">const</span> vector<instruction>& routine::steps<span class="Delimiter">()</span> <span class="Normal">const</span> <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>!calls<span class="Delimiter">.</span>empty<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> diff --git a/html/027call_ingredient.cc.html b/html/027call_ingredient.cc.html index 0fc668d6..07ad869d 100644 --- a/html/027call_ingredient.cc.html +++ b/html/027call_ingredient.cc.html @@ -210,12 +210,16 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Normal">bool</span> is_mu_string<span class="Delimiter">(</span>reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> x<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// End Preprocess is_mu_string(reagent x)</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> + && !x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom + && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom + && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<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>atom + && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom + && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>left<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>atom + && 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> <span class="Delimiter">}</span> </pre> </body> diff --git a/html/028call_reply.cc.html b/html/028call_reply.cc.html index b118e6aa..4c145b0e 100644 --- a/html/028call_reply.cc.html +++ b/html/028call_reply.cc.html @@ -105,7 +105,7 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa <span class="Comment">// End Check RETURN Copy(lhs, rhs)</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!types_coercible<span class="Delimiter">(</span>rhs<span class="Delimiter">,</span> lhs<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise << maybe<span class="Delimiter">(</span>callee<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << reply_inst<span class="Delimiter">.</span>name << <span class="Constant">" ingredient '"</span> << lhs<span class="Delimiter">.</span>original_string << <span class="Constant">"' can't be saved in '"</span> << rhs<span class="Delimiter">.</span>original_string << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> - raise << <span class="Constant">" ("</span> << to_string<span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="Constant">" vs "</span> << to_string<span class="Delimiter">(</span>rhs<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="Constant">")</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + raise << <span class="Constant">" ['"</span> << to_string<span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="Constant">"' vs '"</span> << to_string<span class="Delimiter">(</span>rhs<span class="Delimiter">.</span>type<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_reply_check<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> @@ -114,7 +114,7 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>reply_inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> <span class="Constant">"same-as-ingredient"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> 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> - <span class="Normal">if</span> <span class="Delimiter">(</span>!tmp || tmp<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!tmp || !tmp<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"'same-as-ingredient' metadata should take exactly one value in '"</span> << to_original_string<span class="Delimiter">(</span>reply_inst<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_reply_check<span class="Delimiter">;</span> <span class="Delimiter">}</span> diff --git a/html/030container.cc.html b/html/030container.cc.html index 1ddba97e..cb41b4fd 100644 --- a/html/030container.cc.html +++ b/html/030container.cc.html @@ -37,7 +37,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="Comment">//: Containers contain a fixed number of elements of different types.</span> <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="Comment">//: We'll use this container as a running example in scenarios below.</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> <span class="Comment">// initialize</span> get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> point<span class="Delimiter">).</span>kind = CONTAINER<span class="Delimiter">;</span> @@ -49,8 +49,8 @@ get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> point<sp <span class="Comment">//: numbers, no matter how large they are.</span> <span class="Comment">//: Tests in this layer often explicitly set up 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 errors.</span> +<span class="Comment">//: container. Don't do this in general. I'm tagging exceptions with /unsafe to</span> +<span class="Comment">//: skip later checks.</span> <span class="Delimiter">:(scenario copy_multiple_locations)</span> def main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> @@ -69,8 +69,8 @@ def main [ <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> +<span class="Comment">// A more complex example container, containing another container as one of</span> +<span class="Comment">// its elements.</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> <span class="Comment">// initialize</span> get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> point_number<span class="Delimiter">).</span>kind = CONTAINER<span class="Delimiter">;</span> @@ -184,31 +184,41 @@ atexit<span class="Delimiter">(</span>clear_container_metadata<span class="Delim <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>size<span class="Delimiter">)</span> <span class="Identifier">return</span> r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>size<span class="Delimiter">;</span> <span class="Delimiter">:(before "End size_of(type) Cases")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>value == -<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">// error value, but we'll raise it elsewhere</span> -<span class="Normal">if</span> <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="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>value == -<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">// error value, but we'll raise it elsewhere</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">if</span> <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> - raise << <span class="Constant">"no such type "</span> << type<span class="Delimiter">-></span>value << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> +<span class="Normal">const</span> type_tree* root = root_type<span class="Delimiter">(</span>type<span class="Delimiter">);</span> +<span class="Normal">if</span> <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root<span class="Delimiter">-></span>value<span class="Delimiter">))</span> <span class="Delimiter">{</span> + raise << <span class="Constant">"no such type "</span> << root<span class="Delimiter">-></span>value << <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> -type_info t = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> +type_info t = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root<span class="Delimiter">-></span>value<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>t<span class="Delimiter">.</span>kind == CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// Compute size_of Container</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> type<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">1</span><span class="Delimiter">;</span> <span class="Comment">// error raised elsewhere</span> <span class="Identifier">return</span> get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> type<span class="Delimiter">).</span>size<span class="Delimiter">;</span> <span class="Delimiter">}</span> +<span class="Delimiter">:(code)</span> +<span class="Normal">const</span> type_tree* root_type<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* t<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">const</span> type_tree* result = t<span class="Delimiter">-></span>atom ? t : t<span class="Delimiter">-></span>left<span class="Delimiter">;</span> + assert<span class="Delimiter">(</span>result<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + <span class="Identifier">return</span> result<span class="Delimiter">;</span> +<span class="Delimiter">}</span> + <span class="Comment">//: precompute Container_metadata before we need size_of</span> <span class="Comment">//: also store a copy in each reagent in each instruction in each recipe</span> -<span class="Delimiter">:(after "Begin Instruction Modifying Transforms") // needs to happen before transform_names, therefore after "End Type Modifying Transforms" below</span> -<span class="Delimiter">Transform.push_back(compute_container_sizes)</span><span class="Delimiter">;</span> +<span class="Delimiter">:(after "Begin Instruction Modifying Transforms")</span> <span class="Comment">// needs to happen before transform_names, therefore after Type Modifying Transforms below</span> +Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>compute_container_sizes<span class="Delimiter">);</span> <span class="Delimiter">:(code)</span> <span class="Normal">void</span> compute_container_sizes<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span> recipe& caller = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span> + 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">"--- compute container sizes for "</span> << caller<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> instruction& inst = caller<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> + 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 container sizes for "</span> << to_string<span class="Delimiter">(</span>inst<span class="Delimiter">)</span> << end<span class="Delimiter">();</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> compute_container_sizes<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="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> @@ -220,33 +230,56 @@ type_info t = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</ <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>r<span class="Delimiter">)</span> || is_dummy<span class="Delimiter">(</span>r<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> reagent rcopy = r<span class="Delimiter">;</span> <span class="Comment">// Compute Container Size(reagent rcopy)</span> - set<type_ordinal> pending_metadata<span class="Delimiter">;</span> + set<type_tree> pending_metadata<span class="Delimiter">;</span> <span class="Comment">// might actually be faster to just convert to string rather than compare type_tree directly; so far the difference is negligible</span> compute_container_sizes<span class="Delimiter">(</span>rcopy<span class="Delimiter">.</span>type<span class="Delimiter">,</span> pending_metadata<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> rcopy<span class="Delimiter">.</span>type<span class="Delimiter">))</span> r<span class="Delimiter">.</span>metadata = get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> rcopy<span class="Delimiter">.</span>type<span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> compute_container_sizes<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">,</span> set<type_ordinal>& pending_metadata<span class="Delimiter">)</span> <span class="Delimiter">{</span> +<span class="Normal">void</span> compute_container_sizes<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">,</span> set<type_tree>& pending_metadata<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>pending_metadata<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>value<span class="Delimiter">)</span> pending_metadata<span class="Delimiter">.</span>insert<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> << <span class="Constant">"compute container sizes for "</span> << to_string<span class="Delimiter">(</span>type<span class="Delimiter">)</span> << end<span class="Delimiter">();</span> <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> type<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">)</span> compute_container_sizes<span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">,</span> pending_metadata<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">)</span> compute_container_sizes<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">,</span> pending_metadata<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>pending_metadata<span class="Delimiter">,</span> *type<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + pending_metadata<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>*type<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> + assert<span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>name == <span class="Constant">"address"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + compute_container_sizes<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">,</span> pending_metadata<span class="Delimiter">);</span> + <span class="Delimiter">}</span> + <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>name == <span class="Constant">"array"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">const</span> type_tree* element_type = type<span class="Delimiter">-></span>right<span class="Delimiter">;</span> + <span class="Comment">// hack: support both array:number:3 and array:address:number</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!element_type<span class="Delimiter">-></span>atom && element_type<span class="Delimiter">-></span>right && element_type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>atom && is_integer<span class="Delimiter">(</span>element_type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">))</span> + element_type = element_type<span class="Delimiter">-></span>left<span class="Delimiter">;</span> + compute_container_sizes<span class="Delimiter">(</span>element_type<span class="Delimiter">,</span> pending_metadata<span class="Delimiter">);</span> + <span class="Delimiter">}</span> + <span class="Comment">// End compute_container_sizes Non-atom Cases</span> + <span class="Identifier">return</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + assert<span class="Delimiter">(</span>type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> <span class="Normal">if</span> <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="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// error raised elsewhere</span> type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>info<span class="Delimiter">.</span>kind == CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span> - container_metadata metadata<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> element = info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> - <span class="Comment">// Compute Container Size(element)</span> - compute_container_sizes<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">,</span> pending_metadata<span class="Delimiter">);</span> - metadata<span class="Delimiter">.</span>offset<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>metadata<span class="Delimiter">.</span>size<span class="Delimiter">);</span> <span class="Comment">// save previous size as offset</span> - metadata<span class="Delimiter">.</span>size += size_of<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">);</span> - <span class="Delimiter">}</span> - Container_metadata<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<type_tree*<span class="Delimiter">,</span> container_metadata><span class="Delimiter">(</span><span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*type<span class="Delimiter">),</span> metadata<span class="Delimiter">));</span> + compute_container_sizes<span class="Delimiter">(</span>info<span class="Delimiter">,</span> type<span class="Delimiter">,</span> pending_metadata<span class="Delimiter">);</span> + <span class="Delimiter">}</span> + <span class="Comment">// End compute_container_sizes Atom Cases</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> compute_container_sizes<span class="Delimiter">(</span><span class="Normal">const</span> type_info& container_info<span class="Delimiter">,</span> <span class="Normal">const</span> type_tree* full_type<span class="Delimiter">,</span> set<type_tree>& pending_metadata<span class="Delimiter">)</span> <span class="Delimiter">{</span> + assert<span class="Delimiter">(</span>container_info<span class="Delimiter">.</span>kind == CONTAINER<span class="Delimiter">);</span> + <span class="Comment">// size of a container is the sum of the sizes of its element</span> + <span class="Comment">// (So it can only contain arrays if they're static and include their</span> + <span class="Comment">// length in the type.)</span> + container_metadata metadata<span class="Delimiter">;</span> + <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>container_info<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> element = container_info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> + <span class="Comment">// Compute Container Size(element, full_type)</span> + compute_container_sizes<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">,</span> pending_metadata<span class="Delimiter">);</span> + metadata<span class="Delimiter">.</span>offset<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>metadata<span class="Delimiter">.</span>size<span class="Delimiter">);</span> <span class="Comment">// save previous size as offset</span> + metadata<span class="Delimiter">.</span>size += size_of<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">);</span> <span class="Delimiter">}</span> - <span class="Comment">// End compute_container_sizes Cases</span> + Container_metadata<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<type_tree*<span class="Delimiter">,</span> container_metadata><span class="Delimiter">(</span><span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*full_type<span class="Delimiter">),</span> metadata<span class="Delimiter">));</span> <span class="Delimiter">}</span> container_metadata& get<span class="Delimiter">(</span>vector<pair<type_tree*<span class="Delimiter">,</span> container_metadata> >& all<span class="Delimiter">,</span> <span class="Normal">const</span> type_tree* key<span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -255,7 +288,7 @@ container_metadata& get<span class="Delimiter">(</span>vector<pair<typ <span class="Identifier">return</span> all<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">;</span> <span class="Delimiter">}</span> tb_shutdown<span class="Delimiter">();</span> - raise << <span class="Constant">"unknown size for type "</span> << to_string<span class="Delimiter">(</span>key<span class="Delimiter">)</span> << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> + raise << <span class="Constant">"unknown size for type '"</span> << to_string<span class="Delimiter">(</span>key<span class="Delimiter">)</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> assert<span class="Delimiter">(</span><span class="Constant">false</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> @@ -270,7 +303,8 @@ container_metadata& get<span class="Delimiter">(</span>vector<pair<typ <span class="Normal">bool</span> matches<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* a<span class="Delimiter">,</span> <span class="Normal">const</span> type_tree* b<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <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="Normal">if</span> <span class="Delimiter">(</span>!a || !b<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>a<span class="Delimiter">-></span>value != b<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="Normal">if</span> <span class="Delimiter">(</span>a<span class="Delimiter">-></span>atom != b<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>a<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> a<span class="Delimiter">-></span>value == b<span class="Delimiter">-></span>value<span class="Delimiter">;</span> <span class="Identifier">return</span> matches<span class="Delimiter">(</span>a<span class="Delimiter">-></span>left<span class="Delimiter">,</span> b<span class="Delimiter">-></span>left<span class="Delimiter">)</span> && matches<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> @@ -283,7 +317,122 @@ def main [ ] <span class="traceContains">+app: foo: 34 35 36</span> +<span class="Comment">//: for the following unit tests we'll do the work of the transform by hand</span> + +<span class="Delimiter">:(before "End Unit Tests")</span> +<span class="Normal">void</span> test_container_sizes<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Comment">// a container we don't have the size for</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:point"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Comment">// scan</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// the reagent we scanned knows its size</span> + CHECK_EQ<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>size<span class="Delimiter">,</span> <span class="Constant">2</span><span class="Delimiter">);</span> + <span class="Comment">// the global table also knows its size</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + CHECK_EQ<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">).</span>size<span class="Delimiter">,</span> <span class="Constant">2</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_sizes_nested<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Comment">// a container we don't have the size for</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:point-number"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Comment">// scan</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// the reagent we scanned knows its size</span> + CHECK_EQ<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>size<span class="Delimiter">,</span> <span class="Constant">3</span><span class="Delimiter">);</span> + <span class="Comment">// the global table also knows its size</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + CHECK_EQ<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">).</span>size<span class="Delimiter">,</span> <span class="Constant">3</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_sizes_recursive<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Comment">// define a container containing an address to itself</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" y:address:foo</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> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:foo"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>size<span class="Delimiter">,</span> <span class="Constant">2</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_sizes_from_address<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Comment">// a container we don't have the size for</span> + reagent container<span class="Delimiter">(</span><span class="Constant">"x:point"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Comment">// scanning an address to the container precomputes the size of the container</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:address:point"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + CHECK_EQ<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">).</span>size<span class="Delimiter">,</span> <span class="Constant">2</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_sizes_from_array<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Comment">// a container we don't have the size for</span> + reagent container<span class="Delimiter">(</span><span class="Constant">"x:point"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Comment">// scanning an array of the container precomputes the size of the container</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:array:point"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + CHECK_EQ<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">).</span>size<span class="Delimiter">,</span> <span class="Constant">2</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_sizes_from_address_to_array<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Comment">// a container we don't have the size for</span> + reagent container<span class="Delimiter">(</span><span class="Constant">"x:point"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Comment">// scanning an address to an array of the container precomputes the size of the container</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:address:array:point"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + CHECK_EQ<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">).</span>size<span class="Delimiter">,</span> <span class="Constant">2</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_sizes_from_static_array<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Comment">// a container we don't have the size for</span> + reagent container<span class="Delimiter">(</span><span class="Constant">"x:point"</span><span class="Delimiter">);</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// scanning an address to an array of the container precomputes the size of the container</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:array:point:10"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + CHECK_EQ<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">).</span>size<span class="Delimiter">,</span> <span class="Constant">2</span><span class="Delimiter">);</span> + <span class="Comment">// no non-container types precomputed</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_sizes_from_address_to_static_array<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Comment">// a container we don't have the size for</span> + reagent container<span class="Delimiter">(</span><span class="Constant">"x:point"</span><span class="Delimiter">);</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// scanning an address to an array of the container precomputes the size of the container</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:address:array:point:10"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + CHECK_EQ<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">).</span>size<span class="Delimiter">,</span> <span class="Constant">2</span><span class="Delimiter">);</span> + <span class="Comment">// no non-container types precomputed</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_sizes_from_repeated_address_and_array_types<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Comment">// a container we don't have the size for</span> + reagent container<span class="Delimiter">(</span><span class="Constant">"x:point"</span><span class="Delimiter">);</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// scanning repeated address and array types modifying the container precomputes the size of the container</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:address:array:address:array:point:10"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + CHECK_EQ<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">).</span>size<span class="Delimiter">,</span> <span class="Constant">2</span><span class="Delimiter">);</span> + <span class="Comment">// no non-container types precomputed</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + <span class="SalientComment">//:: To access elements of a container, use 'get'</span> +<span class="Comment">//: 'get' takes a 'base' container and an 'offset' into it and returns the</span> +<span class="Comment">//: appropriate element of the container value.</span> + <span class="Delimiter">:(scenario get)</span> def main [ <span class="Constant">12</span>:number<span class="Special"> <- </span>copy <span class="Constant">34</span> @@ -304,11 +453,15 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> 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> - <span class="Normal">if</span> <span class="Delimiter">(</span>!base<span class="Delimiter">.</span>type || !base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value || !contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">)</span> || 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> + <span class="Normal">if</span> <span class="Delimiter">(</span>!base<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << 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="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Normal">const</span> type_tree* base_root_type = base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom ? base<span class="Delimiter">.</span>type : base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!base_root_type<span class="Delimiter">-></span>atom || base_root_type<span class="Delimiter">-></span>value == <span class="Constant">0</span> || !contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_root_type<span class="Delimiter">-></span>value<span class="Delimiter">)</span> || get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_root_type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>kind != CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << 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="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> <span class="Normal">const</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> <span class="Normal">if</span> <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 << 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="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> @@ -319,14 +472,14 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span offset_value = to_integer<span class="Delimiter">(</span>offset<span class="Delimiter">.</span>name<span class="Delimiter">);</span> <span class="Normal">else</span> offset_value = offset<span class="Delimiter">.</span>value<span class="Delimiter">;</span> - <span class="Normal">if</span> <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 << 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="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Normal">if</span> <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_root_type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>elements<span class="Delimiter">))</span> <span class="Delimiter">{</span> + raise << 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_root_type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>name << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <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<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> 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> - <span class="Normal">const</span> reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> element = element_type<span class="Delimiter">(</span>base<span class="Delimiter">.</span>type<span class="Delimiter">,</span> offset_value<span class="Delimiter">);</span> + <span class="Normal">const</span> reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> element = element_type<span class="Delimiter">(</span>base<span class="Delimiter">.</span>type<span class="Delimiter">,</span> offset_value<span class="Delimiter">);</span> <span class="Comment">// not just base_root_type because later layers will introduce compound types</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!types_coercible<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise << maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> << <span class="Constant">"'get "</span> << base<span class="Delimiter">.</span>original_string << <span class="Constant">", "</span> << offset<span class="Delimiter">.</span>original_string << <span class="Constant">"' should write to "</span> << names_to_string_without_quotes<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="Constant">" but '"</span> << product<span class="Delimiter">.</span>name << <span class="Constant">"' has type "</span> << names_to_string_without_quotes<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> @@ -342,13 +495,13 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span raise << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"tried to access location 0 in '"</span> << to_original_string<span class="Delimiter">(</span>current_instruction<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> + <span class="Normal">const</span> type_tree* base_root_type = root_type<span class="Delimiter">(</span>base<span class="Delimiter">.</span>type<span class="Delimiter">);</span> <span class="Normal">int</span> offset = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>offset < <span class="Constant">0</span> || offset >= SIZE<span class="Delimiter">(</span>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> + <span class="Normal">if</span> <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_root_type<span class="Delimiter">-></span>value<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> assert<span class="Delimiter">(</span>base<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>size<span class="Delimiter">);</span> <span class="Normal">int</span> src = base_address + base<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>offset<span class="Delimiter">.</span>at<span class="Delimiter">(</span>offset<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<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> element = element_type<span class="Delimiter">(</span>base<span class="Delimiter">.</span>type<span class="Delimiter">,</span> offset<span class="Delimiter">);</span> + reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> element = element_type<span class="Delimiter">(</span>base<span class="Delimiter">.</span>type<span class="Delimiter">,</span> offset<span class="Delimiter">);</span> <span class="Comment">// not just base_root_type because later layers will introduce compound types</span> element<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>src<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> << names_to_string<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << end<span class="Delimiter">();</span> <span class="Comment">// Read element</span> @@ -359,9 +512,10 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">:(code)</span> <span class="Normal">const</span> reagent element_type<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">,</span> <span class="Normal">int</span> 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> 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> type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>name<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> - <span class="Normal">const</span> type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> + <span class="Normal">const</span> type_tree* root = root_type<span class="Delimiter">(</span>type<span class="Delimiter">);</span> + assert<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root<span class="Delimiter">-></span>value<span class="Delimiter">));</span> + assert<span class="Delimiter">(</span>!get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root<span class="Delimiter">-></span>value<span class="Delimiter">).</span>name<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> + <span class="Normal">const</span> type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root<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> <span class="Normal">if</span> <span class="Delimiter">(</span>offset_value >= SIZE<span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">))</span> <span class="Identifier">return</span> reagent<span class="Delimiter">();</span> <span class="Comment">// error handled elsewhere</span> reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> element = info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>offset_value<span class="Delimiter">);</span> @@ -442,11 +596,15 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> 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 PUT base in Check</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!base<span class="Delimiter">.</span>type || !base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value || !contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">)</span> || 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> + <span class="Normal">if</span> <span class="Delimiter">(</span>!base<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << 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 'put' 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="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Normal">const</span> type_tree* base_root_type = base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom ? base<span class="Delimiter">.</span>type : base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!base_root_type<span class="Delimiter">-></span>atom || base_root_type<span class="Delimiter">-></span>value == <span class="Constant">0</span> || !contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_root_type<span class="Delimiter">-></span>value<span class="Delimiter">)</span> || get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_root_type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>kind != CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << 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 'put' 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="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> reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> 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> <span class="Comment">// Update PUT offset in Check</span> <span class="Normal">if</span> <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> @@ -456,8 +614,8 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Normal">int</span> offset_value = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Normal">if</span> <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> - <span class="Normal">if</span> <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 << 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="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Normal">if</span> <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_root_type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>elements<span class="Delimiter">))</span> <span class="Delimiter">{</span> + raise << 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_root_type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>name << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> @@ -465,7 +623,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span offset_value = offset<span class="Delimiter">.</span>value<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">const</span> reagent& value = 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="Normal">const</span> reagent& element = element_type<span class="Delimiter">(</span>base<span class="Delimiter">.</span>type<span class="Delimiter">,</span> offset_value<span class="Delimiter">);</span> + <span class="Normal">const</span> reagent& element = element_type<span class="Delimiter">(</span>base<span class="Delimiter">.</span>type<span class="Delimiter">,</span> offset_value<span class="Delimiter">);</span> <span class="Comment">// not just base_root_type because later layers will introduce compound types</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!types_coercible<span class="Delimiter">(</span>element<span class="Delimiter">,</span> value<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise << 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">"'put "</span> << base<span class="Delimiter">.</span>original_string << <span class="Constant">", "</span> << offset<span class="Delimiter">.</span>original_string << <span class="Constant">"' should write to "</span> << names_to_string_without_quotes<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">)</span> << <span class="Constant">" but '"</span> << value<span class="Delimiter">.</span>name << <span class="Constant">"' has type "</span> << names_to_string_without_quotes<span class="Delimiter">(</span>value<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> @@ -487,9 +645,9 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span raise << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"tried to access location 0 in '"</span> << to_original_string<span class="Delimiter">(</span>current_instruction<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> + <span class="Normal">const</span> type_tree* base_root_type = root_type<span class="Delimiter">(</span>base<span class="Delimiter">.</span>type<span class="Delimiter">);</span> <span class="Normal">int</span> offset = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>offset < <span class="Constant">0</span> || offset >= SIZE<span class="Delimiter">(</span>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> + <span class="Normal">if</span> <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_root_type<span class="Delimiter">-></span>value<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> <span class="Normal">int</span> address = base_address + base<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>offset<span class="Delimiter">.</span>at<span class="Delimiter">(</span>offset<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 to is "</span> << address << end<span class="Delimiter">();</span> <span class="Comment">// optimization: directly write the element rather than updating 'product'</span> @@ -623,21 +781,23 @@ Num_calls_to_transform_all_at_first_definition = -<span class="Constant">1</span <span class="Normal">void</span> replace_unknown_types_with_unique_ordinals<span class="Delimiter">(</span>type_tree* type<span class="Delimiter">,</span> <span class="Normal">const</span> type_info& info<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>name<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type<span class="Delimiter">-></span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span> - type<span class="Delimiter">-></span>value = get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type<span class="Delimiter">-></span>name<span class="Delimiter">);</span> - <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>type<span class="Delimiter">-></span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Comment">// sometimes types will contain non-type tags, like numbers for the size of an array</span> - type<span class="Delimiter">-></span>value = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Delimiter">}</span> - <span class="Comment">// End insert_container Special-cases</span> - <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>name != <span class="Constant">"->"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// used in recipe types</span> - put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> Next_type_ordinal++<span class="Delimiter">);</span> - type<span class="Delimiter">-></span>value = get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type<span class="Delimiter">-></span>name<span class="Delimiter">);</span> - <span class="Delimiter">}</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> + replace_unknown_types_with_unique_ordinals<span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">,</span> info<span class="Delimiter">);</span> + replace_unknown_types_with_unique_ordinals<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">,</span> info<span class="Delimiter">);</span> + <span class="Identifier">return</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + assert<span class="Delimiter">(</span>!type<span class="Delimiter">-></span>name<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type<span class="Delimiter">-></span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span> + type<span class="Delimiter">-></span>value = get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type<span class="Delimiter">-></span>name<span class="Delimiter">);</span> + <span class="Delimiter">}</span> + <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>type<span class="Delimiter">-></span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Comment">// sometimes types will contain non-type tags, like numbers for the size of an array</span> + type<span class="Delimiter">-></span>value = <span class="Constant">0</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Comment">// End insert_container Special-cases</span> + <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>name != <span class="Constant">"->"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// used in recipe types</span> + put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> Next_type_ordinal++<span class="Delimiter">);</span> + type<span class="Delimiter">-></span>value = get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type<span class="Delimiter">-></span>name<span class="Delimiter">);</span> <span class="Delimiter">}</span> - replace_unknown_types_with_unique_ordinals<span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">,</span> info<span class="Delimiter">);</span> - replace_unknown_types_with_unique_ordinals<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">,</span> info<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">void</span> skip_bracket<span class="Delimiter">(</span>istream& in<span class="Delimiter">,</span> string message<span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -718,6 +878,11 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa <span class="Normal">void</span> check_or_set_invalid_types<span class="Delimiter">(</span>type_tree* type<span class="Delimiter">,</span> <span class="Normal">const</span> string& block<span class="Delimiter">,</span> <span class="Normal">const</span> string& name<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <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> + <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>atom<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> 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> block<span class="Delimiter">,</span> name<span class="Delimiter">);</span> + <span class="Identifier">return</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Normal">if</span> <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> assert<span class="Delimiter">(</span>!type<span class="Delimiter">-></span>name<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> @@ -726,8 +891,6 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa <span class="Normal">else</span> raise << block << <span class="Constant">"unknown type "</span> << type<span class="Delimiter">-></span>name << <span class="Constant">" 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> 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> block<span class="Delimiter">,</span> name<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">:(scenario container_unknown_field)</span> @@ -769,12 +932,15 @@ check_container_field_types<span class="Delimiter">();</span> <span class="Normal">void</span> check_invalid_types<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">,</span> <span class="Normal">const</span> string& block<span class="Delimiter">,</span> <span class="Normal">const</span> string& name<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <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="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <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="Identifier">return</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>value != <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// value 0 = compound types (layer parse_tree) or type ingredients (layer shape_shifting_container)</span> <span class="Normal">if</span> <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 << block << <span class="Constant">"unknown type in "</span> << name << <span class="cSpecial">'\n'</span> << end<span class="Delimiter">();</span> <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> </pre> </body> diff --git a/html/031merge.cc.html b/html/031merge.cc.html index fd309bbe..0642eab2 100644 --- a/html/031merge.cc.html +++ b/html/031merge.cc.html @@ -159,12 +159,13 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa <span class="Delimiter">}</span> reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> 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 product While Type-checking Merge</span> - type_ordinal product_type = product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>product_type == <span class="Constant">0</span> || !contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> product_type<span class="Delimiter">))</span> <span class="Delimiter">{</span> + <span class="Normal">const</span> type_tree* product_base_type = product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom ? product<span class="Delimiter">.</span>type : product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">;</span> + assert<span class="Delimiter">(</span>product_base_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>product_base_type<span class="Delimiter">-></span>value == <span class="Constant">0</span> || !contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> product_base_type<span class="Delimiter">-></span>value<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"'merge' should yield a container in '"</span> << inst<span class="Delimiter">.</span>original_string << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">const</span> type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> product_type<span class="Delimiter">);</span> + <span class="Normal">const</span> type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> product_base_type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>info<span class="Delimiter">.</span>kind != CONTAINER && info<span class="Delimiter">.</span>kind != EXCLUSIVE_CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"'merge' should yield a container in '"</span> << inst<span class="Delimiter">.</span>original_string << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> @@ -186,7 +187,9 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa <span class="Delimiter">}</span> reagent& container = state<span class="Delimiter">.</span>data<span class="Delimiter">.</span>top<span class="Delimiter">().</span>container<span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!container<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// error handled elsewhere</span> - type_info& container_info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> + <span class="Normal">const</span> type_tree* top_root_type = container<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom ? container<span class="Delimiter">.</span>type : container<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">;</span> + assert<span class="Delimiter">(</span>top_root_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + type_info& container_info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> top_root_type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> <span class="Normal">switch</span> <span class="Delimiter">(</span>container_info<span class="Delimiter">.</span>kind<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">case</span> CONTAINER: <span class="Delimiter">{</span> <span class="Comment">// degenerate case: merge with the same type always succeeds</span> @@ -198,7 +201,7 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa <span class="Normal">if</span> <span class="Delimiter">(</span>types_coercible<span class="Delimiter">(</span>expected_ingredient<span class="Delimiter">,</span> ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>ingredient_index<span class="Delimiter">)))</span> <span class="Delimiter">{</span> ++ingredient_index<span class="Delimiter">;</span> ++state<span class="Delimiter">.</span>data<span class="Delimiter">.</span>top<span class="Delimiter">().</span>container_element_index<span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>state<span class="Delimiter">.</span>data<span class="Delimiter">.</span>top<span class="Delimiter">().</span>container_element_index >= SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> state<span class="Delimiter">.</span>data<span class="Delimiter">.</span>top<span class="Delimiter">().</span>container<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>elements<span class="Delimiter">))</span> <span class="Delimiter">{</span> + <span class="Normal">while</span> <span class="Delimiter">(</span>state<span class="Delimiter">.</span>data<span class="Delimiter">.</span>top<span class="Delimiter">().</span>container_element_index >= SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root_type<span class="Delimiter">(</span>state<span class="Delimiter">.</span>data<span class="Delimiter">.</span>top<span class="Delimiter">().</span>container<span class="Delimiter">.</span>type<span class="Delimiter">)-></span>value<span class="Delimiter">).</span>elements<span class="Delimiter">))</span> <span class="Delimiter">{</span> state<span class="Delimiter">.</span>data<span class="Delimiter">.</span>pop<span class="Delimiter">();</span> <span class="Normal">if</span> <span class="Delimiter">(</span>state<span class="Delimiter">.</span>data<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>ingredient_index < SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">))</span> @@ -233,7 +236,7 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> ++state<span class="Delimiter">.</span>data<span class="Delimiter">.</span>top<span class="Delimiter">().</span>container_element_index<span class="Delimiter">;</span> - <span class="Delimiter">}</span> <span class="Normal">while</span> <span class="Delimiter">(</span>state<span class="Delimiter">.</span>data<span class="Delimiter">.</span>top<span class="Delimiter">().</span>container_element_index >= SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> state<span class="Delimiter">.</span>data<span class="Delimiter">.</span>top<span class="Delimiter">().</span>container<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>elements<span class="Delimiter">));</span> + <span class="Delimiter">}</span> <span class="Normal">while</span> <span class="Delimiter">(</span>state<span class="Delimiter">.</span>data<span class="Delimiter">.</span>top<span class="Delimiter">().</span>container_element_index >= SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root_type<span class="Delimiter">(</span>state<span class="Delimiter">.</span>data<span class="Delimiter">.</span>top<span class="Delimiter">().</span>container<span class="Delimiter">.</span>type<span class="Delimiter">)-></span>value<span class="Delimiter">).</span>elements<span class="Delimiter">));</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> @@ -251,7 +254,6 @@ def main [ <span class="Delimiter">:(before "End Includes")</span> <span class="PreProc">#include </span><span class="Constant"><stack></span> <span class="Normal">using</span> std::stack<span class="Delimiter">;</span> - </pre> </body> </html> diff --git a/html/032array.cc.html b/html/032array.cc.html index 921247a6..d78f29ab 100644 --- a/html/032array.cc.html +++ b/html/032array.cc.html @@ -69,11 +69,14 @@ put<span class="Delimiter">(</span>Recipe_ordinal<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> - <span class="Normal">if</span> <span class="Delimiter">(</span>!product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> + type_tree* array_length_from_type = product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!array_length_from_type<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << 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>original_string << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!is_integer<span class="Delimiter">(</span>product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> + array_length_from_type = array_length_from_type<span class="Delimiter">-></span>left<span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!is_integer<span class="Delimiter">(</span>array_length_from_type<span class="Delimiter">-></span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise << 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>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -84,7 +87,10 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> 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> <span class="Comment">// Update CREATE_ARRAY product in Run</span> <span class="Normal">int</span> base_address = product<span class="Delimiter">.</span>value<span class="Delimiter">;</span> - <span class="Normal">int</span> array_length = to_integer<span class="Delimiter">(</span>product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">);</span> + type_tree* array_length_from_type = product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> + array_length_from_type = array_length_from_type<span class="Delimiter">-></span>left<span class="Delimiter">;</span> + <span class="Normal">int</span> array_length = to_integer<span class="Delimiter">(</span>array_length_from_type<span class="Delimiter">-></span>name<span class="Delimiter">);</span> <span class="Comment">// initialize array length, so that size_of will work</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> << array_length << <span class="Constant">" in location "</span> << base_address << end<span class="Delimiter">();</span> put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> base_address<span class="Delimiter">,</span> array_length<span class="Delimiter">);</span> <span class="Comment">// in array elements</span> @@ -128,7 +134,7 @@ def main [ <span class="traceContains">+app: foo: 3 14 15 16</span> <span class="Delimiter">:(before "End size_of(reagent r) Cases")</span> -<span class="Normal">if</span> <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> +<span class="Normal">if</span> <span class="Delimiter">(</span>!r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom && r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom && r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<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> <span class="Normal">if</span> <span class="Delimiter">(</span>!r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << 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> @@ -142,7 +148,7 @@ def main [ <span class="Comment">//: disable the size mismatch check for arrays since the destination array</span> <span class="Comment">//: need not be initialized</span> <span class="Delimiter">:(before "End size_mismatch(x) Cases")</span> -<span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>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="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>type && !x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<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="Comment">//: arrays are disallowed inside containers unless their length is fixed in</span> <span class="Comment">//: advance</span> @@ -182,12 +188,16 @@ def main [ <span class="Delimiter">:(before "End Load Container Element Definition")</span> <span class="Delimiter">{</span> <span class="Normal">const</span> type_tree* type = info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>back<span class="Delimiter">().</span>type<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>type && type<span class="Delimiter">-></span>name == <span class="Constant">"array"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>type && type<span class="Delimiter">-></span>atom && type<span class="Delimiter">-></span>name == <span class="Constant">"array"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << <span class="Constant">"container '"</span> << name << <span class="Constant">"' doesn't specify type of array elements for '"</span> << info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>back<span class="Delimiter">().</span>name << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">continue</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>type && !type<span class="Delimiter">-></span>atom && type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom && type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>name == <span class="Constant">"array"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << <span class="Constant">"container '"</span> << name << <span class="Constant">"' doesn't specify type of array elements for '"</span> << info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>back<span class="Delimiter">().</span>name << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// array has no length</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// array has no length</span> raise << <span class="Constant">"container '"</span> << name << <span class="Constant">"' cannot determine size of element '"</span> << info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>back<span class="Delimiter">().</span>name << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -217,6 +227,16 @@ def main [ ] <span class="traceContains">+mem: storing 14 in location 5</span> +<span class="Delimiter">:(scenario index_compound_element)</span> +def main [ + <span class="Delimiter">{</span><span class="Constant">1</span>: <span class="Delimiter">(</span>array <span class="Delimiter">(</span>address number<span class="Delimiter">)</span> <span class="Constant">3</span><span class="Delimiter">)}</span><span class="Special"> <- </span>create-array + <span class="Constant">2</span>:number<span class="Special"> <- </span>copy <span class="Constant">14</span> + <span class="Constant">3</span>:number<span class="Special"> <- </span>copy <span class="Constant">15</span> + <span class="Constant">4</span>:number<span class="Special"> <- </span>copy <span class="Constant">16</span> + <span class="Constant">5</span>:address:number<span class="Special"> <- </span>index <span class="Delimiter">{</span><span class="Constant">1</span>: <span class="Delimiter">(</span>array <span class="Delimiter">(</span>address number<span class="Delimiter">)</span> <span class="Constant">3</span><span class="Delimiter">)},</span> <span class="Constant">0</span> +] +<span class="traceContains">+mem: storing 14 in location 5</span> + <span class="Delimiter">:(scenario index_direct_offset)</span> def main [ <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> <- </span>create-array @@ -281,7 +301,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span type_tree* element_type = copy_array_element<span class="Delimiter">(</span>base<span class="Delimiter">.</span>type<span class="Delimiter">);</span> <span class="Normal">int</span> src = base_address + <span class="Constant">1</span> + index_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><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> + 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> << to_string<span class="Delimiter">(</span>element_type<span class="Delimiter">)</span> << end<span class="Delimiter">();</span> reagent element<span class="Delimiter">;</span> element<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>src<span class="Delimiter">);</span> element<span class="Delimiter">.</span>type = element_type<span class="Delimiter">;</span> @@ -292,19 +312,15 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">:(code)</span> type_tree* copy_array_element<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>left<span class="Delimiter">)</span> <span class="Delimiter">{</span> - assert<span class="Delimiter">(</span>!type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>left<span class="Delimiter">-></span>left<span class="Delimiter">);</span> - <span class="Identifier">return</span> <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>left<span class="Delimiter">);</span> - <span class="Delimiter">}</span> assert<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">);</span> - <span class="Comment">// array:<type>:<size>? return just <type></span> - <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right && is_integer<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">))</span> - <span class="Identifier">return</span> <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">,</span> type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>value<span class="Delimiter">);</span> <span class="Comment">// snip type->right->right</span> + <span class="Comment">// hack: don't require parens for either array:number:3 array:address:number</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>atom && 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>atom && is_integer<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">))</span> + <span class="Identifier">return</span> <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>left<span class="Delimiter">);</span> <span class="Identifier">return</span> <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*type<span class="Delimiter">-></span>right<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">int</span> array_length<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>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>right <span class="Comment">// exactly 3 types</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom && !x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>atom && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>atom <span class="Comment">// exactly 3 types</span> && is_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Comment">// third 'type' is a number</span> <span class="Comment">// get size from type</span> <span class="Identifier">return</span> to_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">);</span> diff --git a/html/033exclusive_container.cc.html b/html/033exclusive_container.cc.html index 9b31c886..5068a365 100644 --- a/html/033exclusive_container.cc.html +++ b/html/033exclusive_container.cc.html @@ -70,22 +70,27 @@ def main [ <span class="Comment">// Compute size_of Exclusive Container</span> <span class="Identifier">return</span> get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> type<span class="Delimiter">).</span>size<span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Delimiter">:(before "End compute_container_sizes Cases")</span> +<span class="Delimiter">:(before "End compute_container_sizes Atom Cases")</span> <span class="Normal">if</span> <span class="Delimiter">(</span>info<span class="Delimiter">.</span>kind == EXCLUSIVE_CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span> - container_metadata metadata<span class="Delimiter">;</span> + compute_exclusive_container_sizes<span class="Delimiter">(</span>info<span class="Delimiter">,</span> type<span class="Delimiter">,</span> pending_metadata<span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Delimiter">:(code)</span> +<span class="Normal">void</span> compute_exclusive_container_sizes<span class="Delimiter">(</span><span class="Normal">const</span> type_info& exclusive_container_info<span class="Delimiter">,</span> <span class="Normal">const</span> type_tree* full_type<span class="Delimiter">,</span> set<type_tree>& pending_metadata<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// size of an exclusive container is the size of its largest variant</span> - <span class="Comment">// (So like containers, it can't contain arrays.)</span> - <span class="Normal">int</span> size = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> element = info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> - <span class="Comment">// Compute Exclusive Container Size(element)</span> + <span class="Comment">// (So, like containers, it can only contain arrays if they're static and</span> + <span class="Comment">// include their length in the type.)</span> + container_metadata metadata<span class="Delimiter">;</span> + <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>exclusive_container_info<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> + reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> element = exclusive_container_info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> + <span class="Comment">// Compute Exclusive Container Size(element, full_type)</span> compute_container_sizes<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">,</span> pending_metadata<span class="Delimiter">);</span> <span class="Normal">int</span> variant_size = size_of<span class="Delimiter">(</span>element<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>variant_size > size<span class="Delimiter">)</span> size = variant_size<span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>variant_size > metadata<span class="Delimiter">.</span>size<span class="Delimiter">)</span> metadata<span class="Delimiter">.</span>size = variant_size<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">// ...+1 for its tag.</span> - metadata<span class="Delimiter">.</span>size = size+<span class="Constant">1</span><span class="Delimiter">;</span> - Container_metadata<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<type_tree*<span class="Delimiter">,</span> container_metadata><span class="Delimiter">(</span><span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*type<span class="Delimiter">),</span> metadata<span class="Delimiter">));</span> + ++metadata<span class="Delimiter">.</span>size<span class="Delimiter">;</span> + Container_metadata<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>pair<type_tree*<span class="Delimiter">,</span> container_metadata><span class="Delimiter">(</span><span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*full_type<span class="Delimiter">),</span> metadata<span class="Delimiter">));</span> <span class="Delimiter">}</span> <span class="SalientComment">//:: To access variants of an exclusive container, use 'maybe-convert'.</span> @@ -135,7 +140,12 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> 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 MAYBE_CONVERT base in Check</span> - <span class="Normal">if</span> <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> + <span class="Normal">if</span> <span class="Delimiter">(</span>!base<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'maybe-convert' should be an exclusive-container, but got '"</span> << base<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">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Normal">const</span> type_tree* root_type = base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom ? base<span class="Delimiter">.</span>type : base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!root_type<span class="Delimiter">-></span>atom || root_type<span class="Delimiter">-></span>value == <span class="Constant">0</span> || !contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root_type<span class="Delimiter">-></span>value<span class="Delimiter">)</span> || get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root_type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>kind != EXCLUSIVE_CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"first ingredient of 'maybe-convert' should be an exclusive-container, but got '"</span> << base<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">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -152,7 +162,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Comment">// Update MAYBE_CONVERT product in Check</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> populate_value<span class="Delimiter">(</span>offset<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>offset<span class="Delimiter">.</span>value >= SIZE<span class="Delimiter">(</span>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>elements<span class="Delimiter">))</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>offset<span class="Delimiter">.</span>value >= SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root_type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>elements<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"invalid tag "</span> << offset<span class="Delimiter">.</span>value << <span class="Constant">" in '"</span> << inst<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> @@ -211,9 +221,10 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Normal">const</span> reagent variant_type<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">,</span> <span class="Normal">int</span> tag<span class="Delimiter">)</span> <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>tag >= <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> 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> type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>name<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> - <span class="Normal">const</span> type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> + <span class="Normal">const</span> type_tree* root_type = type<span class="Delimiter">-></span>atom ? type : type<span class="Delimiter">-></span>left<span class="Delimiter">;</span> + assert<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root_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> root_type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>name<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> + <span class="Normal">const</span> type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root_type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> assert<span class="Delimiter">(</span>info<span class="Delimiter">.</span>kind == EXCLUSIVE_CONTAINER<span class="Delimiter">);</span> reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> element = info<span class="Delimiter">.</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>tag<span class="Delimiter">);</span> <span class="Comment">// End variant_type Special-cases</span> @@ -465,7 +476,9 @@ $error: <span class="Constant">0</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<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> 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> <span class="Comment">// Update size_mismatch Check for MERGE(x)</span> - <span class="Normal">if</span> <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="Normal">const</span> type_tree* root_type = x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom ? x<span class="Delimiter">.</span>type : x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">;</span> + assert<span class="Delimiter">(</span>root_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root_type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>kind == EXCLUSIVE_CONTAINER<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> diff --git a/html/034address.cc.html b/html/034address.cc.html index d4ef5474..f809d2fb 100644 --- a/html/034address.cc.html +++ b/html/034address.cc.html @@ -209,12 +209,13 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Normal">bool</span> product_of_new_is_valid<span class="Delimiter">(</span><span class="Normal">const</span> instruction& inst<span class="Delimiter">)</span> <span class="Delimiter">{</span> reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> 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 NEW product in Check</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!product<span class="Delimiter">.</span>type || product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">))</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!product<span class="Delimiter">.</span>type || product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom || product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> drop_from_type<span class="Delimiter">(</span>product<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> > <span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// array allocation</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!product<span class="Delimiter">.</span>type || product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!product<span class="Delimiter">.</span>type || product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom || product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">))</span> + <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> drop_from_type<span class="Delimiter">(</span>product<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> expected_product<span class="Delimiter">(</span><span class="Constant">"x:"</span>+inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">);</span> @@ -228,7 +229,8 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Normal">void</span> drop_from_type<span class="Delimiter">(</span>reagent& r<span class="Delimiter">,</span> string expected_type<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name != expected_type<span class="Delimiter">)</span> <span class="Delimiter">{</span> + assert<span class="Delimiter">(</span>!r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>name != expected_type<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << <span class="Constant">"can't drop2 "</span> << expected_type << <span class="Constant">" from '"</span> << to_string<span class="Delimiter">(</span>r<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> @@ -280,7 +282,7 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa <span class="Comment">//: implement 'allocate' based on size</span> <span class="Delimiter">:(before "End Globals")</span> -<span class="Normal">const</span> <span class="Normal">int</span> Reserved_for_tests = <span class="Constant">1000</span><span class="Delimiter">;</span> +<span class="Normal">extern</span> <span class="Normal">const</span> <span class="Normal">int</span> Reserved_for_tests = <span class="Constant">1000</span><span class="Delimiter">;</span> <span class="Normal">int</span> Memory_allocated_until = Reserved_for_tests<span class="Delimiter">;</span> <span class="Normal">int</span> Initial_memory_per_routine = <span class="Constant">100000</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End Setup")</span> diff --git a/html/035lookup.cc.html b/html/035lookup.cc.html index 0cab088a..43b6ffb1 100644 --- a/html/035lookup.cc.html +++ b/html/035lookup.cc.html @@ -112,7 +112,7 @@ def main [ <span class="Delimiter">}</span> <span class="Normal">void</span> lookup_memory<span class="Delimiter">(</span>reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>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> + <span class="Normal">if</span> <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>type || x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom || x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<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 << 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="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -185,13 +185,15 @@ canonize_type<span class="Delimiter">(</span>rhs<span class="Delimiter">);</span <span class="Delimiter">:(before "Compute Container Size(reagent rcopy)")</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!canonize_type<span class="Delimiter">(</span>rcopy<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> -<span class="Delimiter">:(before "Compute Container Size(element)")</span> +<span class="Delimiter">:(before "Compute Container Size(element, full_type)")</span> +assert<span class="Delimiter">(</span>!has_property<span class="Delimiter">(</span>element<span class="Delimiter">,</span> <span class="Constant">"lookup"</span><span class="Delimiter">));</span> +<span class="Delimiter">:(before "Compute Exclusive Container Size(element, full_type)")</span> assert<span class="Delimiter">(</span>!has_property<span class="Delimiter">(</span>element<span class="Delimiter">,</span> <span class="Constant">"lookup"</span><span class="Delimiter">));</span> <span class="Delimiter">:(code)</span> <span class="Normal">bool</span> canonize_type<span class="Delimiter">(</span>reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">while</span> <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">"lookup"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <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> + <span class="Normal">if</span> <span class="Delimiter">(</span>!r<span class="Delimiter">.</span>type || r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom || !r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left || !r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom || r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<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 << <span class="Constant">"can't lookup non-address: '"</span> << to_string<span class="Delimiter">(</span>r<span class="Delimiter">)</span> << <span class="Constant">"': '"</span> << to_string<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<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">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> diff --git a/html/036refcount.cc.html b/html/036refcount.cc.html index 6613fdb8..ef642de8 100644 --- a/html/036refcount.cc.html +++ b/html/036refcount.cc.html @@ -313,7 +313,6 @@ map<set<tag_condition_info><span class="Delimiter">,</span> set<addr <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Comment">// equal</span> <span class="Delimiter">}</span> - <span class="Comment">//: populate metadata.address in a separate transform, because it requires</span> <span class="Comment">//: already knowing the sizes of all types</span> @@ -332,45 +331,70 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa compute_container_address_offsets<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> + <span class="Normal">void</span> compute_container_address_offsets<span class="Delimiter">(</span>reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>r<span class="Delimiter">)</span> || is_dummy<span class="Delimiter">(</span>r<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">))</span> r<span class="Delimiter">.</span>metadata = get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> compute_container_address_offsets<span class="Delimiter">(</span>type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span> + +<span class="Comment">// the recursive structure of this function needs to exactly match</span> +<span class="Comment">// compute_container_sizes</span> +<span class="Normal">void</span> compute_container_address_offsets<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">)</span> compute_container_address_offsets<span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">)</span> compute_container_address_offsets<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">);</span> - <span class="Normal">if</span> <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="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// error raised elsewhere</span> - type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> + assert<span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>name == <span class="Constant">"address"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + compute_container_address_offsets<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">);</span> + <span class="Delimiter">}</span> + <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>name == <span class="Constant">"array"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">const</span> type_tree* element_type = type<span class="Delimiter">-></span>right<span class="Delimiter">;</span> + <span class="Comment">// hack: support both array:number:3 and array:address:number</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!element_type<span class="Delimiter">-></span>atom && element_type<span class="Delimiter">-></span>right && element_type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>atom && is_integer<span class="Delimiter">(</span>element_type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">))</span> + element_type = element_type<span class="Delimiter">-></span>left<span class="Delimiter">;</span> + compute_container_address_offsets<span class="Delimiter">(</span>element_type<span class="Delimiter">);</span> + <span class="Delimiter">}</span> + <span class="Comment">// End compute_container_address_offsets Non-atom Cases</span> + <span class="Delimiter">}</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root_type<span class="Delimiter">(</span>type<span class="Delimiter">)-></span>value<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// error raised elsewhere</span> + type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root_type<span class="Delimiter">(</span>type<span class="Delimiter">)-></span>value<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>info<span class="Delimiter">.</span>kind == CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span> - container_metadata& metadata = get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> type<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!metadata<span class="Delimiter">.</span>address<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">9994</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"compute address offsets for container "</span> << info<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span> - append_addresses<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">,</span> type<span class="Delimiter">,</span> metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + compute_container_address_offsets<span class="Delimiter">(</span>info<span class="Delimiter">,</span> type<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>info<span class="Delimiter">.</span>kind == EXCLUSIVE_CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span> - container_metadata& metadata = get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> type<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">"compute address offsets for exclusive container "</span> << info<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> tag = <span class="Constant">0</span><span class="Delimiter">;</span> tag < SIZE<span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++tag<span class="Delimiter">)</span> <span class="Delimiter">{</span> - set<tag_condition_info> key<span class="Delimiter">;</span> - key<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>tag_condition_info<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">tag is at offset</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">,</span> tag<span class="Delimiter">));</span> - append_addresses<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">skip tag offset</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">,</span> variant_type<span class="Delimiter">(</span>type<span class="Delimiter">,</span> tag<span class="Delimiter">).</span>type<span class="Delimiter">,</span> metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> key<span class="Delimiter">);</span> - <span class="Delimiter">}</span> + compute_exclusive_container_address_offsets<span class="Delimiter">(</span>info<span class="Delimiter">,</span> type<span class="Delimiter">);</span> + <span class="Delimiter">}</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> compute_container_address_offsets<span class="Delimiter">(</span><span class="Normal">const</span> type_info& container_info<span class="Delimiter">,</span> <span class="Normal">const</span> type_tree* full_type<span class="Delimiter">)</span> <span class="Delimiter">{</span> + container_metadata& metadata = get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> full_type<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!metadata<span class="Delimiter">.</span>address<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">9994</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"compute address offsets for container "</span> << container_info<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span> + append_addresses<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">,</span> full_type<span class="Delimiter">,</span> metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> compute_exclusive_container_address_offsets<span class="Delimiter">(</span><span class="Normal">const</span> type_info& exclusive_container_info<span class="Delimiter">,</span> <span class="Normal">const</span> type_tree* full_type<span class="Delimiter">)</span> <span class="Delimiter">{</span> + container_metadata& metadata = get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> full_type<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">"compute address offsets for exclusive container "</span> << exclusive_container_info<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span> + <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> tag = <span class="Constant">0</span><span class="Delimiter">;</span> tag < SIZE<span class="Delimiter">(</span>exclusive_container_info<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++tag<span class="Delimiter">)</span> <span class="Delimiter">{</span> + set<tag_condition_info> key<span class="Delimiter">;</span> + key<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>tag_condition_info<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">tag is at offset</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">,</span> tag<span class="Delimiter">));</span> + append_addresses<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">skip tag offset</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">,</span> variant_type<span class="Delimiter">(</span>full_type<span class="Delimiter">,</span> tag<span class="Delimiter">).</span>type<span class="Delimiter">,</span> metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> key<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Normal">void</span> append_addresses<span class="Delimiter">(</span><span class="Normal">int</span> base_offset<span class="Delimiter">,</span> <span class="Normal">const</span> type_tree* type<span class="Delimiter">,</span> map<set<tag_condition_info><span class="Delimiter">,</span> set<address_element_info> >& out<span class="Delimiter">,</span> <span class="Normal">const</span> set<tag_condition_info>& key<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">const</span> type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>name == <span class="Constant">"address"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>type<span class="Delimiter">))</span> <span class="Delimiter">{</span> get_or_insert<span class="Delimiter">(</span>out<span class="Delimiter">,</span> key<span class="Delimiter">).</span>insert<span class="Delimiter">(</span>address_element_info<span class="Delimiter">(</span>base_offset<span class="Delimiter">,</span> <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*type<span class="Delimiter">-></span>right<span class="Delimiter">)));</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> + <span class="Normal">const</span> type_tree* root = root_type<span class="Delimiter">(</span>type<span class="Delimiter">);</span> + <span class="Normal">const</span> type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root<span class="Delimiter">-></span>value<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>info<span class="Delimiter">.</span>kind == CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> curr_index = <span class="Constant">0</span><span class="Delimiter">,</span> curr_offset = base_offset<span class="Delimiter">;</span> curr_index < SIZE<span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++curr_index<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">"checking container "</span> << type<span class="Delimiter">-></span>name << <span class="Constant">", element "</span> << curr_index << end<span class="Delimiter">();</span> - reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> element = element_type<span class="Delimiter">(</span>type<span class="Delimiter">,</span> curr_index<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">"checking container "</span> << root<span class="Delimiter">-></span>name << <span class="Constant">", element "</span> << curr_index << end<span class="Delimiter">();</span> + reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> element = element_type<span class="Delimiter">(</span>type<span class="Delimiter">,</span> curr_index<span class="Delimiter">);</span> <span class="Comment">// not root</span> <span class="Comment">// Compute Container Address Offset(element)</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>element<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">"address at offset "</span> << curr_offset << end<span class="Delimiter">();</span> @@ -382,7 +406,8 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa curr_offset += size_of<span class="Delimiter">(</span>element<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_exclusive_container<span class="Delimiter">(</span>element<span class="Delimiter">))</span> <span class="Delimiter">{</span> - <span class="Normal">const</span> type_info& element_info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> + <span class="Normal">const</span> type_tree* element_root_type = root_type<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">);</span> + <span class="Normal">const</span> type_info& element_info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> element_root_type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> tag = <span class="Constant">0</span><span class="Delimiter">;</span> tag < SIZE<span class="Delimiter">(</span>element_info<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++tag<span class="Delimiter">)</span> <span class="Delimiter">{</span> set<tag_condition_info> new_key = key<span class="Delimiter">;</span> new_key<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>tag_condition_info<span class="Delimiter">(</span>curr_offset<span class="Delimiter">,</span> tag<span class="Delimiter">));</span> @@ -413,6 +438,280 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">)</span> + <span class="Comment">/*</span><span class="Comment">refcount</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> +<span class="Comment">//: for the following unit tests we'll do the work of the transform by hand</span> + +<span class="Delimiter">:(before "End Unit Tests")</span> +<span class="Normal">void</span> test_container_address_offsets_empty<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// define a container with no addresses</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:point"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// need to first pre-populate the metadata</span> + <span class="Comment">// scan</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// global metadata contains just the entry for foo</span> + <span class="Comment">// no entries for non-container types or other junk</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// the reagent we scanned knows it has no addresses</span> + CHECK<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> + <span class="Comment">// the global table contains an identical entry</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + CHECK<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">).</span>address<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> + <span class="Comment">// compute_container_address_offsets creates no new entries</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_address_offsets<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// define a container with an address at offset 0 that we have the size for</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:address:number</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> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:foo"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// need to first pre-populate the metadata</span> + <span class="Comment">// scan</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// global metadata contains just the entry for foo</span> + <span class="Comment">// no entries for non-container types or other junk</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// the reagent we scanned knows it has an address at offset 0</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">()));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets = get<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> <span class="Comment">// unconditional for containers</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>address_offsets<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> + <span class="Comment">// the global table contains an identical entry</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets2 = get<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">).</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> + <span class="Comment">// compute_container_address_offsets creates no new entries</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_address_offsets_2<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// define a container with an address at offset 1 that we have the size for</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" y:address:number</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> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:foo"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// need to first pre-populate the metadata</span> + <span class="Comment">// global metadata contains just the entry for foo</span> + <span class="Comment">// no entries for non-container types or other junk</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scan</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// compute_container_address_offsets creates no new entries</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// the reagent we scanned knows it has an address at offset 1</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">()));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets = get<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> <span class="Comment">//</span> + CHECK<span class="Delimiter">(</span>address_offsets<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> + <span class="Comment">// the global table contains an identical entry</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets2 = get<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">).</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> <span class="Comment">//</span> + CHECK<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_address_offsets_nested<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// define a container with a nested container containing an address</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:address:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" y:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">"container bar [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" p:point</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" f:foo</span><span class="cSpecial">\n</span><span class="Constant">"</span> <span class="Comment">// nested container containing address</span> + <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:bar"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// need to first pre-populate the metadata</span> + <span class="Comment">// global metadata contains entries for bar and included types: point and foo</span> + <span class="Comment">// no entries for non-container types or other junk</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">3</span><span class="Delimiter">);</span> + <span class="Comment">// scan</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// the reagent we scanned knows it has an address at offset 2</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">()));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets = get<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">2</span><span class="Delimiter">);</span> <span class="Comment">//</span> + CHECK<span class="Delimiter">(</span>address_offsets<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> + <span class="Comment">// the global table also knows its address offset</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets2 = get<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">).</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">2</span><span class="Delimiter">);</span> <span class="Comment">//</span> + CHECK<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> + <span class="Comment">// compute_container_address_offsets creates no new entries</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">3</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_address_offsets_from_address<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// define a container with an address at offset 0</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:address:number</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> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:address:foo"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// need to first pre-populate the metadata</span> + <span class="Comment">// global metadata contains just the entry for foo</span> + <span class="Comment">// no entries for non-container types or other junk</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scan an address to the container</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// compute_container_address_offsets creates no new entries</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scanning precomputed metadata for the container</span> + reagent container<span class="Delimiter">(</span><span class="Constant">"x:foo"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets2 = get<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">).</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_address_offsets_from_array<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// define a container with an address at offset 0</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:address:number</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> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:array:foo"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// need to first pre-populate the metadata</span> + <span class="Comment">// global metadata contains just the entry for foo</span> + <span class="Comment">// no entries for non-container types or other junk</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scan an array of the container</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// compute_container_address_offsets creates no new entries</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scanning precomputed metadata for the container</span> + reagent container<span class="Delimiter">(</span><span class="Constant">"x:foo"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets2 = get<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">).</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_address_offsets_from_address_to_array<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// define a container with an address at offset 0</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:address:number</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> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:address:array:foo"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// need to first pre-populate the metadata</span> + <span class="Comment">// global metadata contains just the entry for foo</span> + <span class="Comment">// no entries for non-container types or other junk</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scan an address to an array of the container</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// compute_container_address_offsets creates no new entries</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scanning precomputed metadata for the container</span> + reagent container<span class="Delimiter">(</span><span class="Constant">"x:foo"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets2 = get<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">).</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_address_offsets_from_static_array<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// define a container with an address at offset 0</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:address:number</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> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:array:foo:10"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// need to first pre-populate the metadata</span> + <span class="Comment">// global metadata contains just the entry for foo</span> + <span class="Comment">// no entries for non-container types or other junk</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scan a static array of the container</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// compute_container_address_offsets creates no new entries</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scanning precomputed metadata for the container</span> + reagent container<span class="Delimiter">(</span><span class="Constant">"x:foo"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets2 = get<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">).</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_address_offsets_from_address_to_static_array<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// define a container with an address at offset 0</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:address:number</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> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:address:array:foo:10"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// need to first pre-populate the metadata</span> + <span class="Comment">// global metadata contains just the entry for foo</span> + <span class="Comment">// no entries for non-container types or other junk</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scan an address to a static array of the container</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// compute_container_address_offsets creates no new entries</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scanning precomputed metadata for the container</span> + reagent container<span class="Delimiter">(</span><span class="Constant">"x:foo"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets2 = get<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">).</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_address_offsets_from_repeated_address_and_array_types<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// define a container with an address at offset 0</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:address:number</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> + <span class="Comment">// scan a deep nest of 'address' and 'array' types modifying a container</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:address:array:address:address:array:foo:10"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// need to first pre-populate the metadata</span> + <span class="Comment">// global metadata contains just the entry for foo</span> + <span class="Comment">// no entries for non-container types or other junk</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// compute_container_address_offsets creates no new entries</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scanning precomputed metadata for the container</span> + reagent container<span class="Delimiter">(</span><span class="Constant">"x:foo"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets2 = get<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">).</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + <span class="Comment">//: use metadata.address to update refcounts within containers, arrays and</span> <span class="Comment">//: exclusive containers</span> @@ -683,6 +982,7 @@ def main [ <span class="Delimiter">}</span> <span class="Normal">bool</span> is_mu_container<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <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="Comment">// End is_mu_container(type) Special-cases</span> <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> <span class="Identifier">return</span> info<span class="Delimiter">.</span>kind == CONTAINER<span class="Delimiter">;</span> @@ -693,6 +993,7 @@ def main [ <span class="Delimiter">}</span> <span class="Normal">bool</span> is_mu_exclusive_container<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <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="Comment">// End is_mu_exclusive_container(type) Special-cases</span> <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> <span class="Identifier">return</span> info<span class="Delimiter">.</span>kind == EXCLUSIVE_CONTAINER<span class="Delimiter">;</span> diff --git a/html/037abandon.cc.html b/html/037abandon.cc.html index 89ea879c..a6d10bee 100644 --- a/html/037abandon.cc.html +++ b/html/037abandon.cc.html @@ -66,7 +66,7 @@ map<<span class="Normal">int</span><span class="Delimiter">,</span> <span cla <span class="CommentedCode">//? ++Num_free;</span> <span class="CommentedCode">//? cerr << "abandon: " << size << '\n';</span> <span class="Comment">// decrement any contained refcounts</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>payload_type<span class="Delimiter">-></span>name == <span class="Constant">"array"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_array<span class="Delimiter">(</span>payload_type<span class="Delimiter">))</span> <span class="Delimiter">{</span> reagent element<span class="Delimiter">;</span> element<span class="Delimiter">.</span>type = copy_array_element<span class="Delimiter">(</span>payload_type<span class="Delimiter">);</span> <span class="Normal">int</span> array_length = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address+<span class="Comment">/*</span><span class="Comment">skip refcount</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">);</span> diff --git a/html/039location_array.cc.html b/html/039location_array.cc.html index cb1e0e08..a5a12a01 100644 --- a/html/039location_array.cc.html +++ b/html/039location_array.cc.html @@ -44,15 +44,21 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(code)</span> -<span class="Normal">bool</span> is_address_of_array_of_numbers<span class="Delimiter">(</span>reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> product<span class="Delimiter">)</span> <span class="Delimiter">{</span> - canonize_type<span class="Delimiter">(</span>product<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!product<span class="Delimiter">.</span>type || product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - drop_from_type<span class="Delimiter">(</span>product<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!product<span class="Delimiter">.</span>type || product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - drop_from_type<span class="Delimiter">(</span>product<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!product<span class="Delimiter">.</span>type || product<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> +<span class="Normal">bool</span> is_address_of_array_of_numbers<span class="Delimiter">(</span>reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> x<span class="Delimiter">)</span> <span class="Delimiter">{</span> + canonize_type<span class="Delimiter">(</span>x<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!is_compound_type_starting_with<span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + drop_from_type<span class="Delimiter">(</span>x<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!is_compound_type_starting_with<span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + drop_from_type<span class="Delimiter">(</span>x<span class="Delimiter">,</span> <span class="Constant">"array"</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>atom && 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">"number"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> +<span class="Normal">bool</span> is_compound_type_starting_with<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">,</span> <span class="Normal">const</span> string& expected_name<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <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="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Identifier">return</span> type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> expected_name<span class="Delimiter">);</span> +<span class="Delimiter">}</span> + <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> TO_LOCATION_ARRAY: <span class="Delimiter">{</span> <span class="Normal">int</span> array_size = SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> diff --git a/html/042name.cc.html b/html/042name.cc.html index e52ba220..97822b73 100644 --- a/html/042name.cc.html +++ b/html/042name.cc.html @@ -154,12 +154,10 @@ Name = Name_snapshot<span class="Delimiter">;</span> <span class="Delimiter">}</span> type_ordinal skip_addresses<span class="Delimiter">(</span>type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span> - type_ordinal address = get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">);</span> - <span class="Normal">for</span> <span class="Delimiter">(;</span> type<span class="Delimiter">;</span> type = type<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>value != address<span class="Delimiter">)</span> - <span class="Identifier">return</span> type<span class="Delimiter">-></span>value<span class="Delimiter">;</span> - <span class="Delimiter">}</span> - <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span> + <span class="Normal">while</span> <span class="Delimiter">(</span>type && is_compound_type_starting_with<span class="Delimiter">(</span>type<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">))</span> + type = type<span class="Delimiter">-></span>right<span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">)</span> <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Comment">// error handled elsewhere</span> + <span class="Identifier">return</span> root_type<span class="Delimiter">(</span>type<span class="Delimiter">)-></span>value<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">int</span> find_element_name<span class="Delimiter">(</span><span class="Normal">const</span> type_ordinal t<span class="Delimiter">,</span> <span class="Normal">const</span> string& name<span class="Delimiter">,</span> <span class="Normal">const</span> string& recipe_name<span class="Delimiter">)</span> <span class="Delimiter">{</span> diff --git a/html/043space.cc.html b/html/043space.cc.html index 0ecfbcc1..221f4ff2 100644 --- a/html/043space.cc.html +++ b/html/043space.cc.html @@ -119,19 +119,15 @@ absolutize<span class="Delimiter">(</span>x<span class="Delimiter">);</span> <span class="Delimiter">:(after "Begin Preprocess write_memory(x, data)")</span> <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"default-space"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>data<span class="Delimiter">)</span> - || !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> + <span class="Normal">if</span> <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>data<span class="Delimiter">)</span> || !is_space<span class="Delimiter">(</span>x<span class="Delimiter">))</span> raise << 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 is "</span> << to_string<span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<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">:(code)</span> +<span class="Normal">bool</span> is_space<span class="Delimiter">(</span><span class="Normal">const</span> reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Identifier">return</span> is_address_of_array_of_numbers<span class="Delimiter">(</span>r<span class="Delimiter">);</span> +<span class="Delimiter">}</span> <span class="Delimiter">:(scenario get_default_space)</span> def main [ diff --git a/html/045closure_name.cc.html b/html/045closure_name.cc.html index 210327f6..9cc50979 100644 --- a/html/045closure_name.cc.html +++ b/html/045closure_name.cc.html @@ -80,14 +80,7 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> j = <span class="Constant">0</span><span class="Delimiter">;</span> j < SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>name != <span class="Constant">"0"</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> - 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> - <span class="Normal">if</span> <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> + <span class="Normal">if</span> <span class="Delimiter">(</span>!is_space<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="Delimiter">{</span> raise << <span class="Constant">"slot 0 should always have type address:array:location, but is '"</span> << to_string<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">"'</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> @@ -96,7 +89,7 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa raise << <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 << <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> - <span class="Normal">if</span> <span class="Delimiter">(</span>s<span class="Delimiter">-></span>right<span class="Delimiter">)</span> raise << <span class="Constant">"slot 0 should have a single value in /names, but got '"</span> << to_string<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">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!s<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> raise << <span class="Constant">"slot 0 should have a single value in /names, but got '"</span> << to_string<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">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Normal">const</span> string& surrounding_recipe_name = s<span class="Delimiter">-></span>value<span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>surrounding_recipe_name<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span> raise << <span class="Constant">"slot 0 doesn't initialize its /names property in recipe '"</span> << get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> @@ -127,7 +120,7 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa <span class="Identifier">return</span> Name[default_recipe][x<span class="Delimiter">.</span>name]<span class="Delimiter">;</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> - <span class="Normal">if</span> <span class="Delimiter">(</span>!p || p<span class="Delimiter">-></span>right<span class="Delimiter">)</span> raise << <span class="Constant">"/space property should have exactly one (non-negative integer) value</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!p || !p<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> raise << <span class="Constant">"/space property should have exactly one (non-negative integer) value</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Normal">int</span> 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> @@ -171,7 +164,7 @@ recipe_ordinal lookup_surrounding_recipe<span class="Delimiter">(</span><span cl <span class="Normal">bool</span> already_transformed<span class="Delimiter">(</span><span class="Normal">const</span> reagent& r<span class="Delimiter">,</span> <span class="Normal">const</span> map<string<span class="Delimiter">,</span> <span class="Normal">int</span>>& names<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">"space"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> string_tree* p = property<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">"space"</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!p || p<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!p || !p<span class="Delimiter">-></span>atom<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="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> diff --git a/html/046global.cc.html b/html/046global.cc.html index 1d68aa01..11a22b6b 100644 --- a/html/046global.cc.html +++ b/html/046global.cc.html @@ -76,16 +76,8 @@ def main [ global_space = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">:(after "Begin Preprocess write_memory(x, data)")</span> <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name == <span class="Constant">"global-space"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>data<span class="Delimiter">)</span> - || !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> + <span class="Normal">if</span> <span class="Delimiter">(</span>!scalar<span class="Delimiter">(</span>data<span class="Delimiter">)</span> || !is_space<span class="Delimiter">(</span>x<span class="Delimiter">))</span> raise << 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>x<span class="Delimiter">.</span>type<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="Normal">if</span> <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-></span>global_space<span class="Delimiter">)</span> raise << <span class="Constant">"routine already has a global-space; you can't over-write your globals"</span> << end<span class="Delimiter">();</span> Current_routine<span class="Delimiter">-></span>global_space = data<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> @@ -119,11 +111,8 @@ $error: <span class="Constant">0</span> <span class="Delimiter">:(code)</span> <span class="Normal">bool</span> is_global<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>first == <span class="Constant">"space"</span><span class="Delimiter">)</span> - <span class="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> + string_tree* s = property<span class="Delimiter">(</span>x<span class="Delimiter">,</span> <span class="Constant">"space"</span><span class="Delimiter">);</span> + <span class="Identifier">return</span> s && s<span class="Delimiter">-></span>atom && s<span class="Delimiter">-></span>value == <span class="Constant">"global"</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> </pre> </body> diff --git a/html/047check_type_by_name.cc.html b/html/047check_type_by_name.cc.html index b67e8b36..507c7c2d 100644 --- a/html/047check_type_by_name.cc.html +++ b/html/047check_type_by_name.cc.html @@ -88,7 +88,7 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa raise << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"'"</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="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name == <span class="Constant">"array"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_array<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"'"</span> << x<span class="Delimiter">.</span>name << <span class="Constant">": can't be just an array. What is it an array of?</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> <span class="Identifier">return</span><span class="Delimiter">;</span> diff --git a/html/050scenario.cc.html b/html/050scenario.cc.html index 1ec3e9b2..7281a95b 100644 --- a/html/050scenario.cc.html +++ b/html/050scenario.cc.html @@ -196,6 +196,7 @@ Hide_missing_default_space_errors = <span class="Constant">false</span><span cla <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Globals")</span> +<span class="Comment">// this isn't a constant, just a global of type const*</span> <span class="Normal">const</span> scenario* Current_scenario = <span class="Constant">NULL</span><span class="Delimiter">;</span> <span class="Delimiter">:(code)</span> <span class="Normal">void</span> run_mu_scenario<span class="Delimiter">(</span><span class="Normal">const</span> scenario& s<span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -266,7 +267,7 @@ Name[r][<span class="Constant">"__maybe_make_raw_test__"</span>] = Res bind_special_scenario_names<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> transform_all<span class="Delimiter">();</span> run<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span> - CHECK<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> + CHECK_EQ<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="Delimiter">}</span> <span class="Comment">//: Watch out for redefinitions of scenario routines. We should never ever be</span> @@ -424,9 +425,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Normal">void</span> check_type<span class="Delimiter">(</span><span class="Normal">const</span> string& lhs<span class="Delimiter">,</span> istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> reagent x<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name == <span class="Constant">"array"</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>name == <span class="Constant">"character"</span> - && !x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_array<span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">)</span> && is_mu_character<span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">))</span> <span class="Delimiter">{</span> x<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>to_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">));</span> skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span> string _assign = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span> diff --git a/html/054static_dispatch.cc.html b/html/054static_dispatch.cc.html index dec0d19e..d47162c6 100644 --- a/html/054static_dispatch.cc.html +++ b/html/054static_dispatch.cc.html @@ -345,9 +345,8 @@ vector<recipe_ordinal> strictly_matching_variants_except_literal_against_a <span class="Delimiter">}</span> <span class="Normal">bool</span> types_strictly_match_except_literal_against_address_or_boolean<span class="Delimiter">(</span><span class="Normal">const</span> reagent& to<span class="Delimiter">,</span> <span class="Normal">const</span> reagent& from<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>from<span class="Delimiter">)</span> - && to<span class="Delimiter">.</span>type && to<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"boolean"</span><span class="Delimiter">))</span> - <span class="Identifier">return</span> boolean_matches_literal<span class="Delimiter">(</span>to<span class="Delimiter">,</span> from<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>from<span class="Delimiter">)</span> && is_mu_boolean<span class="Delimiter">(</span>to<span class="Delimiter">))</span> + <span class="Identifier">return</span> from<span class="Delimiter">.</span>name == <span class="Constant">"0"</span> || from<span class="Delimiter">.</span>name == <span class="Constant">"1"</span><span class="Delimiter">;</span> <span class="Identifier">return</span> types_strictly_match_except_literal_zero_against_address<span class="Delimiter">(</span>to<span class="Delimiter">,</span> from<span class="Delimiter">);</span> <span class="Delimiter">}</span> diff --git a/html/055shape_shifting_container.cc.html b/html/055shape_shifting_container.cc.html index a50c090b..cb17f5bb 100644 --- a/html/055shape_shifting_container.cc.html +++ b/html/055shape_shifting_container.cc.html @@ -14,14 +14,15 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background- body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 12pt; font-size: 1em; } .Constant { color: #00a0a0; } -.cSpecial { color: #008000; } -.traceContains { color: #008000; } .Special { color: #c00000; } +.traceContains { color: #008000; } +.cSpecial { color: #008000; } +.Comment { color: #9090ff; } .Delimiter { color: #800080; } .SalientComment { color: #00ffff; } .Identifier { color: #fcb165; } .Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } -.Comment { color: #9090ff; } +.CommentedCode { color: #6c6c6c; } --> </style> @@ -35,6 +36,15 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <pre id='vimCodeElement'> <span class="SalientComment">//:: Container definitions can contain 'type ingredients'</span> +<span class="Comment">//: pre-requisite: extend our notion of containers to not necessarily be</span> +<span class="Comment">//: atomic types</span> +<span class="Delimiter">:(before "End is_mu_container(type) Special-cases")</span> +<span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> + <span class="Identifier">return</span> is_mu_container<span class="Delimiter">(</span>root_type<span class="Delimiter">(</span>type<span class="Delimiter">));</span> +<span class="Delimiter">:(before "End is_mu_exclusive_container(type) Special-cases")</span> +<span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> + <span class="Identifier">return</span> is_mu_exclusive_container<span class="Delimiter">(</span>root_type<span class="Delimiter">(</span>type<span class="Delimiter">));</span> + <span class="Delimiter">:(scenario size_of_shape_shifting_container)</span> container foo:_t [ <span class="Normal">x</span>:_t @@ -120,7 +130,7 @@ container foo:t [ <span class="Comment">// ingredient _elem in foo's type_info will have value START_TYPE_INGREDIENTS,</span> <span class="Comment">// and we'll handle it by looking in the current reagent for the next type</span> <span class="Comment">// that appears after foo.</span> -<span class="Normal">const</span> <span class="Normal">int</span> START_TYPE_INGREDIENTS = <span class="Constant">2000</span><span class="Delimiter">;</span> +<span class="Normal">extern</span> <span class="Normal">const</span> <span class="Normal">int</span> START_TYPE_INGREDIENTS = <span class="Constant">2000</span><span class="Delimiter">;</span> <span class="Delimiter">:(before "End Commandline Parsing")</span> <span class="Comment">// after loading .mu files</span> assert<span class="Delimiter">(</span>Next_type_ordinal < START_TYPE_INGREDIENTS<span class="Delimiter">);</span> @@ -236,7 +246,7 @@ def main [ <span class="traceContains">+mem: storing 23 in location 7</span> <span class="traceContains">+run: reply</span> <span class="Comment"># no other stores</span> -<span class="Special">% CHECK(trace_count_prefix("mem", "storing") == 7);</span> +<span class="Special">% CHECK_EQ(trace_count_prefix("mem", "storing"), 7);</span> <span class="Delimiter">:(scenario get_on_shape_shifting_container)</span> container foo:_t [ @@ -302,10 +312,10 @@ def main [ <span class="Delimiter">:(before "End element_type Special-cases")</span> replace_type_ingredients<span class="Delimiter">(</span>element<span class="Delimiter">,</span> type<span class="Delimiter">,</span> info<span class="Delimiter">);</span> -<span class="Delimiter">:(before "Compute Container Size(element)")</span> -replace_type_ingredients<span class="Delimiter">(</span>element<span class="Delimiter">,</span> type<span class="Delimiter">,</span> info<span class="Delimiter">);</span> -<span class="Delimiter">:(before "Compute Exclusive Container Size(element)")</span> -replace_type_ingredients<span class="Delimiter">(</span>element<span class="Delimiter">,</span> type<span class="Delimiter">,</span> info<span class="Delimiter">);</span> +<span class="Delimiter">:(before "Compute Container Size(element, full_type)")</span> +replace_type_ingredients<span class="Delimiter">(</span>element<span class="Delimiter">,</span> full_type<span class="Delimiter">,</span> container_info<span class="Delimiter">);</span> +<span class="Delimiter">:(before "Compute Exclusive Container Size(element, full_type)")</span> +replace_type_ingredients<span class="Delimiter">(</span>element<span class="Delimiter">,</span> full_type<span class="Delimiter">,</span> exclusive_container_info<span class="Delimiter">);</span> <span class="Delimiter">:(before "Compute Container Address Offset(element)")</span> replace_type_ingredients<span class="Delimiter">(</span>element<span class="Delimiter">,</span> type<span class="Delimiter">,</span> info<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>contains_type_ingredient<span class="Delimiter">(</span>element<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// error raised elsewhere</span> @@ -331,63 +341,42 @@ assert<span class="Delimiter">(</span>!contains_type_ingredient<span class="Deli <span class="Normal">bool</span> contains_type_ingredient<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <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="Normal">if</span> <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> - assert<span class="Delimiter">(</span>!is_type_ingredient_name<span class="Delimiter">(</span>type<span class="Delimiter">-></span>name<span class="Delimiter">));</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> type<span class="Delimiter">-></span>value >= START_TYPE_INGREDIENTS<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> <span class="Comment">// replace all type_ingredients in element_type with corresponding elements of callsite_type</span> -<span class="Comment">// todo: too complicated and likely incomplete; maybe avoid replacing in place?</span> <span class="Normal">void</span> replace_type_ingredients<span class="Delimiter">(</span>type_tree* element_type<span class="Delimiter">,</span> <span class="Normal">const</span> type_tree* callsite_type<span class="Delimiter">,</span> <span class="Normal">const</span> type_info& container_info<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <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> <span class="Normal">if</span> <span class="Delimiter">(</span>!element_type<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> - - <span class="Comment">// A. recurse first to avoid nested replaces (which I can't reason about yet)</span> - replace_type_ingredients<span class="Delimiter">(</span>element_type<span class="Delimiter">-></span>left<span class="Delimiter">,</span> callsite_type<span class="Delimiter">,</span> container_info<span class="Delimiter">);</span> - replace_type_ingredients<span class="Delimiter">(</span>element_type<span class="Delimiter">-></span>right<span class="Delimiter">,</span> callsite_type<span class="Delimiter">,</span> container_info<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!element_type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> + replace_type_ingredients<span class="Delimiter">(</span>element_type<span class="Delimiter">-></span>left<span class="Delimiter">,</span> callsite_type<span class="Delimiter">,</span> container_info<span class="Delimiter">);</span> + replace_type_ingredients<span class="Delimiter">(</span>element_type<span class="Delimiter">-></span>right<span class="Delimiter">,</span> callsite_type<span class="Delimiter">,</span> container_info<span class="Delimiter">);</span> + <span class="Identifier">return</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>element_type<span class="Delimiter">-></span>value < START_TYPE_INGREDIENTS<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> - <span class="Normal">const</span> <span class="Normal">int</span> type_ingredient_index = element_type<span class="Delimiter">-></span>value-START_TYPE_INGREDIENTS<span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!has_nth_type<span class="Delimiter">(</span>callsite_type<span class="Delimiter">,</span> type_ingredient_index<span class="Delimiter">))</span> <span class="Delimiter">{</span> raise << <span class="Constant">"illegal type "</span> << names_to_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> + *element_type = *nth_type_ingredient<span class="Delimiter">(</span>callsite_type<span class="Delimiter">,</span> type_ingredient_index<span class="Delimiter">,</span> container_info<span class="Delimiter">);</span> +<span class="Delimiter">}</span> - <span class="Comment">// B. replace the current location</span> - <span class="Normal">const</span> type_tree* replacement = <span class="Constant">NULL</span><span class="Delimiter">;</span> - <span class="Normal">bool</span> zig_left = <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Delimiter">{</span> - <span class="Normal">const</span> type_tree* curr = callsite_type<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < type_ingredient_index<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> - curr = curr<span class="Delimiter">-></span>right<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr && curr<span class="Delimiter">-></span>left<span class="Delimiter">)</span> <span class="Delimiter">{</span> - replacement = curr<span class="Delimiter">-></span>left<span class="Delimiter">;</span> - zig_left = <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> - <span class="Comment">// We want foo:_t to be used like foo:number, which expands to {foo: number}</span> - <span class="Comment">// rather than {foo: (number)}</span> - <span class="Comment">// We'd also like to use it with multiple types: foo:address:number.</span> - replacement = curr<span class="Delimiter">;</span> - <span class="Delimiter">}</span> - <span class="Delimiter">}</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>element_type<span class="Delimiter">-></span>right && replacement<span class="Delimiter">-></span>right && zig_left<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// ZERO confidence that this condition is accurate</span> - element_type<span class="Delimiter">-></span>name = <span class="Constant">""</span><span class="Delimiter">;</span> - element_type<span class="Delimiter">-></span>value = <span class="Constant">0</span><span class="Delimiter">;</span> - element_type<span class="Delimiter">-></span>left = <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*replacement<span class="Delimiter">);</span> - <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> - string old_name = element_type<span class="Delimiter">-></span>name<span class="Delimiter">;</span> - element_type<span class="Delimiter">-></span>name = replacement<span class="Delimiter">-></span>name<span class="Delimiter">;</span> - element_type<span class="Delimiter">-></span>value = replacement<span class="Delimiter">-></span>value<span class="Delimiter">;</span> - assert<span class="Delimiter">(</span>!element_type<span class="Delimiter">-></span>left<span class="Delimiter">);</span> <span class="Comment">// since value is set</span> - element_type<span class="Delimiter">-></span>left = replacement<span class="Delimiter">-></span>left ? <span class="Normal">new</span> 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> - <span class="Normal">if</span> <span class="Delimiter">(</span>zig_left || final_type_ingredient<span class="Delimiter">(</span>type_ingredient_index<span class="Delimiter">,</span> container_info<span class="Delimiter">))</span> <span class="Delimiter">{</span> - type_tree* old_right = element_type<span class="Delimiter">-></span>right<span class="Delimiter">;</span> - element_type<span class="Delimiter">-></span>right = replacement<span class="Delimiter">-></span>right ? <span class="Normal">new</span> 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> - append<span class="Delimiter">(</span>element_type<span class="Delimiter">-></span>right<span class="Delimiter">,</span> old_right<span class="Delimiter">);</span> - <span class="Delimiter">}</span> +<span class="Normal">const</span> type_tree* nth_type_ingredient<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* callsite_type<span class="Delimiter">,</span> <span class="Normal">int</span> type_ingredient_index<span class="Delimiter">,</span> <span class="Normal">const</span> type_info& container_info<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">bool</span> <span class="Normal">final</span> = final_type_ingredient<span class="Delimiter">(</span>type_ingredient_index<span class="Delimiter">,</span> container_info<span class="Delimiter">);</span> + <span class="Normal">const</span> type_tree* curr = callsite_type<span class="Delimiter">;</span> + <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < type_ingredient_index<span class="Delimiter">;</span> ++i<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>atom<span class="Delimiter">);</span> +<span class="CommentedCode">//? cerr << "type ingredient " << i << " is " << to_string(curr->left) << '\n';</span> + curr = curr<span class="Delimiter">-></span>right<span class="Delimiter">;</span> <span class="Delimiter">}</span> + assert<span class="Delimiter">(</span>curr<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> curr<span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!<span class="Normal">final</span><span class="Delimiter">)</span> <span class="Identifier">return</span> curr<span class="Delimiter">-></span>left<span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!curr<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Identifier">return</span> curr<span class="Delimiter">-></span>left<span class="Delimiter">;</span> + <span class="Identifier">return</span> curr<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">bool</span> final_type_ingredient<span class="Delimiter">(</span><span class="Normal">int</span> type_ingredient_index<span class="Delimiter">,</span> <span class="Normal">const</span> type_info& container_info<span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -399,26 +388,7 @@ assert<span class="Delimiter">(</span>!contains_type_ingredient<span class="Deli <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> append<span class="Delimiter">(</span>type_tree*& base<span class="Delimiter">,</span> type_tree* extra<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!base<span class="Delimiter">)</span> <span class="Delimiter">{</span> - base = extra<span class="Delimiter">;</span> - <span class="Identifier">return</span><span class="Delimiter">;</span> - <span class="Delimiter">}</span> - type_tree* curr = base<span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>curr<span class="Delimiter">-></span>right<span class="Delimiter">)</span> curr = curr<span class="Delimiter">-></span>right<span class="Delimiter">;</span> - curr<span class="Delimiter">-></span>right = extra<span class="Delimiter">;</span> -<span class="Delimiter">}</span> - -<span class="Normal">void</span> append<span class="Delimiter">(</span>string_tree*& base<span class="Delimiter">,</span> string_tree* extra<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!base<span class="Delimiter">)</span> <span class="Delimiter">{</span> - base = extra<span class="Delimiter">;</span> - <span class="Identifier">return</span><span class="Delimiter">;</span> - <span class="Delimiter">}</span> - string_tree* curr = base<span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>curr<span class="Delimiter">-></span>right<span class="Delimiter">)</span> curr = curr<span class="Delimiter">-></span>right<span class="Delimiter">;</span> - curr<span class="Delimiter">-></span>right = extra<span class="Delimiter">;</span> -<span class="Delimiter">}</span> - +<span class="Delimiter">:(before "End Unit Tests")</span> <span class="Normal">void</span> test_replace_type_ingredients_entire<span class="Delimiter">()</span> <span class="Delimiter">{</span> run<span class="Delimiter">(</span><span class="Constant">"container foo:_elem [</span><span class="cSpecial">\n</span><span class="Constant">"</span> <span class="Constant">" x:_elem</span><span class="cSpecial">\n</span><span class="Constant">"</span> @@ -426,9 +396,7 @@ assert<span class="Delimiter">(</span>!contains_type_ingredient<span class="Deli <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> reagent callsite<span class="Delimiter">(</span><span class="Constant">"x:foo:point"</span><span class="Delimiter">);</span> reagent element = element_type<span class="Delimiter">(</span>callsite<span class="Delimiter">.</span>type<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>name<span class="Delimiter">,</span> <span class="Constant">"x"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"point"</span><span class="Delimiter">);</span> - CHECK<span class="Delimiter">(</span>!element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>to_string<span class="Delimiter">(</span>element<span class="Delimiter">),</span> <span class="Constant">"{x: </span><span class="cSpecial">\"</span><span class="Constant">point</span><span class="cSpecial">\"</span><span class="Constant">}"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">void</span> test_replace_type_ingredients_tail<span class="Delimiter">()</span> <span class="Delimiter">{</span> @@ -440,10 +408,7 @@ assert<span class="Delimiter">(</span>!contains_type_ingredient<span class="Deli <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> reagent callsite<span class="Delimiter">(</span><span class="Constant">"x:bar:point"</span><span class="Delimiter">);</span> reagent element = element_type<span class="Delimiter">(</span>callsite<span class="Delimiter">.</span>type<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>name<span class="Delimiter">,</span> <span class="Constant">"x"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"foo"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"point"</span><span class="Delimiter">);</span> - CHECK<span class="Delimiter">(</span>!element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>to_string<span class="Delimiter">(</span>element<span class="Delimiter">),</span> <span class="Constant">"{x: (</span><span class="cSpecial">\"</span><span class="Constant">foo</span><span class="cSpecial">\"</span><span class="Constant"> </span><span class="cSpecial">\"</span><span class="Constant">point</span><span class="cSpecial">\"</span><span class="Constant">)}"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">void</span> test_replace_type_ingredients_head_tail_multiple<span class="Delimiter">()</span> <span class="Delimiter">{</span> @@ -455,12 +420,7 @@ assert<span class="Delimiter">(</span>!contains_type_ingredient<span class="Deli <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> reagent callsite<span class="Delimiter">(</span><span class="Constant">"x:bar:address:array:character"</span><span class="Delimiter">);</span> reagent element = element_type<span class="Delimiter">(</span>callsite<span class="Delimiter">.</span>type<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>name<span class="Delimiter">,</span> <span class="Constant">"x"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"foo"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"character"</span><span class="Delimiter">);</span> - CHECK<span class="Delimiter">(</span>!element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>to_string<span class="Delimiter">(</span>element<span class="Delimiter">),</span> <span class="Constant">"{x: (</span><span class="cSpecial">\"</span><span class="Constant">foo</span><span class="cSpecial">\"</span><span class="Constant"> </span><span class="cSpecial">\"</span><span class="Constant">address</span><span class="cSpecial">\"</span><span class="Constant"> </span><span class="cSpecial">\"</span><span class="Constant">array</span><span class="cSpecial">\"</span><span class="Constant"> </span><span class="cSpecial">\"</span><span class="Constant">character</span><span class="cSpecial">\"</span><span class="Constant">)}"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">void</span> test_replace_type_ingredients_head_middle<span class="Delimiter">()</span> <span class="Delimiter">{</span> @@ -472,14 +432,7 @@ assert<span class="Delimiter">(</span>!contains_type_ingredient<span class="Deli <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> reagent callsite<span class="Delimiter">(</span><span class="Constant">"x:bar:address"</span><span class="Delimiter">);</span> reagent element = element_type<span class="Delimiter">(</span>callsite<span class="Delimiter">.</span>type<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>name<span class="Delimiter">,</span> <span class="Constant">"x"</span><span class="Delimiter">);</span> - CHECK<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">)</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"foo"</span><span class="Delimiter">);</span> - CHECK<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">)</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">);</span> - CHECK<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">)</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> - CHECK<span class="Delimiter">(</span>!element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>to_string<span class="Delimiter">(</span>element<span class="Delimiter">),</span> <span class="Constant">"{x: (</span><span class="cSpecial">\"</span><span class="Constant">foo</span><span class="cSpecial">\"</span><span class="Constant"> </span><span class="cSpecial">\"</span><span class="Constant">address</span><span class="cSpecial">\"</span><span class="Constant"> </span><span class="cSpecial">\"</span><span class="Constant">number</span><span class="cSpecial">\"</span><span class="Constant">)}"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">void</span> test_replace_last_type_ingredient_with_multiple<span class="Delimiter">()</span> <span class="Delimiter">{</span> @@ -489,15 +442,9 @@ assert<span class="Delimiter">(</span>!contains_type_ingredient<span class="Deli <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> reagent callsite<span class="Delimiter">(</span><span class="Constant">"{f: (foo number (address array character))}"</span><span class="Delimiter">);</span> reagent element1 = element_type<span class="Delimiter">(</span>callsite<span class="Delimiter">.</span>type<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element1<span class="Delimiter">.</span>name<span class="Delimiter">,</span> <span class="Constant">"x"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element1<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> - CHECK<span class="Delimiter">(</span>!element1<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>to_string<span class="Delimiter">(</span>element1<span class="Delimiter">),</span> <span class="Constant">"{x: </span><span class="cSpecial">\"</span><span class="Constant">number</span><span class="cSpecial">\"</span><span class="Constant">}"</span><span class="Delimiter">);</span> reagent element2 = element_type<span class="Delimiter">(</span>callsite<span class="Delimiter">.</span>type<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element2<span class="Delimiter">.</span>name<span class="Delimiter">,</span> <span class="Constant">"y"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element2<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element2<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element2<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"character"</span><span class="Delimiter">);</span> - CHECK<span class="Delimiter">(</span>!element2<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>to_string<span class="Delimiter">(</span>element2<span class="Delimiter">),</span> <span class="Constant">"{y: (</span><span class="cSpecial">\"</span><span class="Constant">address</span><span class="cSpecial">\"</span><span class="Constant"> </span><span class="cSpecial">\"</span><span class="Constant">array</span><span class="cSpecial">\"</span><span class="Constant"> </span><span class="cSpecial">\"</span><span class="Constant">character</span><span class="cSpecial">\"</span><span class="Constant">)}"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">void</span> test_replace_middle_type_ingredient_with_multiple<span class="Delimiter">()</span> <span class="Delimiter">{</span> @@ -508,19 +455,11 @@ assert<span class="Delimiter">(</span>!contains_type_ingredient<span class="Deli <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> reagent callsite<span class="Delimiter">(</span><span class="Constant">"{f: (foo number (address array character) boolean)}"</span><span class="Delimiter">);</span> reagent element1 = element_type<span class="Delimiter">(</span>callsite<span class="Delimiter">.</span>type<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element1<span class="Delimiter">.</span>name<span class="Delimiter">,</span> <span class="Constant">"x"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element1<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> - CHECK<span class="Delimiter">(</span>!element1<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>to_string<span class="Delimiter">(</span>element1<span class="Delimiter">),</span> <span class="Constant">"{x: </span><span class="cSpecial">\"</span><span class="Constant">number</span><span class="cSpecial">\"</span><span class="Constant">}"</span><span class="Delimiter">);</span> reagent element2 = element_type<span class="Delimiter">(</span>callsite<span class="Delimiter">.</span>type<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element2<span class="Delimiter">.</span>name<span class="Delimiter">,</span> <span class="Constant">"y"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element2<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element2<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element2<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"character"</span><span class="Delimiter">);</span> - CHECK<span class="Delimiter">(</span>!element2<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>to_string<span class="Delimiter">(</span>element2<span class="Delimiter">),</span> <span class="Constant">"{y: (</span><span class="cSpecial">\"</span><span class="Constant">address</span><span class="cSpecial">\"</span><span class="Constant"> </span><span class="cSpecial">\"</span><span class="Constant">array</span><span class="cSpecial">\"</span><span class="Constant"> </span><span class="cSpecial">\"</span><span class="Constant">character</span><span class="cSpecial">\"</span><span class="Constant">)}"</span><span class="Delimiter">);</span> reagent element3 = element_type<span class="Delimiter">(</span>callsite<span class="Delimiter">.</span>type<span class="Delimiter">,</span> <span class="Constant">2</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element3<span class="Delimiter">.</span>name<span class="Delimiter">,</span> <span class="Constant">"z"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element3<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"boolean"</span><span class="Delimiter">);</span> - CHECK<span class="Delimiter">(</span>!element3<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>to_string<span class="Delimiter">(</span>element3<span class="Delimiter">),</span> <span class="Constant">"{z: </span><span class="cSpecial">\"</span><span class="Constant">boolean</span><span class="cSpecial">\"</span><span class="Constant">}"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">void</span> test_replace_middle_type_ingredient_with_multiple2<span class="Delimiter">()</span> <span class="Delimiter">{</span> @@ -530,11 +469,7 @@ assert<span class="Delimiter">(</span>!contains_type_ingredient<span class="Deli <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> reagent callsite<span class="Delimiter">(</span><span class="Constant">"{f: (foo (address array character) number)}"</span><span class="Delimiter">);</span> reagent element = element_type<span class="Delimiter">(</span>callsite<span class="Delimiter">.</span>type<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>name<span class="Delimiter">,</span> <span class="Constant">"key"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"character"</span><span class="Delimiter">);</span> - CHECK<span class="Delimiter">(</span>!element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>to_string<span class="Delimiter">(</span>element<span class="Delimiter">),</span> <span class="Constant">"{key: (</span><span class="cSpecial">\"</span><span class="Constant">address</span><span class="cSpecial">\"</span><span class="Constant"> </span><span class="cSpecial">\"</span><span class="Constant">array</span><span class="cSpecial">\"</span><span class="Constant"> </span><span class="cSpecial">\"</span><span class="Constant">character</span><span class="cSpecial">\"</span><span class="Constant">)}"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">void</span> test_replace_middle_type_ingredient_with_multiple3<span class="Delimiter">()</span> <span class="Delimiter">{</span> @@ -548,18 +483,10 @@ assert<span class="Delimiter">(</span>!contains_type_ingredient<span class="Deli <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> reagent callsite<span class="Delimiter">(</span><span class="Constant">"{f: (foo_table (address array character) number)}"</span><span class="Delimiter">);</span> reagent element = element_type<span class="Delimiter">(</span>callsite<span class="Delimiter">.</span>type<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>name<span class="Delimiter">,</span> <span class="Constant">"data"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"foo_table_row"</span><span class="Delimiter">);</span> - CHECK<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>left<span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>left<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"address"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>left<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"array"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>left<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"character"</span><span class="Delimiter">);</span> - CHECK_EQ<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> - CHECK<span class="Delimiter">(</span>!element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">-></span>right<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>to_string<span class="Delimiter">(</span>element<span class="Delimiter">),</span> <span class="Constant">"{data: (</span><span class="cSpecial">\"</span><span class="Constant">address</span><span class="cSpecial">\"</span><span class="Constant"> </span><span class="cSpecial">\"</span><span class="Constant">array</span><span class="cSpecial">\"</span><span class="Constant"> </span><span class="cSpecial">\"</span><span class="Constant">foo_table_row</span><span class="cSpecial">\"</span><span class="Constant"> (</span><span class="cSpecial">\"</span><span class="Constant">address</span><span class="cSpecial">\"</span><span class="Constant"> </span><span class="cSpecial">\"</span><span class="Constant">array</span><span class="cSpecial">\"</span><span class="Constant"> </span><span class="cSpecial">\"</span><span class="Constant">character</span><span class="cSpecial">\"</span><span class="Constant">) </span><span class="cSpecial">\"</span><span class="Constant">number</span><span class="cSpecial">\"</span><span class="Constant">)}"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> +<span class="Delimiter">:(code)</span> <span class="Normal">bool</span> has_nth_type<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* base<span class="Delimiter">,</span> <span class="Normal">int</span> n<span class="Delimiter">)</span> <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>n >= <span class="Constant">0</span><span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!base<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> @@ -579,7 +506,128 @@ def main [ ] <span class="traceContains">+error: illegal type "foo" seems to be missing a type ingredient or three</span> -<span class="Comment">//: 'merge' on shape-shifting containers</span> +<span class="SalientComment">//:: fix up previous layers</span> + +<span class="Comment">//: We have two transforms in previous layers -- for computing sizes and</span> +<span class="Comment">//: offsets containing addresses for containers and exclusive containers --</span> +<span class="Comment">//: that we need to teach about type ingredients.</span> + +<span class="Delimiter">:(before "End compute_container_sizes Non-atom Cases")</span> +<span class="Normal">const</span> type_tree* root = root_type<span class="Delimiter">(</span>type<span class="Delimiter">);</span> +type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root<span class="Delimiter">-></span>value<span class="Delimiter">);</span> +<span class="Normal">if</span> <span class="Delimiter">(</span>info<span class="Delimiter">.</span>kind == CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span> + compute_container_sizes<span class="Delimiter">(</span>info<span class="Delimiter">,</span> type<span class="Delimiter">,</span> pending_metadata<span class="Delimiter">);</span> + <span class="Identifier">return</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> +<span class="Normal">if</span> <span class="Delimiter">(</span>info<span class="Delimiter">.</span>kind == EXCLUSIVE_CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span> + compute_exclusive_container_sizes<span class="Delimiter">(</span>info<span class="Delimiter">,</span> type<span class="Delimiter">,</span> pending_metadata<span class="Delimiter">);</span> + <span class="Identifier">return</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +<span class="Delimiter">:(before "End Unit Tests")</span> +<span class="Normal">void</span> test_container_sizes_shape_shifting_container<span class="Delimiter">()</span> <span class="Delimiter">{</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo:_t [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" y:_t</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> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:foo:point"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>size<span class="Delimiter">,</span> <span class="Constant">3</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_sizes_shape_shifting_exclusive_container<span class="Delimiter">()</span> <span class="Delimiter">{</span> + run<span class="Delimiter">(</span><span class="Constant">"exclusive-container foo:_t [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" y:_t</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> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:foo:point"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>size<span class="Delimiter">,</span> <span class="Constant">3</span><span class="Delimiter">);</span> + reagent r2<span class="Delimiter">(</span><span class="Constant">"x:foo:number"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r2<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>r2<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>size<span class="Delimiter">,</span> <span class="Constant">2</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_sizes_compound_type_ingredient<span class="Delimiter">()</span> <span class="Delimiter">{</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo:_t [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" y:_t</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> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:foo:address:point"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>size<span class="Delimiter">,</span> <span class="Constant">2</span><span class="Delimiter">);</span> + <span class="Comment">// scan also pre-computes metadata for type ingredient</span> + reagent point<span class="Delimiter">(</span><span class="Constant">"x:point"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> point<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + CHECK_EQ<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> point<span class="Delimiter">.</span>type<span class="Delimiter">).</span>size<span class="Delimiter">,</span> <span class="Constant">2</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_sizes_recursive_shape_shifting_container<span class="Delimiter">()</span> <span class="Delimiter">{</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo:_t [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" y:address:foo:_t</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> + reagent r2<span class="Delimiter">(</span><span class="Constant">"x:foo:number"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r2<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>r2<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>size<span class="Delimiter">,</span> <span class="Constant">2</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Delimiter">:(before "End compute_container_address_offsets Non-atom Cases")</span> +<span class="Normal">const</span> type_tree* root = root_type<span class="Delimiter">(</span>type<span class="Delimiter">);</span> +type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root<span class="Delimiter">-></span>value<span class="Delimiter">);</span> +<span class="Normal">if</span> <span class="Delimiter">(</span>info<span class="Delimiter">.</span>kind == CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span> + compute_container_address_offsets<span class="Delimiter">(</span>info<span class="Delimiter">,</span> type<span class="Delimiter">);</span> + <span class="Identifier">return</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> +<span class="Normal">if</span> <span class="Delimiter">(</span>info<span class="Delimiter">.</span>kind == EXCLUSIVE_CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span> + compute_exclusive_container_address_offsets<span class="Delimiter">(</span>info<span class="Delimiter">,</span> type<span class="Delimiter">);</span> + <span class="Identifier">return</span><span class="Delimiter">;</span> +<span class="Delimiter">}</span> + +<span class="Delimiter">:(before "End Unit Tests")</span> +<span class="Normal">void</span> test_container_address_offsets_in_shape_shifting_container<span class="Delimiter">()</span> <span class="Delimiter">{</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo:_t [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" y:_t</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> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:foo:address:number"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">()));</span> + set<address_element_info>& offset_info = get<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>offset_info<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>offset_info<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> <span class="Comment">//</span> + CHECK<span class="Delimiter">(</span>offset_info<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>offset_info<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_address_offsets_in_nested_shape_shifting_container<span class="Delimiter">()</span> <span class="Delimiter">{</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo:_t [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" y:_t</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">"container bar:_t [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:_t</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" y:foo:_t</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> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:bar:address:number"</span><span class="Delimiter">);</span> + CLEAR_TRACE<span class="Delimiter">;</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">()));</span> + set<address_element_info>& offset_info = get<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>offset_info<span class="Delimiter">),</span> <span class="Constant">2</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>offset_info<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> <span class="Comment">//</span> + CHECK<span class="Delimiter">(</span>offset_info<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>offset_info<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">((</span>++offset_info<span class="Delimiter">.</span>begin<span class="Delimiter">())-></span>offset<span class="Delimiter">,</span> <span class="Constant">2</span><span class="Delimiter">);</span> <span class="Comment">//</span> + CHECK<span class="Delimiter">((</span>++offset_info<span class="Delimiter">.</span>begin<span class="Delimiter">())-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">((</span>++offset_info<span class="Delimiter">.</span>begin<span class="Delimiter">())-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="SalientComment">//:: 'merge' on shape-shifting containers</span> <span class="Delimiter">:(scenario merge_check_shape_shifting_container_containing_exclusive_container)</span> container foo:_elem [ diff --git a/html/056shape_shifting_recipe.cc.html b/html/056shape_shifting_recipe.cc.html index 2302862c..f03430ff 100644 --- a/html/056shape_shifting_recipe.cc.html +++ b/html/056shape_shifting_recipe.cc.html @@ -134,8 +134,8 @@ vector<recipe_ordinal> strictly_matching_shape_shifting_variants<span clas <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>variants<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <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="Normal">if</span> <span class="Delimiter">(</span>!any_type_ingredient_in_header<span class="Delimiter">(</span>variants<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="Normal">if</span> <span class="Delimiter">(</span>all_concrete_header_reagents_strictly_match<span class="Delimiter">(</span>inst<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> - result<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!all_concrete_header_reagents_strictly_match<span class="Delimiter">(</span>inst<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="Identifier">continue</span><span class="Delimiter">;</span> + result<span class="Delimiter">.</span>push_back<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> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -229,31 +229,28 @@ recipe_ordinal best_shape_shifting_variant<span class="Delimiter">(</span><span <span class="Normal">int</span> number_of_concrete_type_names<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">int</span> result = <span class="Constant">0</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>name<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> && !is_type_ingredient_name<span class="Delimiter">(</span>type<span class="Delimiter">-></span>name<span class="Delimiter">))</span> - ++result<span class="Delimiter">;</span> - result += number_of_concrete_type_names<span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">);</span> - result += number_of_concrete_type_names<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">);</span> - <span class="Identifier">return</span> result<span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> + <span class="Identifier">return</span> is_type_ingredient_name<span class="Delimiter">(</span>type<span class="Delimiter">-></span>name<span class="Delimiter">)</span> ? <span class="Constant">0</span> : <span class="Constant">1</span><span class="Delimiter">;</span> + <span class="Identifier">return</span> number_of_concrete_type_names<span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">)</span> + + number_of_concrete_type_names<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">bool</span> concrete_type_names_strictly_match<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* to<span class="Delimiter">,</span> <span class="Normal">const</span> type_tree* from<span class="Delimiter">,</span> <span class="Normal">const</span> reagent& rhs_reagent<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!to<span class="Delimiter">)</span> <span class="Identifier">return</span> !from<span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!from<span class="Delimiter">)</span> <span class="Identifier">return</span> !to<span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>is_type_ingredient_name<span class="Delimiter">(</span>to<span class="Delimiter">-></span>name<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Comment">// type ingredient matches anything</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>to<span class="Delimiter">-></span>name == <span class="Constant">"literal"</span> && from<span class="Delimiter">-></span>name == <span class="Constant">"literal"</span><span class="Delimiter">)</span> - <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>to<span class="Delimiter">-></span>name == <span class="Constant">"literal"</span> - && Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>from<span class="Delimiter">-></span>name<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">())</span> - <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>from<span class="Delimiter">-></span>name == <span class="Constant">"literal"</span> - && Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>to<span class="Delimiter">-></span>name<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">())</span> - <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>from<span class="Delimiter">-></span>name == <span class="Constant">"literal"</span> && to<span class="Delimiter">-></span>name == <span class="Constant">"address"</span><span class="Delimiter">)</span> - <span class="Identifier">return</span> rhs_reagent<span class="Delimiter">.</span>name == <span class="Constant">"0"</span><span class="Delimiter">;</span> - <span class="Identifier">return</span> to<span class="Delimiter">-></span>name == from<span class="Delimiter">-></span>name - && concrete_type_names_strictly_match<span class="Delimiter">(</span>to<span class="Delimiter">-></span>left<span class="Delimiter">,</span> from<span class="Delimiter">-></span>left<span class="Delimiter">,</span> rhs_reagent<span class="Delimiter">)</span> - && concrete_type_names_strictly_match<span class="Delimiter">(</span>to<span class="Delimiter">-></span>right<span class="Delimiter">,</span> from<span class="Delimiter">-></span>right<span class="Delimiter">,</span> rhs_reagent<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>to<span class="Delimiter">-></span>atom && is_type_ingredient_name<span class="Delimiter">(</span>to<span class="Delimiter">-></span>name<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Comment">// type ingredient matches anything</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>from<span class="Delimiter">-></span>atom && is_mu_address<span class="Delimiter">(</span>to<span class="Delimiter">))</span> + <span class="Identifier">return</span> from<span class="Delimiter">-></span>name == <span class="Constant">"literal"</span> && rhs_reagent<span class="Delimiter">.</span>name == <span class="Constant">"0"</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!from<span class="Delimiter">-></span>atom && !to<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> + <span class="Identifier">return</span> concrete_type_names_strictly_match<span class="Delimiter">(</span>to<span class="Delimiter">-></span>left<span class="Delimiter">,</span> from<span class="Delimiter">-></span>left<span class="Delimiter">,</span> rhs_reagent<span class="Delimiter">)</span> + && concrete_type_names_strictly_match<span class="Delimiter">(</span>to<span class="Delimiter">-></span>right<span class="Delimiter">,</span> from<span class="Delimiter">-></span>right<span class="Delimiter">,</span> rhs_reagent<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>from<span class="Delimiter">-></span>atom != to<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Comment">// both from and to are atoms</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>from<span class="Delimiter">-></span>name == <span class="Constant">"literal"</span><span class="Delimiter">)</span> + <span class="Identifier">return</span> Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>to<span class="Delimiter">-></span>name<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">();</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>to<span class="Delimiter">-></span>name == <span class="Constant">"literal"</span><span class="Delimiter">)</span> + <span class="Identifier">return</span> Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>from<span class="Delimiter">-></span>name<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">();</span> + <span class="Identifier">return</span> to<span class="Delimiter">-></span>name == from<span class="Delimiter">-></span>name<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">bool</span> contains_type_ingredient_name<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -355,7 +352,7 @@ recipe_ordinal new_variant<span class="Delimiter">(</span>recipe_ordinal exempla <span class="Delimiter">}</span> <span class="Delimiter">}</span> -<span class="Normal">inline</span> <span class="Normal">int</span> min<span class="Delimiter">(</span><span class="Normal">int</span> a<span class="Delimiter">,</span> <span class="Normal">int</span> b<span class="Delimiter">)</span> <span class="Delimiter">{</span> +<span class="Normal">int</span> min<span class="Delimiter">(</span><span class="Normal">int</span> a<span class="Delimiter">,</span> <span class="Normal">int</span> b<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Identifier">return</span> <span class="Delimiter">(</span>a < b<span class="Delimiter">)</span> ? a : b<span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -374,14 +371,12 @@ recipe_ordinal new_variant<span class="Delimiter">(</span>recipe_ordinal exempla <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_type_ingredient_name<span class="Delimiter">(</span>exemplar_type<span class="Delimiter">-></span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Normal">const</span> type_tree* curr_refinement_type = <span class="Constant">NULL</span><span class="Delimiter">;</span> <span class="Comment">// temporary heap allocation; must always be deleted before it goes out of scope</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>refinement_type<span class="Delimiter">-></span>left<span class="Delimiter">)</span> - curr_refinement_type = <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*refinement_type<span class="Delimiter">-></span>left<span class="Delimiter">);</span> - <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>exemplar_type<span class="Delimiter">-></span>right<span class="Delimiter">)</span> - <span class="Comment">// splice out refinement_type->right, it'll be used later by the exemplar_type->right</span> - curr_refinement_type = <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>refinement_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> refinement_type<span class="Delimiter">-></span>value<span class="Delimiter">,</span> <span class="Constant">NULL</span><span class="Delimiter">);</span> - <span class="Normal">else</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>exemplar_type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> curr_refinement_type = <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*refinement_type<span class="Delimiter">);</span> - assert<span class="Delimiter">(</span>!curr_refinement_type<span class="Delimiter">-></span>left<span class="Delimiter">);</span> + <span class="Normal">else</span> <span class="Delimiter">{</span> + assert<span class="Delimiter">(</span>!refinement_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + curr_refinement_type = <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*refinement_type<span class="Delimiter">-></span>left<span class="Delimiter">);</span> + <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-></span>name<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>name << <span class="Constant">" to "</span> << to_string<span class="Delimiter">(</span>curr_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>name<span class="Delimiter">,</span> <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*curr_refinement_type<span class="Delimiter">));</span> @@ -443,52 +438,29 @@ recipe_ordinal new_variant<span class="Delimiter">(</span>recipe_ordinal exempla replace_type_ingredients<span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">,</span> mappings<span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Comment">// todo: too complicated and likely incomplete; maybe avoid replacing in place?</span> <span class="Normal">void</span> replace_type_ingredients<span class="Delimiter">(</span>type_tree* type<span class="Delimiter">,</span> <span class="Normal">const</span> map<string<span class="Delimiter">,</span> <span class="Normal">const</span> type_tree*>& mappings<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type<span class="Delimiter">-></span>name<span class="Delimiter">))</span> <span class="Comment">// todo: ugly side effect</span> - type<span class="Delimiter">-></span>value = get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type<span class="Delimiter">-></span>name<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!is_type_ingredient_name<span class="Delimiter">(</span>type<span class="Delimiter">-></span>name<span class="Delimiter">)</span> || !contains_key<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> type<span class="Delimiter">-></span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>atom<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="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - + <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type<span class="Delimiter">-></span>name<span class="Delimiter">))</span> <span class="Comment">// todo: ugly side effect</span> + type<span class="Delimiter">-></span>value = get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type<span class="Delimiter">-></span>name<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> type<span class="Delimiter">-></span>name<span class="Delimiter">))</span> + <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Normal">const</span> type_tree* replacement = get<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> type<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> << type<span class="Delimiter">-></span>name << <span class="Constant">" => "</span> << names_to_string<span class="Delimiter">(</span>replacement<span class="Delimiter">)</span> << end<span class="Delimiter">();</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> replacement<span class="Delimiter">-></span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span> - <span class="Comment">// error in program; should be reported elsewhere</span> - <span class="Identifier">return</span><span class="Delimiter">;</span> - <span class="Delimiter">}</span> - - <span class="Comment">// type is a single type ingredient</span> - assert<span class="Delimiter">(</span>!type<span class="Delimiter">-></span>left<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>right<span class="Delimiter">)</span> assert<span class="Delimiter">(</span>!replacement<span class="Delimiter">-></span>left<span class="Delimiter">);</span> - - <span class="Normal">if</span> <span class="Delimiter">(</span>!replacement<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!replacement<span class="Delimiter">-></span>left<span class="Delimiter">)</span> <span class="Delimiter">{</span> - type<span class="Delimiter">-></span>name = <span class="Delimiter">(</span>replacement<span class="Delimiter">-></span>name == <span class="Constant">"literal"</span><span class="Delimiter">)</span> ? <span class="Constant">"number"</span> : replacement<span class="Delimiter">-></span>name<span class="Delimiter">;</span> - type<span class="Delimiter">-></span>value = get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type<span class="Delimiter">-></span>name<span class="Delimiter">);</span> - <span class="Delimiter">}</span> - <span class="Normal">else</span> <span class="Delimiter">{</span> - type<span class="Delimiter">-></span>name = <span class="Constant">""</span><span class="Delimiter">;</span> - type<span class="Delimiter">-></span>value = <span class="Constant">0</span><span class="Delimiter">;</span> - type<span class="Delimiter">-></span>left = <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*replacement<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>replacement<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> replacement<span class="Delimiter">-></span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span> + <span class="Comment">// error in program; should be reported elsewhere</span> + <span class="Identifier">return</span><span class="Delimiter">;</span> <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> - <span class="Comment">// replace non-last type?</span> - <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> - type<span class="Delimiter">-></span>name = <span class="Constant">""</span><span class="Delimiter">;</span> - type<span class="Delimiter">-></span>value = <span class="Constant">0</span><span class="Delimiter">;</span> - type<span class="Delimiter">-></span>left = <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*replacement<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> + type<span class="Delimiter">-></span>name = <span class="Delimiter">(</span>replacement<span class="Delimiter">-></span>name == <span class="Constant">"literal"</span><span class="Delimiter">)</span> ? <span class="Constant">"number"</span> : replacement<span class="Delimiter">-></span>name<span class="Delimiter">;</span> + type<span class="Delimiter">-></span>value = get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type<span class="Delimiter">-></span>name<span class="Delimiter">);</span> <span class="Delimiter">}</span> - <span class="Comment">// replace last type?</span> <span class="Normal">else</span> <span class="Delimiter">{</span> - type<span class="Delimiter">-></span>name = replacement<span class="Delimiter">-></span>name<span class="Delimiter">;</span> - type<span class="Delimiter">-></span>value = get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type<span class="Delimiter">-></span>name<span class="Delimiter">);</span> - type<span class="Delimiter">-></span>right = <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*replacement<span class="Delimiter">-></span>right<span class="Delimiter">);</span> + *type = *replacement<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> @@ -510,34 +482,9 @@ recipe_ordinal new_variant<span class="Delimiter">(</span>recipe_ordinal exempla <span class="Delimiter">}</span> type_tree* parse_type_tree<span class="Delimiter">(</span><span class="Normal">const</span> 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_type_tree<span class="Delimiter">(</span>in<span class="Delimiter">);</span> -<span class="Delimiter">}</span> - -type_tree* parse_type_tree<span class="Delimiter">(</span>istream& in<span class="Delimiter">)</span> <span class="Delimiter">{</span> - skip_whitespace_but_not_newline<span class="Delimiter">(</span>in<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">')'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - 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> - <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="Constant">'('</span><span class="Delimiter">)</span> - <span class="Identifier">return</span> <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>next_word<span class="Delimiter">(</span>in<span class="Delimiter">),</span> <span class="Constant">0</span><span class="Delimiter">);</span> - in<span class="Delimiter">.</span>get<span class="Delimiter">();</span> <span class="Comment">// skip '('</span> - type_tree* result = <span class="Constant">NULL</span><span class="Delimiter">;</span> - type_tree** curr = &result<span class="Delimiter">;</span> - <span class="Normal">while</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="Constant">')'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> - assert<span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">));</span> - *curr = <span class="Normal">new</span> type_tree<span class="Delimiter">(</span><span class="Constant">""</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> - skip_whitespace_but_not_newline<span class="Delimiter">(</span>in<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'('</span><span class="Delimiter">)</span> - <span class="Delimiter">(</span>*curr<span class="Delimiter">)-></span>left = parse_type_tree<span class="Delimiter">(</span>in<span class="Delimiter">);</span> - <span class="Normal">else</span> - <span class="Delimiter">(</span>*curr<span class="Delimiter">)-></span>name = 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> + string_tree* s2 = parse_string_tree<span class="Delimiter">(</span>s<span class="Delimiter">);</span> + type_tree* result = new_type_tree<span class="Delimiter">(</span>s2<span class="Delimiter">);</span> + <span class="Normal">delete</span> s2<span class="Delimiter">;</span> <span class="Identifier">return</span> result<span class="Delimiter">;</span> <span class="Delimiter">}</span> diff --git a/html/057immutable.cc.html b/html/057immutable.cc.html index 2c2c3974..29d2ea86 100644 --- a/html/057immutable.cc.html +++ b/html/057immutable.cc.html @@ -590,10 +590,10 @@ $error: <span class="Constant">0</span> <span class="Delimiter">:(before "End Immutable Ingredients Special-cases")</span> <span class="Normal">if</span> <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>current_ingredient<span class="Delimiter">,</span> <span class="Constant">"contained-in"</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> <span class="Normal">const</span> string_tree* tmp = property<span class="Delimiter">(</span>current_ingredient<span class="Delimiter">,</span> <span class="Constant">"contained-in"</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>tmp<span class="Delimiter">-></span>left || tmp<span class="Delimiter">-></span>right + <span class="Normal">if</span> <span class="Delimiter">(</span>!tmp<span class="Delimiter">-></span>atom || !is_present_in_ingredients<span class="Delimiter">(</span>caller<span class="Delimiter">,</span> tmp<span class="Delimiter">-></span>value<span class="Delimiter">)</span> || !is_present_in_products<span class="Delimiter">(</span>caller<span class="Delimiter">,</span> tmp<span class="Delimiter">-></span>value<span class="Delimiter">))</span> - raise << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"/contained-in can only point to another ingredient+product, but got '"</span> << to_string<span class="Delimiter">(</span>property<span class="Delimiter">(</span>current_ingredient<span class="Delimiter">,</span> <span class="Constant">"contained-in"</span><span class="Delimiter">))</span> << <span class="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + raise << maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> << <span class="Constant">"/contained-in can only point to another ingredient or product, but got '"</span> << to_string<span class="Delimiter">(</span>property<span class="Delimiter">(</span>current_ingredient<span class="Delimiter">,</span> <span class="Constant">"contained-in"</span><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> </pre> diff --git a/html/062rewrite_stash.cc.html b/html/062rewrite_stash.cc.html index d40916b7..1d8adc6f 100644 --- a/html/062rewrite_stash.cc.html +++ b/html/062rewrite_stash.cc.html @@ -151,14 +151,15 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa <span class="Delimiter">}</span> <span class="Normal">bool</span> is_lookup_of_address_of_array<span class="Delimiter">(</span>reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> x<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name != <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="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>name != <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="Normal">if</span> <span class="Delimiter">(</span>!canonize_type<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Identifier">return</span> x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name == <span class="Constant">"array"</span><span class="Delimiter">;</span> + <span class="Identifier">return</span> is_mu_array<span class="Delimiter">(</span>x<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">bool</span> is_static_array<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// no canonize_type()</span> - <span class="Identifier">return</span> x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name == <span class="Constant">"array"</span><span class="Delimiter">;</span> + <span class="Identifier">return</span> !x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom && x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>name == <span class="Constant">"array"</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">//: Make sure that the new system is strictly better than just the 'stash'</span> diff --git a/html/069hash.cc.html b/html/069hash.cc.html index 07fd97ee..9f22b7a3 100644 --- a/html/069hash.cc.html +++ b/html/069hash.cc.html @@ -124,8 +124,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Normal">size_t</span> hash_mu_container<span class="Delimiter">(</span><span class="Normal">size_t</span> h<span class="Delimiter">,</span> <span class="Normal">const</span> reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> - assert<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> - type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> + type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root_type<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">)-></span>value<span class="Delimiter">);</span> <span class="Normal">int</span> address = r<span class="Delimiter">.</span>value<span class="Delimiter">;</span> <span class="Normal">int</span> offset = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < SIZE<span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -140,12 +139,13 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Normal">size_t</span> hash_mu_exclusive_container<span class="Delimiter">(</span><span class="Normal">size_t</span> h<span class="Delimiter">,</span> <span class="Normal">const</span> reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> - assert<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> + <span class="Normal">const</span> type_tree* type = root_type<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">);</span> + assert<span class="Delimiter">(</span>type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> <span class="Normal">int</span> tag = get<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> r<span class="Delimiter">.</span>value<span class="Delimiter">);</span> reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> variant = variant_type<span class="Delimiter">(</span>r<span class="Delimiter">,</span> tag<span class="Delimiter">);</span> <span class="Comment">// todo: move this error to container definition time</span> <span class="Normal">if</span> <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>variant<span class="Delimiter">,</span> <span class="Constant">"ignore-for-hash"</span><span class="Delimiter">))</span> - raise << get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>name << <span class="Constant">": /ignore-for-hash won't work in exclusive containers</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + raise << get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>name << <span class="Constant">": /ignore-for-hash won't work in exclusive containers</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> variant<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>r<span class="Delimiter">.</span>value + <span class="Comment">/*</span><span class="Comment">skip tag</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">);</span> h = hash<span class="Delimiter">(</span>h<span class="Delimiter">,</span> variant<span class="Delimiter">);</span> <span class="Identifier">return</span> h<span class="Delimiter">;</span> diff --git a/html/071recipe.cc.html b/html/071recipe.cc.html index 0ae26bfe..47204f71 100644 --- a/html/071recipe.cc.html +++ b/html/071recipe.cc.html @@ -105,8 +105,8 @@ get_or_insert<span class="Delimiter">(</span>Type<span class="Delimiter">,</span <span class="Normal">bool</span> is_matching_non_recipe_literal<span class="Delimiter">(</span><span class="Normal">const</span> reagent& x<span class="Delimiter">,</span> <span class="Normal">const</span> string& name<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>name != name<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">"recipe-literal"</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Identifier">return</span> 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">"recipe-literal"</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Comment">//: It's confusing to use variable names that are also recipe names. Always</span> @@ -212,22 +212,32 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa <span class="Delimiter">}</span> recipe from_reagent<span class="Delimiter">(</span><span class="Normal">const</span> reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> - assert<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name == <span class="Constant">"recipe"</span><span class="Delimiter">);</span> + assert<span class="Delimiter">(</span>!r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom && r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom && r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>name == <span class="Constant">"recipe"</span><span class="Delimiter">);</span> recipe result_header<span class="Delimiter">;</span> <span class="Comment">// will contain only ingredients and products, nothing else</span> result_header<span class="Delimiter">.</span>has_header = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Normal">const</span> type_tree* curr = r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>right<span class="Delimiter">;</span> - <span class="Normal">for</span> <span class="Delimiter">(;</span> curr<span class="Delimiter">;</span> curr=curr<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">-></span>name == <span class="Constant">"->"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">nada</span><span class="Comment">*/</span><span class="Delimiter">;</span> curr && !curr<span class="Delimiter">-></span>atom<span class="Delimiter">;</span> curr = curr<span class="Delimiter">-></span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom && curr<span class="Delimiter">-></span>left<span class="Delimiter">-></span>name == <span class="Constant">"->"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> curr = curr<span class="Delimiter">-></span>right<span class="Delimiter">;</span> <span class="Comment">// skip delimiter</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> - result_header<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>next_recipe_reagent<span class="Delimiter">(</span>curr<span class="Delimiter">));</span> + result_header<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>next_recipe_reagent<span class="Delimiter">(</span>curr<span class="Delimiter">-></span>left<span class="Delimiter">));</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">-></span>right && curr<span class="Delimiter">-></span>right<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> + result_header<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>next_recipe_reagent<span class="Delimiter">(</span>curr<span class="Delimiter">-></span>right<span class="Delimiter">));</span> + <span class="Identifier">return</span> result_header<span class="Delimiter">;</span> <span class="Comment">// no products</span> + <span class="Delimiter">}</span> <span class="Delimiter">}</span> - <span class="Normal">for</span> <span class="Delimiter">(;</span> curr<span class="Delimiter">;</span> curr=curr<span class="Delimiter">-></span>right<span class="Delimiter">)</span> + <span class="Normal">for</span> <span class="Delimiter">(;</span> curr && !curr<span class="Delimiter">-></span>atom<span class="Delimiter">;</span> curr=curr<span class="Delimiter">-></span>right<span class="Delimiter">)</span> + result_header<span class="Delimiter">.</span>products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>next_recipe_reagent<span class="Delimiter">(</span>curr<span class="Delimiter">-></span>left<span class="Delimiter">));</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>curr<span class="Delimiter">)</span> <span class="Delimiter">{</span> + assert<span class="Delimiter">(</span>curr<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> result_header<span class="Delimiter">.</span>products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>next_recipe_reagent<span class="Delimiter">(</span>curr<span class="Delimiter">));</span> + <span class="Delimiter">}</span> <span class="Identifier">return</span> result_header<span class="Delimiter">;</span> <span class="Delimiter">}</span> +<span class="Comment">// todo: unit test: 'recipe number' vs 'recipe -> number'</span> + reagent next_recipe_reagent<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* curr<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!curr<span class="Delimiter">-></span>left<span class="Delimiter">)</span> <span class="Identifier">return</span> reagent<span class="Delimiter">(</span><span class="Constant">"recipe:"</span>+curr<span class="Delimiter">-></span>name<span class="Delimiter">);</span> reagent result<span class="Delimiter">;</span> @@ -238,9 +248,10 @@ reagent next_recipe_reagent<span class="Delimiter">(</span><span class="Normal"> <span class="Normal">bool</span> is_mu_recipe<span class="Delimiter">(</span><span class="Normal">const</span> reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!r<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name == <span class="Constant">"recipe"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name == <span class="Constant">"recipe-literal"</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="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> + <span class="Identifier">return</span> r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>name == <span class="Constant">"recipe-literal"</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>name == <span class="Constant">"recipe"</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> diff --git a/html/073wait.cc.html b/html/073wait.cc.html index 847eafa3..926c6b29 100644 --- a/html/073wait.cc.html +++ b/html/073wait.cc.html @@ -158,7 +158,12 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> 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="Normal">if</span> <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="Normal">if</span> <span class="Delimiter">(</span>!base<span class="Delimiter">.</span>type || !base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value || !contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">)</span> || 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> + <span class="Normal">if</span> <span class="Delimiter">(</span>!base<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Delimiter">{</span> + raise << 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-location' 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="Constant">"'</span><span class="cSpecial">\n</span><span class="Constant">"</span> << end<span class="Delimiter">();</span> + <span class="Identifier">break</span><span class="Delimiter">;</span> + <span class="Delimiter">}</span> + <span class="Normal">const</span> type_tree* base_root_type = base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>atom ? base<span class="Delimiter">.</span>type : base<span class="Delimiter">.</span>type<span class="Delimiter">-></span>left<span class="Delimiter">;</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!base_root_type<span class="Delimiter">-></span>atom || base_root_type<span class="Delimiter">-></span>value == <span class="Constant">0</span> || !contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_root_type<span class="Delimiter">-></span>value<span class="Delimiter">)</span> || get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_root_type<span class="Delimiter">-></span>value<span class="Delimiter">).</span>kind != CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span> raise << 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-location' 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="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> @@ -195,9 +200,9 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span raise << maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> << <span class="Constant">"tried to access location 0 in '"</span> << to_original_string<span class="Delimiter">(</span>current_instruction<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> + <span class="Normal">const</span> type_tree* base_root_type = root_type<span class="Delimiter">(</span>base<span class="Delimiter">.</span>type<span class="Delimiter">);</span> <span class="Normal">int</span> offset = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>offset < <span class="Constant">0</span> || offset >= SIZE<span class="Delimiter">(</span>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> + <span class="Normal">if</span> <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_root_type<span class="Delimiter">-></span>value<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> <span class="Normal">int</span> result = base_address<span class="Delimiter">;</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i < offset<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> result += size_of<span class="Delimiter">(</span>element_type<span class="Delimiter">(</span>base<span class="Delimiter">.</span>type<span class="Delimiter">,</span> i<span class="Delimiter">));</span> diff --git a/html/074deep_copy.cc.html b/html/074deep_copy.cc.html index 4a520023..b440083b 100644 --- a/html/074deep_copy.cc.html +++ b/html/074deep_copy.cc.html @@ -317,7 +317,7 @@ vector<<span class="Normal">double</span>> deep_copy<span class="Delimiter <span class="Comment">// construct a fake reagent that reads directly from the appropriate</span> <span class="Comment">// field of the container</span> reagent curr<span class="Delimiter">;</span> - curr<span class="Delimiter">.</span>type = <span class="Normal">new</span> type_tree<span class="Delimiter">(</span><span class="Constant">"address"</span><span class="Delimiter">,</span> <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*info<span class="Delimiter">-></span>payload_type<span class="Delimiter">));</span> + curr<span class="Delimiter">.</span>type = <span class="Normal">new</span> type_tree<span class="Delimiter">(</span><span class="Normal">new</span> type_tree<span class="Delimiter">(</span><span class="Constant">"address"</span><span class="Delimiter">),</span> <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*info<span class="Delimiter">-></span>payload_type<span class="Delimiter">));</span> curr<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>canonized_in<span class="Delimiter">.</span>value + info<span class="Delimiter">-></span>offset<span class="Delimiter">);</span> curr<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> trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">"run"</span><span class="Delimiter">)</span> << <span class="Constant">"deep-copy: copying address "</span> << curr<span class="Delimiter">.</span>value << end<span class="Delimiter">();</span> diff --git a/html/080display.cc.html b/html/080display.cc.html index 44613b49..e3546ae0 100644 --- a/html/080display.cc.html +++ b/html/080display.cc.html @@ -20,6 +20,7 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color .SalientComment { color: #00ffff; } .Identifier { color: #fcb165; } .Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } +.PreProc { color: #800080; } --> </style> @@ -38,9 +39,28 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="SalientComment">//:: Display management</span> <span class="Delimiter">:(before "End Globals")</span> -<span class="Normal">int</span> Display_row = <span class="Constant">0</span><span class="Delimiter">,</span> Display_column = <span class="Constant">0</span><span class="Delimiter">;</span> +<span class="Normal">int</span> Display_row = <span class="Constant">0</span><span class="Delimiter">;</span> +<span class="Normal">int</span> Display_column = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Normal">bool</span> Autodisplay = <span class="Constant">true</span><span class="Delimiter">;</span> +<span class="Delimiter">:(before "End Includes")</span> +<span class="PreProc">#define CHECK_SCREEN \</span> +<span class="PreProc"> </span><span class="Normal">if</span><span class="PreProc"> (!tb_is_active()) </span><span class="Delimiter">{</span><span class="PreProc"> \</span> +<span class="PreProc"> </span><span class="Normal">if</span><span class="PreProc"> (Run_tests) \</span> +<span class="PreProc"> raise << maybe(current_recipe_name()) << </span><span class="Constant">"tried to print to real screen before 'open-console'</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="PreProc"> << end()</span><span class="Delimiter">;</span><span class="PreProc"> \</span> +<span class="PreProc"> </span><span class="Normal">else</span><span class="PreProc"> \</span> +<span class="PreProc"> raise << maybe(current_recipe_name()) << </span><span class="Constant">"tried to print to real screen in a test!</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="PreProc"> << end()</span><span class="Delimiter">;</span><span class="PreProc"> \</span> +<span class="PreProc"> </span><span class="Identifier">break</span><span class="Delimiter">;</span><span class="PreProc"> \</span> +<span class="PreProc"> </span><span class="Delimiter">}</span> +<span class="PreProc">#define CHECK_CONSOLE \</span> +<span class="PreProc"> </span><span class="Normal">if</span><span class="PreProc"> (!tb_is_active()) </span><span class="Delimiter">{</span><span class="PreProc"> \</span> +<span class="PreProc"> </span><span class="Normal">if</span><span class="PreProc"> (Run_tests) \</span> +<span class="PreProc"> raise << maybe(current_recipe_name()) << </span><span class="Constant">"tried to read event from real keyboard/mouse before 'open-console'</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="PreProc"> << end()</span><span class="Delimiter">;</span><span class="PreProc"> \</span> +<span class="PreProc"> </span><span class="Normal">else</span><span class="PreProc"> \</span> +<span class="PreProc"> raise << maybe(current_recipe_name()) << </span><span class="Constant">"tried to read event from real keyboard/mouse in a test!</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="PreProc"> << end()</span><span class="Delimiter">;</span><span class="PreProc"> \</span> +<span class="PreProc"> </span><span class="Identifier">break</span><span class="Delimiter">;</span><span class="PreProc"> \</span> +<span class="PreProc"> </span><span class="Delimiter">}</span> + <span class="Delimiter">:(before "End Primitive Recipe Declarations")</span> OPEN_CONSOLE<span class="Delimiter">,</span> <span class="Delimiter">:(before "End Primitive Recipe Numbers")</span> @@ -90,6 +110,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> CLEAR_DISPLAY: <span class="Delimiter">{</span> + CHECK_SCREEN<span class="Delimiter">;</span> tb_clear<span class="Delimiter">();</span> Display_row = Display_column = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Identifier">break</span><span class="Delimiter">;</span> @@ -105,6 +126,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> SYNC_DISPLAY: <span class="Delimiter">{</span> + CHECK_SCREEN<span class="Delimiter">;</span> tb_sync<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -119,6 +141,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> CLEAR_LINE_ON_DISPLAY: <span class="Delimiter">{</span> + CHECK_SCREEN<span class="Delimiter">;</span> <span class="Normal">int</span> width = tb_width<span class="Delimiter">();</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> x = Display_column<span class="Delimiter">;</span> x < width<span class="Delimiter">;</span> ++x<span class="Delimiter">)</span> <span class="Delimiter">{</span> tb_change_cell<span class="Delimiter">(</span>x<span class="Delimiter">,</span> Display_row<span class="Delimiter">,</span> <span class="Constant">' '</span><span class="Delimiter">,</span> TB_WHITE<span class="Delimiter">,</span> TB_BLACK<span class="Delimiter">);</span> @@ -158,6 +181,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> PRINT_CHARACTER_TO_DISPLAY: <span class="Delimiter">{</span> + CHECK_SCREEN<span class="Delimiter">;</span> <span class="Normal">int</span> h=tb_height<span class="Delimiter">(),</span> w=tb_width<span class="Delimiter">();</span> <span class="Normal">int</span> height = <span class="Delimiter">(</span>h >= <span class="Constant">0</span><span class="Delimiter">)</span> ? h : <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Normal">int</span> width = <span class="Delimiter">(</span>w >= <span class="Constant">0</span><span class="Delimiter">)</span> ? w : <span class="Constant">0</span><span class="Delimiter">;</span> @@ -208,6 +232,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> CURSOR_POSITION_ON_DISPLAY: <span class="Delimiter">{</span> + CHECK_SCREEN<span class="Delimiter">;</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">);</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>Display_row<span class="Delimiter">);</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>Display_column<span class="Delimiter">);</span> @@ -236,6 +261,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> MOVE_CURSOR_ON_DISPLAY: <span class="Delimiter">{</span> + CHECK_SCREEN<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> @@ -253,6 +279,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> MOVE_CURSOR_DOWN_ON_DISPLAY: <span class="Delimiter">{</span> + CHECK_SCREEN<span class="Delimiter">;</span> <span class="Normal">int</span> h=tb_height<span class="Delimiter">();</span> <span class="Normal">int</span> height = <span class="Delimiter">(</span>h >= <span class="Constant">0</span><span class="Delimiter">)</span> ? h : <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Display_row < height-<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -273,6 +300,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> MOVE_CURSOR_UP_ON_DISPLAY: <span class="Delimiter">{</span> + CHECK_SCREEN<span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Display_row > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> --Display_row<span class="Delimiter">;</span> tb_set_cursor<span class="Delimiter">(</span>Display_column<span class="Delimiter">,</span> Display_row<span class="Delimiter">);</span> @@ -291,6 +319,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> MOVE_CURSOR_RIGHT_ON_DISPLAY: <span class="Delimiter">{</span> + CHECK_SCREEN<span class="Delimiter">;</span> <span class="Normal">int</span> w=tb_width<span class="Delimiter">();</span> <span class="Normal">int</span> width = <span class="Delimiter">(</span>w >= <span class="Constant">0</span><span class="Delimiter">)</span> ? w : <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Display_column < width-<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> @@ -311,6 +340,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> MOVE_CURSOR_LEFT_ON_DISPLAY: <span class="Delimiter">{</span> + CHECK_SCREEN<span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Display_column > <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> --Display_column<span class="Delimiter">;</span> tb_set_cursor<span class="Delimiter">(</span>Display_column<span class="Delimiter">,</span> Display_row<span class="Delimiter">);</span> @@ -343,6 +373,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> DISPLAY_WIDTH: <span class="Delimiter">{</span> + CHECK_SCREEN<span class="Delimiter">;</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>tb_width<span class="Delimiter">());</span> <span class="Identifier">break</span><span class="Delimiter">;</span> @@ -358,6 +389,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> DISPLAY_HEIGHT: <span class="Delimiter">{</span> + CHECK_SCREEN<span class="Delimiter">;</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>tb_height<span class="Delimiter">());</span> <span class="Identifier">break</span><span class="Delimiter">;</span> @@ -373,6 +405,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> HIDE_CURSOR_ON_DISPLAY: <span class="Delimiter">{</span> + CHECK_SCREEN<span class="Delimiter">;</span> tb_set_cursor<span class="Delimiter">(</span>TB_HIDE_CURSOR<span class="Delimiter">,</span> TB_HIDE_CURSOR<span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -387,6 +420,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> SHOW_CURSOR_ON_DISPLAY: <span class="Delimiter">{</span> + CHECK_SCREEN<span class="Delimiter">;</span> tb_set_cursor<span class="Delimiter">(</span>Display_row<span class="Delimiter">,</span> Display_column<span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -401,6 +435,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> HIDE_DISPLAY: <span class="Delimiter">{</span> + CHECK_SCREEN<span class="Delimiter">;</span> Autodisplay = <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> @@ -415,6 +450,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> SHOW_DISPLAY: <span class="Delimiter">{</span> + CHECK_SCREEN<span class="Delimiter">;</span> Autodisplay = <span class="Constant">true</span><span class="Delimiter">;</span> tb_present<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> @@ -432,6 +468,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> WAIT_FOR_SOME_INTERACTION: <span class="Delimiter">{</span> + CHECK_SCREEN<span class="Delimiter">;</span> tb_event event<span class="Delimiter">;</span> tb_poll_event<span class="Delimiter">(</span>&event<span class="Delimiter">);</span> <span class="Identifier">break</span><span class="Delimiter">;</span> @@ -447,6 +484,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> CHECK_FOR_INTERACTION: <span class="Delimiter">{</span> + CHECK_CONSOLE<span class="Delimiter">;</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">2</span><span class="Delimiter">);</span> <span class="Comment">// result and status</span> tb_event event<span class="Delimiter">;</span> <span class="Normal">int</span> event_type = tb_peek_event<span class="Delimiter">(</span>&event<span class="Delimiter">,</span> <span class="Constant">5</span><span class="Comment">/*</span><span class="Comment">ms</span><span class="Comment">*/</span><span class="Delimiter">);</span> @@ -517,6 +555,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> INTERACTIONS_LEFT: <span class="Delimiter">{</span> + CHECK_CONSOLE<span class="Delimiter">;</span> products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>tb_event_ready<span class="Delimiter">());</span> <span class="Identifier">break</span><span class="Delimiter">;</span> @@ -534,6 +573,7 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">}</span> <span class="Delimiter">:(before "End Primitive Recipe Implementations")</span> <span class="Normal">case</span> CLEAR_DISPLAY_FROM: <span class="Delimiter">{</span> + CHECK_SCREEN<span class="Delimiter">;</span> <span class="Comment">// todo: error checking</span> <span class="Normal">int</span> row = ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span> <span class="Normal">int</span> 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> diff --git a/html/082scenario_screen.cc.html b/html/082scenario_screen.cc.html index 5501e57f..f0f10ac5 100644 --- a/html/082scenario_screen.cc.html +++ b/html/082scenario_screen.cc.html @@ -168,7 +168,7 @@ $error: <span class="Constant">0</span> <span class="Comment">//: locations.</span> <span class="Delimiter">:(before "End Globals")</span> -<span class="Normal">const</span> <span class="Normal">int</span> Max_variables_in_scenarios = Reserved_for_tests-<span class="Constant">100</span><span class="Delimiter">;</span> +<span class="Normal">extern</span> <span class="Normal">const</span> <span class="Normal">int</span> Max_variables_in_scenarios = Reserved_for_tests-<span class="Constant">100</span><span class="Delimiter">;</span> <span class="Normal">int</span> Next_predefined_global_for_scenarios = Max_variables_in_scenarios<span class="Delimiter">;</span> <span class="Delimiter">:(before "End Setup")</span> assert<span class="Delimiter">(</span>Next_predefined_global_for_scenarios < Reserved_for_tests<span class="Delimiter">);</span> @@ -180,7 +180,7 @@ assert<span class="Delimiter">(</span>Name[tmp_recipe<span class="Delimiter">.</ <span class="Delimiter">:(before "End Globals")</span> <span class="Comment">// Scenario Globals.</span> -<span class="Normal">const</span> <span class="Normal">int</span> SCREEN = Next_predefined_global_for_scenarios++<span class="Delimiter">;</span> +<span class="Normal">extern</span> <span class="Normal">const</span> <span class="Normal">int</span> SCREEN = Next_predefined_global_for_scenarios++<span class="Delimiter">;</span> <span class="Comment">// End Scenario Globals.</span> <span class="Comment">//: give 'screen' a fixed location in scenarios</span> diff --git a/html/085scenario_console.cc.html b/html/085scenario_console.cc.html index f4c60570..fec10788 100644 --- a/html/085scenario_console.cc.html +++ b/html/085scenario_console.cc.html @@ -67,7 +67,7 @@ scenario keyboard-in-scenario [ ] <span class="Delimiter">:(before "End Scenario Globals")</span> -<span class="Normal">const</span> <span class="Normal">int</span> CONSOLE = Next_predefined_global_for_scenarios++<span class="Delimiter">;</span> +<span class="Normal">extern</span> <span class="Normal">const</span> <span class="Normal">int</span> CONSOLE = Next_predefined_global_for_scenarios++<span class="Delimiter">;</span> <span class="Comment">//: give 'console' a fixed location in scenarios</span> <span class="Delimiter">:(before "End Special Scenario Variable Names(r)")</span> Name[r][<span class="Constant">"console"</span>] = CONSOLE<span class="Delimiter">;</span> diff --git a/html/089scenario_filesystem.cc.html b/html/089scenario_filesystem.cc.html index 0f9b51b6..f854cb6e 100644 --- a/html/089scenario_filesystem.cc.html +++ b/html/089scenario_filesystem.cc.html @@ -106,7 +106,7 @@ scenario assume-filesystem [ ] <span class="Delimiter">:(before "End Globals")</span> -<span class="Normal">const</span> <span class="Normal">int</span> FILESYSTEM = Next_predefined_global_for_scenarios++<span class="Delimiter">;</span> +<span class="Normal">extern</span> <span class="Normal">const</span> <span class="Normal">int</span> FILESYSTEM = Next_predefined_global_for_scenarios++<span class="Delimiter">;</span> <span class="Comment">//: give 'filesystem' a fixed location in scenarios</span> <span class="Delimiter">:(before "End Special Scenario Variable Names(r)")</span> Name[r][<span class="Constant">"filesystem"</span>] = FILESYSTEM<span class="Delimiter">;</span> diff --git a/html/101run_sandboxed.cc.html b/html/101run_sandboxed.cc.html index a0b9b043..d43b68af 100644 --- a/html/101run_sandboxed.cc.html +++ b/html/101run_sandboxed.cc.html @@ -104,7 +104,6 @@ put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span <span class="Delimiter">:(before "End Globals")</span> <span class="Normal">bool</span> 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> diff --git a/html/counters.mu.html b/html/counters.mu.html index e59b934c..940c68ec 100644 --- a/html/counters.mu.html +++ b/html/counters.mu.html @@ -55,7 +55,6 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color a-value:number<span class="Special"> <- </span>increment-counter a, <span class="Constant">1</span> <span class="Comment"># check results</span> $print <span class="Constant">[Contents of counters]</span>, <span class="Constant">10/newline</span> - <span class="Comment"># trailing space in next line is to help with syntax highlighting</span> $print <span class="Constant">[a: ]</span>, a-value, <span class="Constant">[ b: ]</span>, b-value, <span class="Constant">10/newline</span> ] </pre> diff --git a/html/tangle.mu.html b/html/tangle.mu.html index a654161e..da54e95f 100644 --- a/html/tangle.mu.html +++ b/html/tangle.mu.html @@ -63,8 +63,9 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color <span class="muRecipe">def</span> main [ <span class="Constant">1</span>:number<span class="Special"> <- </span>factorial <span class="Constant">5</span> - $print <span class="Constant">[result: ]</span>, <span class="Constant">1</span>:number, [ -] + <span class="Comment"># trailing space in next line is to help with syntax highlighting</span> + $print <span class="Constant">[result: ]</span>, <span class="Constant">1</span>:number, <span class="Constant">[ </span> +<span class="Constant">]</span> ] </pre> </body> |