<!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.arc.t</title>
<meta name="Generator" content="Vim/7.4">
<meta name="plugin-version" content="vim7.4_v1">
<meta name="syntax" content="scheme">
<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: #aaaaaa; background-color: #000000; }
body { font-family: monospace; color: #aaaaaa; background-color: #000000; }
a { color:#4444ff; }
* { font-size: 1em; }
.Global { color: #00af87; }
.SalientComment { color: #00ffff; }
.CommentedCode { color: #666666; }
.Mu, .Mu .Normal, .Mu .Constant { color: #eeeeee; }
.Op { color: #ff8888; }
.Delimiter { color: #600060; }
.Normal { color: #aaaaaa; }
.Comment { color: #8080ff; }
.Constant, .MuConstant { color: #008080; }
.Identifier { color: #008080; }
-->
</style>
<script type='text/javascript'>
<!--
-->
</script>
</head>
<body>
<pre id='vimCodeElement'>
<span class="Comment">; Mu: An exploration on making the global structure of programs more accessible.</span>
<span class="Comment">;</span>
<span class="Comment">; "Is it a language, or an operating system, or a virtual machine? Mu."</span>
<span class="Comment">; (with apologies to Robert Pirsig: <a href="http://en.wikipedia.org/wiki/Mu_%28negative%29#In_popular_culture">http://en.wikipedia.org/wiki/Mu_%28negative%29#In_popular_culture</a>)</span>
<span class="Comment">;</span>
<span class="SalientComment">;; Motivation</span>
<span class="Comment">;</span>
<span class="Comment">; I want to live in a world where I can have an itch to tweak a program, clone</span>
<span class="Comment">; its open-source repository, orient myself on how it's organized, and make</span>
<span class="Comment">; the simple change I envisioned, all in an afternoon. This codebase tries to</span>
<span class="Comment">; make this possible for its readers. (More details: <a href="http://akkartik.name/about">http://akkartik.name/about</a>)</span>
<span class="Comment">;</span>
<span class="Comment">; What helps comprehend the global structure of programs? For starters, let's</span>
<span class="Comment">; enumerate what doesn't: idiomatic code, adherence to a style guide or naming</span>
<span class="Comment">; convention, consistent indentation, API documentation for each class, etc.</span>
<span class="Comment">; These conventional considerations improve matters in the small, but don't</span>
<span class="Comment">; help understand global organization. They help existing programmers manage</span>
<span class="Comment">; day-to-day operations, but they can't turn outsider programmers into</span>
<span class="Comment">; insiders. (Elaboration: <a href="http://akkartik.name/post/readable-bad">http://akkartik.name/post/readable-bad</a>)</span>
<span class="Comment">;</span>
<span class="Comment">; In my experience, two things have improved matters so far: version control</span>
<span class="Comment">; and automated tests. Version control lets me rewind back to earlier, simpler</span>
<span class="Comment">; times when the codebase was simpler, when its core skeleton was easier to</span>
<span class="Comment">; ascertain. Indeed, arguably what came first is by definition the skeleton of</span>
<span class="Comment">; a program, modulo major rewrites. Once you understand the skeleton, it</span>
<span class="Comment">; becomes tractable to 'play back' later major features one by one. (Previous</span>
<span class="Comment">; project that fleshed out this idea: <a href="http://akkartik.name/post/wart-layers">http://akkartik.name/post/wart-layers</a>)</span>
<span class="Comment">;</span>
<span class="Comment">; The second and biggest boost to comprehension comes from tests. Tests are</span>
<span class="Comment">; good for writers for well-understood reasons: they avoid regressions, and</span>
<span class="Comment">; they can influence code to be more decoupled and easier to change. In</span>
<span class="Comment">; addition, tests are also good for the outsider reader because they permit</span>
<span class="Comment">; active reading. If you can't build a program and run its tests it can't help</span>
<span class="Comment">; you understand it. It hangs limp at best, and might even be actively</span>
<span class="Comment">; misleading. If you can run its tests, however, it comes alive. You can step</span>
<span class="Comment">; through scenarios in a debugger. You can add logging and scan logs to make</span>
<span class="Comment">; sense of them. You can run what-if scenarios: "why is this line not written</span>
<span class="Comment">; like this?" Make a change, rerun tests: "Oh, that's why." (Elaboration:</span>
<span class="Comment">; <a href="http://akkartik.name/post/literate-programming">http://akkartik.name/post/literate-programming</a>)</span>
<span class="Comment">;</span>
<span class="Comment">; However, tests are only useful to the extent that they exist. Think back to</span>
<span class="Comment">; your most recent codebase. Do you feel comfortable releasing a new version</span>
<span class="Comment">; just because the tests pass? I'm not aware of any such project. There's just</span>
<span class="Comment">; too many situations envisaged by the authors that were never encoded in a</span>
<span class="Comment">; test. Even disciplined authors can't test for performance or race conditions</span>
<span class="Comment">; or fault tolerance. If a line is phrased just so because of some subtle</span>
<span class="Comment">; performance consideration, it's hard to communicate to newcomers.</span>
<span class="Comment">;</span>
<span class="Comment">; This isn't an arcane problem, and it isn't just a matter of altruism. As</span>
<span class="Comment">; more and more such implicit considerations proliferate, and as the original</span>
<span class="Comment">; authors are replaced by latecomers for day-to-day operations, knowledge is</span>
<span class="Comment">; actively forgotten and lost. The once-pristine codebase turns into legacy</span>
<span class="Comment">; code that is hard to modify without expensive and stress-inducing</span>
<span class="Comment">; regressions.</span>
<span class="Comment">;</span>
<span class="Comment">; How to write tests for performance, fault tolerance, race conditions, etc.?</span>
<span class="Comment">; How can we state and verify that a codepath doesn't ever perform memory</span>
<span class="Comment">; allocation, or write to disk? It requires better, more observable primitives</span>
<span class="Comment">; than we currently have. Modern operating systems have their roots in the</span>
<span class="Comment">; 70s. Their interfaces were not designed to be testable. They provide no way</span>
<span class="Comment">; to simulate a full disk, or a specific sequence of writes from different</span>
<span class="Comment">; threads. We need something better.</span>
<span class="Comment">;</span>
<span class="Comment">; This project tries to move, groping, towards that 'something better', a</span>
<span class="Comment">; platform that is both thoroughly tested and allows programs written for it</span>
<span class="Comment">; to be thoroughly tested. It tries to answer the question:</span>
<span class="Comment">;</span>
<span class="Comment">; If Denis Ritchie and Ken Thompson were to set out today to co-design unix</span>
<span class="Comment">; and C, knowing what we know about automated tests, what would they do</span>
<span class="Comment">; differently?</span>
<span class="Comment">;</span>
<span class="Comment">; To try to impose *some* constraints on this gigantic yak-shave, we'll try to</span>
<span class="Comment">; keep both language and OS as simple as possible, focused entirely on</span>
<span class="Comment">; permitting more kinds of tests, on first *collecting* all the information</span>
<span class="Comment">; about implicit considerations in some form so that readers and tools can</span>
<span class="Comment">; have at least some hope of making sense of it.</span>
<span class="Comment">;</span>
<span class="Comment">; The initial language will be just assembly. We'll try to make it convenient</span>
<span class="Comment">; to program in with some simple localized rewrite rules inspired by lisp</span>
<span class="Comment">; macros and literate programming. Programmers will have to do their own</span>
<span class="Comment">; memory management and register allocation, but we'll provide libraries to</span>
<span class="Comment">; help with them.</span>
<span class="Comment">;</span>
<span class="Comment">; The initial OS will provide just memory management and concurrency</span>
<span class="Comment">; primitives. No users or permissions (we don't live on mainframes anymore),</span>
<span class="Comment">; no kernel- vs user-mode, no virtual memory or process abstraction, all</span>
<span class="Comment">; threads sharing a single address space (use VMs for security and</span>
<span class="Comment">; sandboxing). The only use case we care about is getting a test harness to</span>
<span class="Comment">; run some code, feed it data through blocking channels, stop it and observe</span>
<span class="Comment">; its internals. The code under test is expected to cooperate in such testing,</span>
<span class="Comment">; by logging important events for the test harness to observe. (More info:</span>
<span class="Comment">; <a href="http://akkartik.name/post/tracing-tests">http://akkartik.name/post/tracing-tests</a>)</span>
<span class="Comment">;</span>
<span class="Comment">; The common thread here is elimination of abstractions, and it's not an</span>
<span class="Comment">; accident. Abstractions help insiders manage the evolution of a codebase, but</span>
<span class="Comment">; they actively hinder outsiders in understanding it from scratch. This</span>
<span class="Comment">; matters, because the funnel to turn outsiders into insiders is critical to</span>
<span class="Comment">; the long-term life of a codebase. Perhaps authors should raise their</span>
<span class="Comment">; estimation of the costs of abstraction, and go against their instincts for</span>
<span class="Comment">; introducing it. That's what I'll be trying to do: question every abstraction</span>
<span class="Comment">; before I introduce it. We'll see how it goes.</span>
<span class="Comment">; ---</span>
<span class="SalientComment">;; Getting started</span>
<span class="Comment">;</span>
<span class="Comment">; Mu is currently built atop Racket and Arc, but this is temporary and</span>
<span class="Comment">; contingent. We want to keep our options open, whether to port to a different</span>
<span class="Comment">; host language, and easy to rewrite to native code for any platform. So we'll</span>
<span class="Comment">; try to avoid 'cheating': relying on the host platform for advanced</span>
<span class="Comment">; functionality.</span>
<span class="Comment">;</span>
<span class="Comment">; Other than that, we'll say no more about the code, and focus in the rest of</span>
<span class="Comment">; this file on the scenarios the code cares about.</span>
<span class="Delimiter">(</span>load <span class="Constant">"mu.arc"</span><span class="Delimiter">)</span>
<span class="Comment">; Our language is assembly-like in that functions consist of series of</span>
<span class="Comment">; statements, and statements consist of an operation and its arguments (input</span>
<span class="Comment">; and output).</span>
<span class="Comment">;</span>
<span class="Mu"><span class="Comment">; oarg1, oarg2, ... <span class="Op"><-</span> op arg1, arg2, ...</span></span>
<span class="Comment">;</span>
<span class="Comment">; Args must be atomic, like an integer or a memory address, they can't be</span>
<span class="Comment">; expressions doing arithmetic or function calls. But we can have any number</span>
<span class="Comment">; of them.</span>
<span class="Comment">;</span>
<span class="Comment">; Since we're building on lisp, our code samples won't look quite like the</span>
<span class="Comment">; idealized syntax above. For now they will be lists of lists:</span>
<span class="Comment">;</span>
<span class="Comment">; (function-name</span>
<span class="Mu"><span class="Comment">; ((oarg1 oarg2 ... <span class="Op"><-</span> op arg1 arg2 ...)</span></span>
<span class="Comment">; ...</span>
<span class="Comment">; ...))</span>
<span class="Comment">;</span>
<span class="Comment">; Each arg/oarg is itself a list, with the payload value at the head, and</span>
<span class="Comment">; various metadata in the rest. In this first example the only metadata is types:</span>
<span class="Comment">; 'integer' for a memory location containing an integer, and 'literal' for a</span>
<span class="Comment">; value included directly in code. (Assembly languages traditionally call them</span>
<span class="Comment">; 'immediate' operands.) In the future a simple tool will check that the types</span>
<span class="Comment">; line up as expected in each op. A different tool might add types where they</span>
<span class="Comment">; aren't provided. Instead of a monolithic compiler I want to build simple,</span>
<span class="Comment">; lightweight tools that can be combined in various ways, say for using</span>
<span class="Comment">; different typecheckers in different subsystems.</span>
<span class="Comment">;</span>
<span class="Comment">; In our tests we'll define such mu functions using a call to 'add-fns', so</span>
<span class="Comment">; look for it. Everything outside 'add-fns' is just test-harness details.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"literal"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">23</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.1</span> <span class="Constant">23</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'copy' writes its lone 'arg' after the instruction name to its lone 'oarg' or output arg before the arrow. After this test, the value 23 is stored in memory address 1."</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Comment">; Our basic arithmetic ops can operate on memory locations or literals.</span>
<span class="Comment">; (Ignore hardware details like registers for now.)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"add"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">1</span> <span class="Constant">2</span> <span class="Constant">3</span> <span class="Constant">3</span> <span class="Constant">4</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'add' operates on two addresses"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"add-literal"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.1</span> <span class="Constant">5</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - ops can take 'literal' operands (but not return them)"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"sub-literal"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> sub <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.1</span> <span class="Constant">-2</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'sub' subtracts the second arg from the first"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"mul-literal"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> mul <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.1</span> <span class="Constant">6</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'mul' multiplies like 'add' adds"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"div-literal"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> div <span class="Delimiter">(</span><span class="MuConstant">8</span> literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.1</span> <span class="Delimiter">(</span><span class="Identifier">/</span> real.8 <span class="Constant">3</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'div' divides like 'sub' subtracts"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"idiv-literal"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> idiv <span class="Delimiter">(</span><span class="MuConstant">23</span> literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">6</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">3</span> <span class="Constant">2</span> <span class="Constant">5</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'idiv' performs integer division, returning quotient and remainder"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"dummy-oarg"</span><span class="Delimiter">)</span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">(</span>_ <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> idiv <span class="Delimiter">(</span><span class="MuConstant">23</span> literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">6</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">2</span> <span class="Constant">5</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - '_' oarg can ignore some results"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Comment">; Basic boolean operations: and, or, not</span>
<span class="Comment">; There are easy ways to encode booleans in binary, but we'll skip past those</span>
<span class="Comment">; details for now.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"and-literal"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> and <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.1</span> nil<span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - logical 'and' for booleans"</span><span class="Delimiter">))</span>
<span class="Comment">; Basic comparison operations: lt, le, gt, ge, eq, neq</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"lt-literal"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> lt <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.1</span> nil<span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'lt' is the less-than inequality operator"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"le-literal-false"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> le <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.1</span> nil<span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'le' is the <= inequality operator"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"le-literal-true"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> le <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.1</span> t<span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'le' returns true for equal operands"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"le-literal-true-2"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> le <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">5</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.1</span> t<span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - le is the <= inequality operator - 2"</span><span class="Delimiter">))</span>
<span class="Comment">; Control flow operations: jump, jump-if, jump-unless</span>
<span class="Comment">; These introduce a new type -- 'offset' -- for literals that refer to memory</span>
<span class="Comment">; locations relative to the current location.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"jump-skip"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">8</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">jump</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span> <span class="Comment">; should be skipped</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">8</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'jump' skips some instructions"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"jump-target"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">8</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">jump</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span> <span class="Comment">; should be skipped</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">)))))</span> <span class="Comment">; never reached</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">8</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'jump' doesn't skip too many instructions"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"jump-if-skip"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> eq <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">jump-if</span> <span class="Delimiter">(</span><span class="Constant">1</span> boolean<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> t <span class="Constant">2</span> <span class="Constant">1</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'jump-if' is a conditional 'jump'"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"jump-if-fallthrough"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> eq <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">jump-if</span> <span class="Delimiter">(</span><span class="Constant">3</span> boolean<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> nil <span class="Constant">2</span> <span class="Constant">3</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - if 'jump-if's first arg is false, it doesn't skip any instructions"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"jump-if-backward"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Comment">; loop</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> eq <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">jump-if</span> <span class="Delimiter">(</span><span class="Constant">3</span> boolean<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">-3</span> offset<span class="Delimiter">))</span> <span class="Comment">; to loop</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">2</span> <span class="Constant">2</span> <span class="Constant">4</span> <span class="Constant">3</span> nil <span class="Constant">4</span> <span class="Constant">3</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'jump-if' can take a negative offset to make backward jumps"</span><span class="Delimiter">))</span>
<span class="Comment">; Data movement relies on addressing modes:</span>
<span class="Comment">; 'direct' - refers to a memory location; default for most types.</span>
<span class="Comment">; 'literal' - directly encoded in the code; implicit for some types like 'offset'.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"direct-addressing"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">34</span> <span class="Constant">2</span> <span class="Constant">34</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'copy' performs direct addressing"</span><span class="Delimiter">))</span>
<span class="Comment">; 'Indirect' addressing refers to an address stored in a memory location.</span>
<span class="Comment">; Indicated by the metadata 'deref'. Usually requires an address type.</span>
<span class="Comment">; In the test below, the memory location 1 contains '2', so an indirect read</span>
<span class="Comment">; of location 1 returns the value of location 2.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"indirect-addressing"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span> <span class="Comment">; unsafe; can't do this in general</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="Constant">1</span> integer-address deref<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">2</span> <span class="Constant">2</span> <span class="Constant">34</span> <span class="Constant">3</span> <span class="Constant">34</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'copy' performs indirect addressing"</span><span class="Delimiter">))</span>
<span class="Comment">; Output args can use indirect addressing. In the test below the value is</span>
<span class="Comment">; stored at the location stored in location 1 (i.e. location 2).</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"indirect-addressing-oarg"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">2</span> <span class="Constant">2</span> <span class="Constant">36</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - instructions can perform indirect addressing on output arg"</span><span class="Delimiter">))</span>
<span class="SalientComment">;; Compound data types</span>
<span class="Comment">;</span>
<span class="Comment">; Until now we've dealt with scalar types like integers and booleans and</span>
<span class="Comment">; addresses, where mu looks like other assembly languages. In addition, mu</span>
<span class="Comment">; provides first-class support for compound types: arrays and records.</span>
<span class="Comment">;</span>
<span class="Comment">; 'get' accesses fields in records</span>
<span class="Comment">; 'index' accesses indices in arrays</span>
<span class="Comment">;</span>
<span class="Comment">; Both operations require knowledge about the types being worked on, so all</span>
<span class="Comment">; types used in mu programs are defined in a single global system-wide table</span>
<span class="Comment">; (see types* in mu.arc for the complete list of types; we'll add to it over</span>
<span class="Comment">; time).</span>
<span class="Comment">; first a sanity check that the table of types is consistent</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>each <span class="Delimiter">(</span>typ typeinfo<span class="Delimiter">)</span> <span class="Global">types*</span>
<span class="Delimiter">(</span>when typeinfo!record
<span class="Delimiter">(</span>assert <span class="Delimiter">(</span>is typeinfo!size <span class="Delimiter">(</span>len typeinfo!elems<span class="Delimiter">)))</span>
<span class="Delimiter">(</span>when typeinfo!fields
<span class="Delimiter">(</span>assert <span class="Delimiter">(</span>is typeinfo!size <span class="Delimiter">(</span>len typeinfo!fields<span class="Delimiter">))))))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"get-record"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> integer-boolean-pair<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> integer-boolean-pair<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">0</span> offset<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">34</span> <span class="Constant">2</span> nil <span class="Constant">3</span> nil <span class="Constant">4</span> <span class="Constant">34</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'get' accesses fields of records"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"get-indirect"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer-boolean-pair-address<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">3</span> integer-boolean-pair-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">3</span> integer-boolean-pair-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">0</span> offset<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">34</span> <span class="Constant">2</span> nil <span class="Constant">3</span> <span class="Constant">1</span> <span class="Constant">4</span> nil <span class="Constant">5</span> <span class="Constant">34</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'get' accesses fields of record address"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"get-compound-field"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">35</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">36</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer-integer-pair<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> integer-point-pair<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> offset<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">34</span> <span class="Constant">2</span> <span class="Constant">35</span> <span class="Constant">3</span> <span class="Constant">36</span> <span class="Constant">4</span> <span class="Constant">35</span> <span class="Constant">5</span> <span class="Constant">36</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'get' accesses fields spanning multiple locations"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"get-address"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> boolean-address<span class="Delimiter">)</span> <span class="Op"><-</span> get-address <span class="Delimiter">(</span><span class="Constant">1</span> integer-boolean-pair<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> offset<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">34</span> <span class="Constant">2</span> t <span class="Constant">3</span> <span class="Constant">2</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'get-address' returns address of fields of records"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"get-address-indirect"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer-boolean-pair-address<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> boolean-address<span class="Delimiter">)</span> <span class="Op"><-</span> get-address <span class="Delimiter">(</span><span class="Constant">3</span> integer-boolean-pair-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> offset<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">34</span> <span class="Constant">2</span> t <span class="Constant">3</span> <span class="Constant">1</span> <span class="Constant">4</span> <span class="Constant">2</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'get-address' accesses fields of record address"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"index-literal"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">23</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">24</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">6</span> integer-boolean-pair<span class="Delimiter">)</span> <span class="Op"><-</span> index <span class="Delimiter">(</span><span class="Constant">1</span> integer-boolean-pair-array<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">2</span> <span class="Constant">2</span> <span class="Constant">23</span> <span class="Constant">3</span> nil <span class="Constant">4</span> <span class="Constant">24</span> <span class="Constant">5</span> t <span class="Constant">6</span> <span class="Constant">24</span> <span class="Constant">7</span> t<span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'index' accesses indices of arrays"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"index-direct"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">23</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">24</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">6</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">7</span> integer-boolean-pair<span class="Delimiter">)</span> <span class="Op"><-</span> index <span class="Delimiter">(</span><span class="Constant">1</span> integer-boolean-pair-array<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">6</span> integer<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">2</span> <span class="Constant">2</span> <span class="Constant">23</span> <span class="Constant">3</span> nil <span class="Constant">4</span> <span class="Constant">24</span> <span class="Constant">5</span> t <span class="Constant">6</span> <span class="Constant">1</span> <span class="Constant">7</span> <span class="Constant">24</span> <span class="Constant">8</span> t<span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'index' accesses indices of arrays"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"index-indirect"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">23</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">24</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">6</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">7</span> integer-boolean-pair-array-address<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">8</span> integer-boolean-pair<span class="Delimiter">)</span> <span class="Op"><-</span> index <span class="Delimiter">(</span><span class="Constant">7</span> integer-boolean-pair-array-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">6</span> integer<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (= dump-trace* (obj blacklist '("sz" "m" "setm" "addr" "cvt0" "cvt1")))</span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">2</span> <span class="Constant">2</span> <span class="Constant">23</span> <span class="Constant">3</span> nil <span class="Constant">4</span> <span class="Constant">24</span> <span class="Constant">5</span> t <span class="Constant">6</span> <span class="Constant">1</span> <span class="Constant">7</span> <span class="Constant">1</span> <span class="Constant">8</span> <span class="Constant">24</span> <span class="Constant">9</span> t<span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'index' accesses indices of array address"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"index-address"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">23</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">24</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">6</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">7</span> integer-boolean-pair-address<span class="Delimiter">)</span> <span class="Op"><-</span> index-address <span class="Delimiter">(</span><span class="Constant">1</span> integer-boolean-pair-array<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">6</span> integer<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">2</span> <span class="Constant">2</span> <span class="Constant">23</span> <span class="Constant">3</span> nil <span class="Constant">4</span> <span class="Constant">24</span> <span class="Constant">5</span> t <span class="Constant">6</span> <span class="Constant">1</span> <span class="Constant">7</span> <span class="Constant">4</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'index-address' returns addresses of indices of arrays"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"index-address-indirect"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">23</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">24</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">6</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">7</span> integer-boolean-pair-array-address<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">8</span> integer-boolean-pair-address<span class="Delimiter">)</span> <span class="Op"><-</span> index-address <span class="Delimiter">(</span><span class="Constant">7</span> integer-boolean-pair-array-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">6</span> integer<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">2</span> <span class="Constant">2</span> <span class="Constant">23</span> <span class="Constant">3</span> nil <span class="Constant">4</span> <span class="Constant">24</span> <span class="Constant">5</span> t <span class="Constant">6</span> <span class="Constant">1</span> <span class="Constant">7</span> <span class="Constant">1</span> <span class="Constant">8</span> <span class="Constant">4</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'index-address' returns addresses of indices of array addresses"</span><span class="Delimiter">))</span>
<span class="Comment">; Array values know their length. Record lengths are saved in the types table.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"len-array"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">23</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">24</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">6</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> len <span class="Delimiter">(</span><span class="Constant">1</span> integer-boolean-pair-array<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">2</span> <span class="Constant">2</span> <span class="Constant">23</span> <span class="Constant">3</span> nil <span class="Constant">4</span> <span class="Constant">24</span> <span class="Constant">5</span> t <span class="Constant">6</span> <span class="Constant">2</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'len' accesses length of array"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"len-array-indirect"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">23</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">24</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">6</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">7</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> len <span class="Delimiter">(</span><span class="Constant">6</span> integer-boolean-pair-array-address deref<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="CommentedCode">;? (= dump-trace* (obj blacklist '("sz" "m" "setm" "addr" "cvt0" "cvt1")))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">2</span> <span class="Constant">2</span> <span class="Constant">23</span> <span class="Constant">3</span> nil <span class="Constant">4</span> <span class="Constant">24</span> <span class="Constant">5</span> t <span class="Constant">6</span> <span class="Constant">1</span> <span class="Constant">7</span> <span class="Constant">2</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'len' accesses length of array address"</span><span class="Delimiter">))</span>
<span class="Comment">; 'sizeof' is a helper to determine the amount of memory required by a type.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"sizeof-record"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> sizeof <span class="Delimiter">(</span>integer-boolean-pair literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.1</span> <span class="Constant">2</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'sizeof' returns space required by arg"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"sizeof-record-not-len"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> sizeof <span class="Delimiter">(</span>integer-point-pair literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.1</span> <span class="Constant">3</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'sizeof' is different from number of elems"</span><span class="Delimiter">))</span>
<span class="Comment">; Regardless of a type's length, you can move it around just like a primitive.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"compound-operand-copy"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer-boolean-pair<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="Constant">1</span> integer-boolean-pair<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">34</span> <span class="Constant">2</span> nil <span class="Constant">3</span> <span class="Constant">34</span> <span class="Constant">4</span> nil<span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - ops can operate on records spanning multiple locations"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"compound-arg"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer-boolean-pair<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>test1 <span class="Delimiter">(</span><span class="Constant">1</span> integer-boolean-pair<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">34</span> <span class="Constant">2</span> nil <span class="Constant">4</span> <span class="Constant">34</span> <span class="Constant">5</span> nil<span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'arg' can copy records spanning multiple locations"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"compound-arg-indirect"</span><span class="Delimiter">)</span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer-boolean-pair<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer-boolean-pair-address<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>test1 <span class="Delimiter">(</span><span class="Constant">3</span> integer-boolean-pair-address deref<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">34</span> <span class="Constant">2</span> nil <span class="Constant">3</span> <span class="Constant">1</span> <span class="Constant">4</span> <span class="Constant">34</span> <span class="Constant">5</span> nil<span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'arg' can copy records spanning multiple locations in indirect mode"</span><span class="Delimiter">))</span>
<span class="Comment">; A special kind of record is the 'tagged type'. It lets us represent</span>
<span class="Comment">; dynamically typed values, which save type information in memory rather than</span>
<span class="Comment">; in the code to use them. This will let us do things like create heterogenous</span>
<span class="Comment">; lists containing both integers and strings. Tagged values admit two</span>
<span class="Comment">; operations:</span>
<span class="Comment">;</span>
<span class="Comment">; 'save-type' - turns a regular value into a tagged-value of the appropriate type</span>
<span class="Comment">; 'maybe-coerce' - turns a tagged value into a regular value if the type matches</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"tagged-value"</span><span class="Delimiter">)</span>
<span class="CommentedCode">;? (= dump-trace* (obj blacklist '("sz" "m" "setm" "addr" "cvt0" "cvt1")))</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> type<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span>integer-address literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span> <span class="Comment">; pointer to nowhere</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer-address<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">4</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> maybe-coerce <span class="Delimiter">(</span><span class="Constant">1</span> tagged-value<span class="Delimiter">)</span> <span class="Delimiter">(</span>integer-address literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="CommentedCode">;? (prn completed-routines*)</span>
<span class="Delimiter">(</span><span class="Normal">let</span> last-routine <span class="Delimiter">(</span>deq <span class="Global">completed-routines*</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>aif rep.last-routine!error <span class="Delimiter">(</span>prn <span class="Constant">"error - "</span> it<span class="Delimiter">)))</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.3</span> <span class="Constant">34</span><span class="Delimiter">)</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.4</span> t<span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'maybe-coerce' copies value only if type tag matches"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"tagged-value-2"</span><span class="Delimiter">)</span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> type<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span>integer-address literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span> <span class="Comment">; pointer to nowhere</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer-address<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">4</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> maybe-coerce <span class="Delimiter">(</span><span class="Constant">1</span> tagged-value<span class="Delimiter">)</span> <span class="Delimiter">(</span>boolean-address literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.3</span> <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.4</span> nil<span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'maybe-coerce' doesn't copy value when type tag doesn't match"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"save-type"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span> <span class="Comment">; pointer to nowhere</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> tagged-value<span class="Delimiter">)</span> <span class="Op"><-</span> save-type <span class="Delimiter">(</span><span class="Constant">1</span> integer-address<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">34</span> <span class="Constant">2</span> <span class="Delimiter">'</span>integer-address <span class="Constant">3</span> <span class="Constant">34</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'save-type' saves the type of a value at runtime, turning it into a tagged-value"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-tagged-value"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span> <span class="Comment">; pointer to nowhere</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-tagged-value <span class="Delimiter">(</span>integer-address literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">1</span> integer-address<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer-address<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">4</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> maybe-coerce <span class="Delimiter">(</span><span class="Constant">2</span> tagged-value-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>integer-address literal<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (= dump-trace* (obj blacklist '("sz" "m" "setm" "addr" "cvt0" "cvt1" "sizeof")))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.3</span> <span class="Constant">34</span><span class="Delimiter">)</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.4</span> t<span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'new-tagged-value' is the converse of 'maybe-coerce'"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Comment">; Now that we can record types for values we can construct a dynamically typed</span>
<span class="Comment">; list.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"list"</span><span class="Delimiter">)</span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Comment">; 1 points at first node: tagged-value (int 34)</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> list-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>list literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> list-value-address <span class="Delimiter">(</span><span class="Constant">1</span> list-address<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> type-address<span class="Delimiter">)</span> <span class="Op"><-</span> get-address <span class="Delimiter">(</span><span class="Constant">2</span> tagged-value-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">0</span> offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> type-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span>integer literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> location<span class="Delimiter">)</span> <span class="Op"><-</span> get-address <span class="Delimiter">(</span><span class="Constant">2</span> tagged-value-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> location deref<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> list-address-address<span class="Delimiter">)</span> <span class="Op"><-</span> get-address <span class="Delimiter">(</span><span class="Constant">1</span> list-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> list-address-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>list literal<span class="Delimiter">))</span></span>
<span class="Comment">; 6 points at second node: tagged-value (boolean t)</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">6</span> list-address<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="Constant">5</span> list-address-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">7</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> list-value-address <span class="Delimiter">(</span><span class="Constant">6</span> list-address<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">8</span> type-address<span class="Delimiter">)</span> <span class="Op"><-</span> get-address <span class="Delimiter">(</span><span class="Constant">7</span> tagged-value-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">0</span> offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">8</span> type-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span>boolean literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">9</span> location<span class="Delimiter">)</span> <span class="Op"><-</span> get-address <span class="Delimiter">(</span><span class="Constant">7</span> tagged-value-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">9</span> location deref<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">10</span> list-address<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">6</span> list-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> offset<span class="Delimiter">))</span></span>
<span class="Delimiter">)))</span>
<span class="Delimiter">(</span><span class="Normal">let</span> first Memory-in-use-until
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>test1<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>~all first <span class="Delimiter">(</span><span class="Identifier">map</span> <span class="Global">memory*</span> <span class="Delimiter">'(</span><span class="Constant">1</span> <span class="Constant">2</span> <span class="Constant">3</span><span class="Delimiter">)))</span>
<span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Error">.first</span> <span class="Delimiter">'</span>integer<span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.4</span> <span class="Delimiter">(</span><span class="Identifier">+</span> first <span class="Constant">1</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>~is <span class="Delimiter">(</span><span class="Global">memory*</span> <span class="Delimiter">(</span><span class="Identifier">+</span> first <span class="Constant">1</span><span class="Delimiter">))</span> <span class="Constant">34</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.5</span> <span class="Delimiter">(</span><span class="Identifier">+</span> first <span class="Constant">2</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span><span class="Normal">let</span> second <span class="Global">memory*</span><span class="Constant">.6</span>
<span class="Delimiter">(</span><span class="Normal">or</span>
<span class="Delimiter">(</span>~is <span class="Delimiter">(</span><span class="Global">memory*</span> <span class="Delimiter">(</span><span class="Identifier">+</span> first <span class="Constant">2</span><span class="Delimiter">))</span> second<span class="Delimiter">)</span>
<span class="Delimiter">(</span>~all second <span class="Delimiter">(</span><span class="Identifier">map</span> <span class="Global">memory*</span> <span class="Delimiter">'(</span><span class="Constant">6</span> <span class="Constant">7</span> <span class="Constant">8</span><span class="Delimiter">)))</span>
<span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Error">.second</span> <span class="Delimiter">'</span>boolean<span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.9</span> <span class="Delimiter">(</span><span class="Identifier">+</span> second <span class="Constant">1</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>~is <span class="Delimiter">(</span><span class="Global">memory*</span> <span class="Delimiter">(</span><span class="Identifier">+</span> second <span class="Constant">1</span><span class="Delimiter">))</span> t<span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.10</span> nil<span class="Delimiter">))))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - lists can contain elements of different types"</span><span class="Delimiter">)))</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test2</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">10</span> list-address<span class="Delimiter">)</span> <span class="Op"><-</span> list-next <span class="Delimiter">(</span><span class="Constant">1</span> list-address<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>test2<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.10</span> <span class="Global">memory*</span><span class="Constant">.6</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'list-next can move a list pointer to the next node"</span><span class="Delimiter">))</span>
<span class="Comment">; 'new-list' takes a variable number of args and constructs a list containing</span>
<span class="Comment">; them.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-list"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> new-list <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">5</span> literal<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (= dump-trace* (obj blacklist '("sz" "m" "setm" "addr" "cvt0" "cvt1" "sizeof")))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">let</span> first <span class="Global">memory*</span><span class="Constant">.1</span>
<span class="CommentedCode">;? (prn first)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Error">.first</span> <span class="Delimiter">'</span>integer<span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is <span class="Delimiter">(</span><span class="Global">memory*</span> <span class="Delimiter">(</span><span class="Identifier">+</span> first <span class="Constant">1</span><span class="Delimiter">))</span> <span class="Constant">3</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Normal">let</span> second <span class="Delimiter">(</span><span class="Global">memory*</span> <span class="Delimiter">(</span><span class="Identifier">+</span> first <span class="Constant">2</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (prn second)</span>
<span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Error">.second</span> <span class="Delimiter">'</span>integer<span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is <span class="Delimiter">(</span><span class="Global">memory*</span> <span class="Delimiter">(</span><span class="Identifier">+</span> second <span class="Constant">1</span><span class="Delimiter">))</span> <span class="Constant">4</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Normal">let</span> third <span class="Delimiter">(</span><span class="Global">memory*</span> <span class="Delimiter">(</span><span class="Identifier">+</span> second <span class="Constant">2</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (prn third)</span>
<span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Error">.third</span> <span class="Delimiter">'</span>integer<span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is <span class="Delimiter">(</span><span class="Global">memory*</span> <span class="Delimiter">(</span><span class="Identifier">+</span> third <span class="Constant">1</span><span class="Delimiter">))</span> <span class="Constant">5</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is <span class="Delimiter">(</span><span class="Global">memory*</span> <span class="Delimiter">(</span><span class="Identifier">+</span> third <span class="Constant">2</span><span class="Delimiter">)</span> nil<span class="Delimiter">)))))))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'new-list' can construct a list of integers"</span><span class="Delimiter">)))</span>
<span class="SalientComment">;; Functions</span>
<span class="Comment">;</span>
<span class="Comment">; Just like the table of types is centralized, functions are conceptualized as</span>
<span class="Comment">; a centralized table of operations just like the "primitives" we've seen so</span>
<span class="Comment">; far. If you create a function you can call it like any other op.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-fn"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)))</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>test1<span class="Delimiter">))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">1</span> <span class="Constant">2</span> <span class="Constant">3</span> <span class="Constant">3</span> <span class="Constant">4</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - calling a user-defined function runs its instructions"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-fn-once"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">)))</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">(</span>test1<span class="Delimiter">))))</span></span>
<span class="CommentedCode">;? (= dump-trace* (obj whitelist '("run")))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Constant">2</span> <span class="Global">curr-cycle*</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - calling a user-defined function runs its instructions exactly once "</span> <span class="Global">curr-cycle*</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Comment">; User-defined functions communicate with their callers through two</span>
<span class="Comment">; primitives:</span>
<span class="Comment">;</span>
<span class="Comment">; 'arg' - to access inputs</span>
<span class="Comment">; 'reply' - to return outputs</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-fn-reply"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">)))</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>test1<span class="Delimiter">))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">1</span> <span class="Constant">2</span> <span class="Constant">3</span> <span class="Constant">3</span> <span class="Constant">4</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'reply' stops executing the current function"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-fn-reply-nested"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> test2<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>test2</span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)))</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>test1<span class="Delimiter">))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">2</span> <span class="Constant">34</span> <span class="Constant">3</span> <span class="Constant">34</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'reply' stops executing any callers as necessary"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-fn-reply-once"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">)))</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>test1<span class="Delimiter">))))</span></span>
<span class="CommentedCode">;? (= dump-trace* (obj whitelist '("run")))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Constant">5</span> <span class="Global">curr-cycle*</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'reply' executes instructions exactly once "</span> <span class="Global">curr-cycle*</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-fn-arg-sequential"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">5</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">)))</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>test1 <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Delimiter">)))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">1</span> <span class="Constant">2</span> <span class="Constant">3</span> <span class="Constant">3</span> <span class="Constant">4</span>
<span class="Comment">; add-fn's temporaries</span>
<span class="Constant">4</span> <span class="Constant">1</span> <span class="Constant">5</span> <span class="Constant">3</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'arg' accesses in order the operands of the most recent function call (the caller)"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-fn-arg-random-access"</span><span class="Delimiter">)</span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span> <span class="Delimiter">(</span><span class="MuConstant">0</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">5</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">)))</span> <span class="Comment">; should never run</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>test1 <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Delimiter">)))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">1</span> <span class="Constant">2</span> <span class="Constant">3</span> <span class="Constant">3</span> <span class="Constant">4</span>
<span class="Comment">; add-fn's temporaries</span>
<span class="Constant">4</span> <span class="Constant">1</span> <span class="Constant">5</span> <span class="Constant">3</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'arg' with index can access function call arguments out of order"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-fn-arg-status"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">5</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">(</span>test1 <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Delimiter">)))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">4</span> <span class="Constant">1</span> <span class="Constant">5</span> t<span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'arg' sets a second oarg when arg exists"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-fn-arg-missing"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">(</span>test1 <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Delimiter">)))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">4</span> <span class="Constant">1</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - missing 'arg' doesn't cause error"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-fn-arg-missing-2"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">6</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">(</span>test1 <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Delimiter">)))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">4</span> <span class="Constant">1</span> <span class="Constant">6</span> nil<span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - missing 'arg' wipes second oarg when provided"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-fn-arg-missing-3"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">6</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">(</span>test1 <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Delimiter">)))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">4</span> <span class="Constant">1</span> <span class="Constant">6</span> nil<span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - missing 'arg' consistently wipes its oarg"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-fn-arg-missing-4"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Comment">; if given two args, adds them; if given one arg, increments</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">6</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Mu">{ <span class="muHack">begin</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">break-if</span> <span class="Delimiter">(</span><span class="Constant">6</span> boolean<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu">}</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">7</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">5</span> integer<span class="Delimiter">)))</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">(</span>test1 <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Delimiter">)))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">4</span> <span class="Constant">34</span> <span class="Constant">5</span> <span class="Constant">1</span> <span class="Constant">6</span> nil <span class="Constant">7</span> <span class="Constant">35</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - function with optional second arg"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-fn-arg-by-value"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">0</span> literal<span class="Delimiter">))</span> <span class="Comment">; overwrite caller memory</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">))</span> <span class="Comment">; arg not clobbered</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>test1 <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">0</span> <span class="Constant">2</span> <span class="Constant">34</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'arg' passes by value"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-fn-reply-oarg"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">6</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">5</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span> <span class="Delimiter">(</span><span class="Constant">6</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">)))</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> test1 <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">1</span> <span class="Constant">2</span> <span class="Constant">3</span> <span class="Constant">3</span> <span class="Constant">4</span>
<span class="Comment">; add-fn's temporaries</span>
<span class="Constant">4</span> <span class="Constant">1</span> <span class="Constant">5</span> <span class="Constant">3</span> <span class="Constant">6</span> <span class="Constant">4</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'reply' can take aguments that are returned, or written back into output args of caller"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-fn-reply-oarg-multiple"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">6</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">5</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span> <span class="Delimiter">(</span><span class="Constant">6</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">5</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">)))</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">7</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> test1 <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">1</span> <span class="Constant">2</span> <span class="Constant">3</span> <span class="Constant">3</span> <span class="Constant">4</span> <span class="Constant">7</span> <span class="Constant">3</span>
<span class="Comment">; add-fn's temporaries</span>
<span class="Constant">4</span> <span class="Constant">1</span> <span class="Constant">5</span> <span class="Constant">3</span> <span class="Constant">6</span> <span class="Constant">4</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'reply' permits a function to return multiple values at once"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-fn-prepare-reply"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">6</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">5</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>prepare-reply <span class="Delimiter">(</span><span class="Constant">6</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">5</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">)))</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">7</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> test1 <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">1</span> <span class="Constant">2</span> <span class="Constant">3</span> <span class="Constant">3</span> <span class="Constant">4</span> <span class="Constant">7</span> <span class="Constant">3</span>
<span class="Comment">; add-fn's temporaries</span>
<span class="Constant">4</span> <span class="Constant">1</span> <span class="Constant">5</span> <span class="Constant">3</span> <span class="Constant">6</span> <span class="Constant">4</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - without args, 'reply' returns values from previous 'prepare-reply'."</span><span class="Delimiter">))</span>
<span class="SalientComment">;; Structured programming</span>
<span class="Comment">;</span>
<span class="Comment">; Our control operators are quite inconvenient to use, so mu provides a</span>
<span class="Comment">; lightweight tool called 'convert-braces' to work in a slightly more</span>
<span class="Comment">; convenient format with nested braces:</span>
<span class="Comment">;</span>
<span class="Comment">; {</span>
<span class="Comment">; some instructions</span>
<span class="Comment">; {</span>
<span class="Comment">; more instructions</span>
<span class="Comment">; }</span>
<span class="Comment">; }</span>
<span class="Comment">;</span>
<span class="Comment">; Braces are just labels, they require no special parsing. The operations</span>
<span class="Comment">; 'break' and 'continue' jump to just after the enclosing '}' and '{'</span>
<span class="Comment">; respectively.</span>
<span class="Comment">;</span>
<span class="Comment">; Conditional and unconditional 'break' and 'continue' should give us 80% of</span>
<span class="Comment">; the benefits of the control-flow primitives we're used to in other</span>
<span class="Comment">; languages, like 'if', 'while', 'for', etc.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"convert-braces"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Delimiter">(</span>convert-braces
<span class="Mu"><span class="Delimiter">'(((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Mu">{ <span class="muHack">begin</span> <span class="Comment">; 'begin' is just a hack because racket turns curlies into parens</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> neq <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">break-if</span> <span class="Delimiter">(</span><span class="Constant">4</span> boolean<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu">}</span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">)))</span></span>
<span class="Mu"><span class="Delimiter">'(((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> neq <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">jump-if</span> <span class="Delimiter">(</span><span class="Constant">4</span> boolean<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">)))</span></span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - convert-braces replaces break-if with a jump-if to after the next close-curly"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"convert-braces-empty-block"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Delimiter">(</span>convert-braces
<span class="Mu"><span class="Delimiter">'(((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Mu">{ <span class="muHack">begin</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">break</span><span class="Delimiter">)</span></span>
<span class="Mu">}</span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">)))</span></span>
<span class="Mu"><span class="Delimiter">'(((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">jump</span> <span class="Delimiter">(</span><span class="MuConstant">0</span> offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">)))</span></span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - convert-braces works for degenerate blocks"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"convert-braces-nested-break"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Delimiter">(</span>convert-braces
<span class="Mu"><span class="Delimiter">'(((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Mu">{ <span class="muHack">begin</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> neq <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">break-if</span> <span class="Delimiter">(</span><span class="Constant">4</span> boolean<span class="Delimiter">))</span></span>
<span class="Mu">{ <span class="muHack">begin</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu">}</span>
<span class="Mu">}</span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">)))</span></span>
<span class="Mu"><span class="Delimiter">'(((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> neq <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">jump-if</span> <span class="Delimiter">(</span><span class="Constant">4</span> boolean<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">)))</span></span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - convert-braces balances curlies when converting break"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"convert-braces-nested-continue"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Delimiter">(</span>convert-braces
<span class="Mu"><span class="Delimiter">'(((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu">{ <span class="muHack">begin</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Mu">{ <span class="muHack">begin</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> neq <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> integer<span class="Delimiter">))</span></span>
<span class="Mu">}</span>
<span class="Delimiter">(</span><span class="Identifier">continue-if</span> <span class="Delimiter">(</span><span class="Constant">4</span> boolean<span class="Delimiter">))</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu">}</span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">)))</span></span>
<span class="Mu"><span class="Delimiter">'(((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> neq <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">jump-if</span> <span class="Delimiter">(</span><span class="Constant">4</span> boolean<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">-3</span> offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">)))</span></span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - convert-braces balances curlies when converting continue"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"continue"</span><span class="Delimiter">)</span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu">{ <span class="muHack">begin</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> neq <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">continue-if</span> <span class="Delimiter">(</span><span class="Constant">3</span> boolean<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu">}</span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">))))</span></span>
<span class="CommentedCode">;? (each stmt function*!main</span>
<span class="CommentedCode">;? (prn stmt))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">4</span> <span class="Constant">2</span> <span class="Constant">4</span> <span class="Constant">3</span> nil <span class="Constant">4</span> <span class="Constant">34</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - continue correctly loops"</span><span class="Delimiter">))</span>
<span class="Comment">; todo: fuzz-test invariant: convert-braces offsets should be robust to any</span>
<span class="Comment">; number of inner blocks inside but not around the continue block.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"continue-nested"</span><span class="Delimiter">)</span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu">{ <span class="muHack">begin</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Mu">{ <span class="muHack">begin</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> neq <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Mu">}</span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">continue-if</span> <span class="Delimiter">(</span><span class="Constant">3</span> boolean<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu">}</span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">))))</span></span>
<span class="CommentedCode">;? (each stmt function*!main</span>
<span class="CommentedCode">;? (prn stmt))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">4</span> <span class="Constant">2</span> <span class="Constant">4</span> <span class="Constant">3</span> nil <span class="Constant">4</span> <span class="Constant">34</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - continue correctly loops"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"continue-fail"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu">{ <span class="muHack">begin</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Mu">{ <span class="muHack">begin</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> neq <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))</span></span>
<span class="Mu">}</span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">continue-if</span> <span class="Delimiter">(</span><span class="Constant">3</span> boolean<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu">}</span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span><span class="Delimiter">))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">4</span> <span class="Constant">2</span> <span class="Constant">4</span> <span class="Constant">3</span> nil <span class="Constant">4</span> <span class="Constant">34</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - continue might never trigger"</span><span class="Delimiter">))</span>
<span class="SalientComment">;; Variables</span>
<span class="Comment">;</span>
<span class="Comment">; A big convenience high-level languages provide is the ability to name memory</span>
<span class="Comment">; locations. In mu, a lightweight tool called 'convert-names' provides this</span>
<span class="Comment">; convenience.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="CommentedCode">;? (new-trace "convert-names")</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Delimiter">(</span>convert-names
<span class="Mu"><span class="Delimiter">'(((</span>x integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span>y integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span>z integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span>x integer<span class="Delimiter">)</span> <span class="Delimiter">(</span>y integer<span class="Delimiter">))))</span></span>
<span class="Mu"><span class="Delimiter">'(((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))))</span></span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - convert-names renames symbolic names to integer locations"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="CommentedCode">;? (new-trace "convert-names-compound")</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Delimiter">(</span>convert-names
<span class="Mu"><span class="Delimiter">'(((</span>x integer-boolean-pair<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span>y integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))))</span></span>
<span class="Mu"><span class="Delimiter">'(((</span><span class="Constant">1</span> integer-boolean-pair<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))))</span></span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - convert-names increments integer locations by the size of the type of the previous var"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="CommentedCode">;? (new-trace "convert-names-nil")</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Delimiter">(</span>convert-names
<span class="Mu"><span class="Delimiter">'(((</span>x integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span>y integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span>nil integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span>x integer<span class="Delimiter">)</span> <span class="Delimiter">(</span>y integer<span class="Delimiter">))))</span></span>
<span class="Mu"><span class="Delimiter">'(((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span>nil integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))))</span></span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - convert-names never renames nil"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="CommentedCode">;? (new-trace "convert-names-global")</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Delimiter">(</span>convert-names
<span class="Mu"><span class="Delimiter">'(((</span>x integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span>y integer global<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#00af87'>default-scope</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span>x integer<span class="Delimiter">)</span> <span class="Delimiter">(</span>y integer global<span class="Delimiter">))))</span></span>
<span class="Mu"><span class="Delimiter">'(((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span>y integer global<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#00af87'>default-scope</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span>y integer global<span class="Delimiter">))))</span></span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - convert-names never renames global operands"</span><span class="Delimiter">))</span>
<span class="Comment">; kludgy support for 'fork' below</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="CommentedCode">;? (new-trace "convert-names-functions")</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Delimiter">(</span>convert-names
<span class="Mu"><span class="Delimiter">'(((</span>x integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span>y integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span>z fn<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span>x integer<span class="Delimiter">)</span> <span class="Delimiter">(</span>y integer<span class="Delimiter">))))</span></span>
<span class="Mu"><span class="Delimiter">'(((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span>z fn<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))))</span></span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - convert-names never renames nil"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="CommentedCode">;? (new-trace "convert-names-record-fields")</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Delimiter">(</span>convert-names
<span class="Mu"><span class="Delimiter">'(((</span>x integer<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">34</span> integer-boolean-pair<span class="Delimiter">)</span> <span class="Delimiter">(</span>bool offset<span class="Delimiter">))))</span></span>
<span class="Mu"><span class="Delimiter">'(((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">34</span> integer-boolean-pair<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> offset<span class="Delimiter">))))</span></span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - convert-names replaces record field offsets"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="CommentedCode">;? (new-trace "convert-names-record-fields-ambiguous")</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>errsafe <span class="Delimiter">(</span>convert-names
<span class="Mu"><span class="Delimiter">'(((</span>bool boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span>x integer<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">34</span> integer-boolean-pair<span class="Delimiter">)</span> <span class="Delimiter">(</span>bool offset<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - convert-names doesn't allow offsets and variables with the same name in a function"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="CommentedCode">;? (new-trace "convert-names-record-fields-ambiguous-2")</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>errsafe <span class="Delimiter">(</span>convert-names
<span class="Mu"><span class="Delimiter">'(((</span>x integer<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">34</span> integer-boolean-pair<span class="Delimiter">)</span> <span class="Delimiter">(</span>bool offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span>bool boolean<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - convert-names doesn't allow offsets and variables with the same name in a function - 2"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="CommentedCode">;? (new-trace "convert-names-record-fields-indirect")</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Delimiter">(</span>convert-names
<span class="Mu"><span class="Delimiter">'(((</span>x integer<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">34</span> integer-boolean-pair-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>bool offset<span class="Delimiter">))))</span></span>
<span class="Mu"><span class="Delimiter">'(((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">34</span> integer-boolean-pair-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> offset<span class="Delimiter">))))</span></span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - convert-names replaces field offsets for record addresses"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="CommentedCode">;? (new-trace "convert-names-record-fields-multiple")</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Delimiter">(</span>convert-names
<span class="Mu"><span class="Delimiter">'(((</span><span class="Constant">2</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> integer-boolean-pair<span class="Delimiter">)</span> <span class="Delimiter">(</span>bool offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> integer-boolean-pair<span class="Delimiter">)</span> <span class="Delimiter">(</span>bool offset<span class="Delimiter">))))</span></span>
<span class="Mu"><span class="Delimiter">'(((</span><span class="Constant">2</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> integer-boolean-pair<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> integer-boolean-pair<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> offset<span class="Delimiter">))))</span></span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - convert-names replaces field offsets with multiple mentions"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Comment">; A rudimentary memory allocator. Eventually we want to write this in mu.</span>
<span class="Comment">;</span>
<span class="Comment">; No deallocation yet; let's see how much code we can build in mu before we</span>
<span class="Comment">; feel the need for it.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-primitive"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>integer literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span><span class="Normal">let</span> before Memory-in-use-until
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span><span class="Constant">.1</span> before<span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'new' returns current high-water mark"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso Memory-in-use-until <span class="Delimiter">(</span><span class="Identifier">+</span> before <span class="Constant">1</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'new' on primitive types increments high-water mark by their size"</span><span class="Delimiter">)))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-array-literal"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> type-array-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>type-array literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">5</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span><span class="Normal">let</span> before Memory-in-use-until
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span><span class="Constant">.1</span> before<span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'new' on array with literal size returns current high-water mark"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso Memory-in-use-until <span class="Delimiter">(</span><span class="Identifier">+</span> before <span class="Constant">6</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'new' on primitive arrays increments high-water mark by their size"</span><span class="Delimiter">)))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"new-array-direct"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">5</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> type-array-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>type-array literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span><span class="Normal">let</span> before Memory-in-use-until
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span><span class="Constant">.2</span> before<span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'new' on array with variable size returns current high-water mark"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso Memory-in-use-until <span class="Delimiter">(</span><span class="Identifier">+</span> before <span class="Constant">6</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'new' on primitive arrays increments high-water mark by their (variable) size"</span><span class="Delimiter">)))</span>
<span class="Comment">; Even though our memory locations can now have names, the names are all</span>
<span class="Comment">; globals, accessible from any function. To isolate functions from their</span>
<span class="Comment">; callers we need local variables, and mu provides them using a special</span>
<span class="Comment">; variable called <span style='color:#00af87'>default-scope</span>. When you initialize such a variable (likely</span>
<span class="Comment">; with a call to our just-defined memory allocator) mu interprets memory</span>
<span class="Comment">; locations as offsets from its value. If <span style='color:#00af87'>default-scope</span> is set to 1000, for</span>
<span class="Comment">; example, reads and writes to memory location 1 will really go to 1001.</span>
<span class="Comment">;</span>
<span class="Comment">; '<span style='color:#00af87'>default-scope</span>' is itself hard-coded to be function-local; it's nil in a new</span>
<span class="Comment">; function, and it's restored when functions return to their callers. But the</span>
<span class="Comment">; actual scope allocation is independent. So you can define closures, or do</span>
<span class="Comment">; even more funky things like share locals between two coroutines.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"set-default-scope"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#00af87'>default-scope</span> scope-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>scope literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">23</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span><span class="Normal">let</span> before Memory-in-use-until
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~and <span class="Delimiter">(</span>~is <span class="Constant">23</span> <span class="Global">memory*</span><span class="Constant">.1</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>is <span class="Constant">23</span> <span class="Delimiter">(</span><span class="Global">memory*</span> <span class="Delimiter">(</span><span class="Identifier">+</span> before <span class="Constant">1</span><span class="Delimiter">))))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - <span style='color:#00af87'>default-scope</span> implicitly modifies variable locations"</span><span class="Delimiter">)))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"set-default-scope-skips-offset"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#00af87'>default-scope</span> scope-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>scope literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">23</span> offset<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span><span class="Normal">let</span> before Memory-in-use-until
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~and <span class="Delimiter">(</span>~is <span class="Constant">23</span> <span class="Global">memory*</span><span class="Constant">.1</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>is <span class="Constant">23</span> <span class="Delimiter">(</span><span class="Global">memory*</span> <span class="Delimiter">(</span><span class="Identifier">+</span> before <span class="Constant">1</span><span class="Delimiter">))))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - <span style='color:#00af87'>default-scope</span> skips 'offset' types just like literals"</span><span class="Delimiter">)))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"default-scope-bounds-check"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#00af87'>default-scope</span> scope-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>scope literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">23</span> literal<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">let</span> last-routine <span class="Delimiter">(</span>deq <span class="Global">completed-routines*</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>no rep.last-routine!error<span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - <span style='color:#00af87'>default-scope</span> checks bounds"</span><span class="Delimiter">)))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"default-scope-and-get-indirect"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#00af87'>default-scope</span> scope-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>scope literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">5</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer-boolean-pair-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>integer-boolean-pair literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> get-address <span class="Delimiter">(</span><span class="Constant">1</span> integer-boolean-pair-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">0</span> offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer global<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> integer-boolean-pair-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">0</span> offset<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (= dump-trace* (obj blacklist '("sz" "m" "setm" "addr" "cvt0" "cvt1")))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="CommentedCode">;? (prn (as cons completed-routines*))</span>
<span class="Delimiter">(</span><span class="Normal">let</span> last-routine <span class="Delimiter">(</span>deq <span class="Global">completed-routines*</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>aif rep.last-routine!error <span class="Delimiter">(</span>prn <span class="Constant">"error - "</span> it<span class="Delimiter">)))</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Constant">34</span> <span class="Global">memory*</span><span class="Constant">.3</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - indirect 'get' works in the presence of <span style='color:#00af87'>default-scope</span>"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"default-scope-and-index-indirect"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#00af87'>default-scope</span> scope-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>scope literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">5</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer-array-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>integer-array literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> index-address <span class="Delimiter">(</span><span class="Constant">1</span> integer-array-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">2</span> offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer global<span class="Delimiter">)</span> <span class="Op"><-</span> index <span class="Delimiter">(</span><span class="Constant">1</span> integer-array-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">2</span> offset<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (= dump-trace* (obj blacklist '("sz" "m" "setm" "addr" "cvt0" "cvt1")))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="CommentedCode">;? (prn (as cons completed-routines*))</span>
<span class="Delimiter">(</span><span class="Normal">let</span> last-routine <span class="Delimiter">(</span>deq <span class="Global">completed-routines*</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>aif rep.last-routine!error <span class="Delimiter">(</span>prn <span class="Constant">"error - "</span> it<span class="Delimiter">)))</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Constant">34</span> <span class="Global">memory*</span><span class="Constant">.3</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - indirect 'index' works in the presence of <span style='color:#00af87'>default-scope</span>"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="CommentedCode">;? (new-trace "convert-names-default-scope")</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Delimiter">(</span>convert-names
<span class="Mu"><span class="Delimiter">'(((</span>x integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span>y integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Comment">; unsafe in general; don't write random values to '<span style='color:#00af87'>default-scope</span>'</span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#00af87'>default-scope</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span>x integer<span class="Delimiter">)</span> <span class="Delimiter">(</span>y integer<span class="Delimiter">))))</span></span>
<span class="Mu"><span class="Delimiter">'(((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#00af87'>default-scope</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer<span class="Delimiter">))))</span></span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - convert-names never renames <span style='color:#00af87'>default-scope</span>"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"suppress-default-scope"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#00af87'>default-scope</span> scope-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>scope literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer global<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">23</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span><span class="Normal">let</span> before Memory-in-use-until
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~and <span class="Delimiter">(</span>is <span class="Constant">23</span> <span class="Global">memory*</span><span class="Constant">.1</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is <span class="Constant">23</span> <span class="Delimiter">(</span><span class="Global">memory*</span> <span class="Delimiter">(</span><span class="Identifier">+</span> before <span class="Constant">1</span><span class="Delimiter">))))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - <span style='color:#00af87'>default-scope</span> skipped for locations with metadata 'global'"</span><span class="Delimiter">)))</span>
<span class="SalientComment">;; Dynamic dispatch</span>
<span class="Comment">;</span>
<span class="Comment">; Putting it all together, here's how you define generic functions that run</span>
<span class="Comment">; different code based on the types of their args.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"dispatch-clause"</span><span class="Delimiter">)</span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Comment">; doesn't matter too much how many locals you allocate space for (here 20)</span>
<span class="Comment">; if it's slightly too many -- memory is plentiful</span>
<span class="Comment">; if it's too few -- mu will raise an error</span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#00af87'>default-scope</span> scope-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>scope literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">20</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#ff8700'>first-arg-box</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Comment">; if given integers, add them</span>
<span class="Mu">{ <span class="muHack">begin</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#ff8700'>first-arg</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span>match? boolean<span class="Delimiter">)</span> <span class="Op"><-</span> maybe-coerce <span class="Delimiter">(</span><span style='color:#ff8700'>first-arg-box</span> tagged-value-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>integer literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">break-unless</span> <span class="Delimiter">(</span>match? boolean<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#ffd700'>second-arg-box</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#ffd700'>second-arg</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> maybe-coerce <span class="Delimiter">(</span><span style='color:#ffd700'>second-arg-box</span> tagged-value-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>integer literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#af005f'>result</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span style='color:#ff8700'>first-arg</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span style='color:#ffd700'>second-arg</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span> <span class="Delimiter">(</span><span style='color:#af005f'>result</span> integer<span class="Delimiter">))</span></span>
<span class="Mu">}</span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span> <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">)))</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-tagged-value <span class="Delimiter">(</span>integer literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-tagged-value <span class="Delimiter">(</span>integer literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> test1 <span class="Delimiter">(</span><span class="Constant">1</span> tagged-value-address<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> tagged-value-address<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.3</span> <span class="Constant">37</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - an example function that checks that its oarg is an integer"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Comment">; todo - test that reply increments pc for caller frame after popping current frame</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"dispatch-multiple-clauses"</span><span class="Delimiter">)</span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#00af87'>default-scope</span> scope-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>scope literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">20</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#ff8700'>first-arg-box</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Comment">; if given integers, add them</span>
<span class="Mu">{ <span class="muHack">begin</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#ff8700'>first-arg</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span>match? boolean<span class="Delimiter">)</span> <span class="Op"><-</span> maybe-coerce <span class="Delimiter">(</span><span style='color:#ff8700'>first-arg-box</span> tagged-value-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>integer literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">break-unless</span> <span class="Delimiter">(</span>match? boolean<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#ffd700'>second-arg-box</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#ffd700'>second-arg</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> maybe-coerce <span class="Delimiter">(</span><span style='color:#ffd700'>second-arg-box</span> tagged-value-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>integer literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#af005f'>result</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span style='color:#ff8700'>first-arg</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span style='color:#ffd700'>second-arg</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span> <span class="Delimiter">(</span><span style='color:#af005f'>result</span> integer<span class="Delimiter">))</span></span>
<span class="Mu">}</span>
<span class="Comment">; if given booleans, or them (it's a silly kind of generic function)</span>
<span class="Mu">{ <span class="muHack">begin</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#ff8700'>first-arg</span> boolean<span class="Delimiter">)</span> <span class="Delimiter">(</span>match? boolean<span class="Delimiter">)</span> <span class="Op"><-</span> maybe-coerce <span class="Delimiter">(</span><span style='color:#ff8700'>first-arg-box</span> tagged-value-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>boolean literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">break-unless</span> <span class="Delimiter">(</span>match? boolean<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#ffd700'>second-arg-box</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#ffd700'>second-arg</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> maybe-coerce <span class="Delimiter">(</span><span style='color:#ffd700'>second-arg-box</span> tagged-value-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>boolean literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#af005f'>result</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> or <span class="Delimiter">(</span><span style='color:#ff8700'>first-arg</span> boolean<span class="Delimiter">)</span> <span class="Delimiter">(</span><span style='color:#ffd700'>second-arg</span> boolean<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span> <span class="Delimiter">(</span><span style='color:#af005f'>result</span> integer<span class="Delimiter">))</span></span>
<span class="Mu">}</span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span> <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">)))</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-tagged-value <span class="Delimiter">(</span>boolean literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-tagged-value <span class="Delimiter">(</span>boolean literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> test1 <span class="Delimiter">(</span><span class="Constant">1</span> tagged-value-address<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> tagged-value-address<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (each stmt function*!test-fn</span>
<span class="CommentedCode">;? (prn " " stmt))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (wipe dump-trace*)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.3</span> t<span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - an example function that can do different things (dispatch) based on the type of its args or oargs"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"dispatch-multiple-calls"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>test1</span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#00af87'>default-scope</span> scope-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>scope literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">20</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#ff8700'>first-arg-box</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Comment">; if given integers, add them</span>
<span class="Mu">{ <span class="muHack">begin</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#ff8700'>first-arg</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span>match? boolean<span class="Delimiter">)</span> <span class="Op"><-</span> maybe-coerce <span class="Delimiter">(</span><span style='color:#ff8700'>first-arg-box</span> tagged-value-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>integer literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">break-unless</span> <span class="Delimiter">(</span>match? boolean<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#ffd700'>second-arg-box</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#ffd700'>second-arg</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> maybe-coerce <span class="Delimiter">(</span><span style='color:#ffd700'>second-arg-box</span> tagged-value-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>integer literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#af005f'>result</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span style='color:#ff8700'>first-arg</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span style='color:#ffd700'>second-arg</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span> <span class="Delimiter">(</span><span style='color:#af005f'>result</span> integer<span class="Delimiter">))</span></span>
<span class="Mu">}</span>
<span class="Comment">; if given booleans, or them (it's a silly kind of generic function)</span>
<span class="Mu">{ <span class="muHack">begin</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#ff8700'>first-arg</span> boolean<span class="Delimiter">)</span> <span class="Delimiter">(</span>match? boolean<span class="Delimiter">)</span> <span class="Op"><-</span> maybe-coerce <span class="Delimiter">(</span><span style='color:#ff8700'>first-arg-box</span> tagged-value-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>boolean literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">break-unless</span> <span class="Delimiter">(</span>match? boolean<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#ffd700'>second-arg-box</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> <span class="Identifier">arg</span><span class="Delimiter">)</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#ffd700'>second-arg</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> maybe-coerce <span class="Delimiter">(</span><span style='color:#ffd700'>second-arg-box</span> tagged-value-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>boolean literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span style='color:#af005f'>result</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> or <span class="Delimiter">(</span><span style='color:#ff8700'>first-arg</span> boolean<span class="Delimiter">)</span> <span class="Delimiter">(</span><span style='color:#ffd700'>second-arg</span> boolean<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span> <span class="Delimiter">(</span><span style='color:#af005f'>result</span> integer<span class="Delimiter">))</span></span>
<span class="Mu">}</span>
<span class="Mu"><span class="Delimiter">(</span><span class="Identifier">reply</span> <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">)))</span></span>
<span class="Mu"><span class="Delimiter">(</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-tagged-value <span class="Delimiter">(</span>boolean literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-tagged-value <span class="Delimiter">(</span>boolean literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">t</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> test1 <span class="Delimiter">(</span><span class="Constant">1</span> tagged-value-address<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> tagged-value-address<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">10</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-tagged-value <span class="Delimiter">(</span>integer literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">11</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-tagged-value <span class="Delimiter">(</span>integer literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">12</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> test1 <span class="Delimiter">(</span><span class="Constant">10</span> tagged-value-address<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">11</span> tagged-value-address<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~and <span class="Delimiter">(</span>is <span class="Global">memory*</span><span class="Constant">.3</span> t<span class="Delimiter">)</span> <span class="Delimiter">(</span>is <span class="Global">memory*</span><span class="Constant">.12</span> <span class="Constant">37</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - different calls can exercise different clauses of the same function"</span><span class="Delimiter">))</span>
<span class="SalientComment">;; Concurrency</span>
<span class="Comment">;</span>
<span class="Comment">; A rudimentary process scheduler. You can 'run' multiple functions at once,</span>
<span class="Comment">; and they share the virtual processor.</span>
<span class="Comment">;</span>
<span class="Comment">; There's also a 'fork' primitive to let functions create new threads of</span>
<span class="Comment">; execution (we call them routines).</span>
<span class="Comment">;</span>
<span class="Comment">; Eventually we want to allow callers to influence how much of their CPU they</span>
<span class="Comment">; give to their 'children', or to rescind a child's running privileges.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"scheduler"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>f1</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">)))</span></span>
<span class="Mu"><span class="Delimiter">(</span>f2</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>f1 <span class="Delimiter">'</span>f2<span class="Delimiter">)</span>
<span class="Delimiter">(</span>when <span class="Delimiter">(</span>~iso <span class="Constant">2</span> <span class="Global">curr-cycle*</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - scheduler didn't run the right number of instructions: "</span> <span class="Global">curr-cycle*</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Global">memory*</span> <span class="Delimiter">(</span>obj <span class="Constant">1</span> <span class="Constant">3</span> <span class="Constant">2</span> <span class="Constant">4</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - scheduler runs multiple functions: "</span> <span class="Global">memory*</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>check-trace-contents <span class="Constant">"scheduler orders functions correctly"</span>
<span class="Delimiter">'((</span><span class="Constant">"schedule"</span> <span class="Constant">"f1"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"schedule"</span> <span class="Constant">"f2"</span><span class="Delimiter">)</span>
<span class="Delimiter">))</span>
<span class="Delimiter">(</span>check-trace-contents <span class="Constant">"scheduler orders schedule and run events correctly"</span>
<span class="Delimiter">'((</span><span class="Constant">"schedule"</span> <span class="Constant">"f1"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"run"</span> <span class="Constant">"f1 0"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"schedule"</span> <span class="Constant">"f2"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"run"</span> <span class="Constant">"f2 0"</span><span class="Delimiter">)</span>
<span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"scheduler-alternate"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Delimiter">'((</span>f1
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">)))</span></span>
<span class="Delimiter">(</span>f2
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span><span class="Identifier">=</span> <span class="Global">scheduling-interval*</span> <span class="Constant">1</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>f1 <span class="Delimiter">'</span>f2<span class="Delimiter">)</span>
<span class="Delimiter">(</span>check-trace-contents <span class="Constant">"scheduler alternates between routines"</span>
<span class="Delimiter">'((</span><span class="Constant">"run"</span> <span class="Constant">"f1 0"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"run"</span> <span class="Constant">"f2 0"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"run"</span> <span class="Constant">"f1 1"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"run"</span> <span class="Constant">"f2 1"</span><span class="Delimiter">)</span>
<span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"sleep"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Delimiter">'((</span>f1
<span class="Mu"><span class="Delimiter">(</span>sleep <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">)))</span></span>
<span class="Delimiter">(</span>f2
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (= dump-trace* (obj whitelist '("run" "schedule")))</span>
<span class="Delimiter">(</span><span class="Identifier">=</span> <span class="Global">scheduling-interval*</span> <span class="Constant">1</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>f1 <span class="Delimiter">'</span>f2<span class="Delimiter">)</span>
<span class="Delimiter">(</span>check-trace-contents <span class="Constant">"scheduler handles sleeping routines"</span>
<span class="Delimiter">'((</span><span class="Constant">"run"</span> <span class="Constant">"f1 0"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"run"</span> <span class="Constant">"sleeping until 2"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"schedule"</span> <span class="Constant">"pushing f1 to sleep queue"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"run"</span> <span class="Constant">"f2 0"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"run"</span> <span class="Constant">"f2 1"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"schedule"</span> <span class="Constant">"waking up f1"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"run"</span> <span class="Constant">"f1 1"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"run"</span> <span class="Constant">"f1 2"</span><span class="Delimiter">)</span>
<span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"sleep-long"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Delimiter">'((</span>f1
<span class="Mu"><span class="Delimiter">(</span>sleep <span class="Delimiter">(</span><span class="MuConstant">20</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">)))</span></span>
<span class="Delimiter">(</span>f2
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (= dump-trace* (obj whitelist '("run" "schedule")))</span>
<span class="Delimiter">(</span><span class="Identifier">=</span> <span class="Global">scheduling-interval*</span> <span class="Constant">1</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>f1 <span class="Delimiter">'</span>f2<span class="Delimiter">)</span>
<span class="Delimiter">(</span>check-trace-contents <span class="Constant">"scheduler progresses sleeping routines when there are no routines left to run"</span>
<span class="Delimiter">'((</span><span class="Constant">"run"</span> <span class="Constant">"f1 0"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"run"</span> <span class="Constant">"sleeping until 21"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"schedule"</span> <span class="Constant">"pushing f1 to sleep queue"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"run"</span> <span class="Constant">"f2 0"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"run"</span> <span class="Constant">"f2 1"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"schedule"</span> <span class="Constant">"waking up f1"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"run"</span> <span class="Constant">"f1 1"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Constant">"run"</span> <span class="Constant">"f1 2"</span><span class="Delimiter">)</span>
<span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"sleep-location"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Delimiter">'((</span>f1
<span class="Comment">; waits for memory location 1 to be set, before computing its successor</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">0</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>sleep <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> add <span class="Delimiter">(</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">)))</span></span>
<span class="Delimiter">(</span>f2
<span class="Mu"><span class="Delimiter">(</span>sleep <span class="Delimiter">(</span><span class="MuConstant">30</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">)))))</span> <span class="Comment">; set to value</span></span>
<span class="CommentedCode">;? (= dump-trace* (obj whitelist '("run" "schedule")))</span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span><span class="Identifier">=</span> <span class="Global">scheduling-interval*</span> <span class="Constant">1</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>f1 <span class="Delimiter">'</span>f2<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn canon.memory*)</span>
<span class="Delimiter">(</span><span class="Normal">let</span> last-routine <span class="Delimiter">(</span>deq <span class="Global">completed-routines*</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>aif rep.last-routine!error <span class="Delimiter">(</span>prn <span class="Constant">"error - "</span> it<span class="Delimiter">)))</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.2</span> <span class="Constant">4</span><span class="Delimiter">)</span> <span class="Comment">; successor of value</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - scheduler handles routines blocking on a memory location"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Comment">; The scheduler needs to keep track of the call stack for each routine.</span>
<span class="Comment">; Eventually we'll want to save this information in mu's address space itself,</span>
<span class="Comment">; along with the types array, the magic buffers for args and oargs, and so on.</span>
<span class="Comment">;</span>
<span class="Comment">; Eventually we want the right stack-management primitives to build delimited</span>
<span class="Comment">; continuations in mu.</span>
<span class="Comment">; Routines can throw errors.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"array-bounds-check"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Mu"><span class="Delimiter">'((</span>main</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">23</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">24</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> index <span class="Delimiter">(</span><span class="Constant">1</span> integer-array<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">let</span> last-routine <span class="Delimiter">(</span>deq <span class="Global">completed-routines*</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>no rep.last-routine!error<span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'index' throws an error if out of bounds"</span><span class="Delimiter">)))</span>
<span class="SalientComment">;; Synchronization</span>
<span class="Comment">;</span>
<span class="Comment">; Mu synchronizes using channels rather than locks, like Erlang and Go.</span>
<span class="Comment">;</span>
<span class="Comment">; The two ends of a channel will usually belong to different routines, but</span>
<span class="Comment">; each end should only be used by a single one. Don't try to read from or</span>
<span class="Comment">; write to it from multiple routines at once.</span>
<span class="Comment">;</span>
<span class="Comment">; To avoid locking, writer and reader will never write to the same location.</span>
<span class="Comment">; So channels will include fields in pairs, one for the writer and one for the</span>
<span class="Comment">; reader.</span>
<span class="Comment">; The core circular buffer contains values at index 'first-full' up to (but</span>
<span class="Comment">; not including) index 'first-empty'. The reader always modifies it at</span>
<span class="Comment">; first-full, while the writer always modifies it at first-empty.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"channel-new"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Delimiter">'((</span>main
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-channel <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>first-full offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>first-free offset<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>~is <span class="Constant">0</span> <span class="Global">memory*</span><span class="Constant">.2</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is <span class="Constant">0</span> <span class="Global">memory*</span><span class="Constant">.3</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'new-channel' initializes 'first-full and 'first-free to 0"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"channel-write"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Delimiter">'((</span>main
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-channel <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>integer literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-tagged-value <span class="Delimiter">(</span>integer-address literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer-address<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> write <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> tagged-value-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>first-full offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>first-free offset<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="CommentedCode">;? (= dump-trace* (obj blacklist '("sz" "m" "setm" "addr" "array-len" "cvt0" "cvt1")))</span>
<span class="CommentedCode">;? (= dump-trace* (obj whitelist '("jump")))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn canon.memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>~is <span class="Constant">0</span> <span class="Global">memory*</span><span class="Constant">.4</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is <span class="Constant">1</span> <span class="Global">memory*</span><span class="Constant">.5</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'write' enqueues item to channel"</span><span class="Delimiter">))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"channel-read"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Delimiter">'((</span>main
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-channel <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>integer literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-tagged-value <span class="Delimiter">(</span>integer-address literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer-address<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> write <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> tagged-value-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> tagged-value<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> read <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">6</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> maybe-coerce <span class="Delimiter">(</span><span class="Constant">4</span> tagged-value<span class="Delimiter">)</span> <span class="Delimiter">(</span>integer-address literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">7</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>first-full offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">8</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>first-free offset<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="CommentedCode">;? (= dump-trace* (obj blacklist '("sz" "m" "setm" "addr" "array-len" "cvt0" "cvt1")))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn int-canon.memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~is <span class="Global">memory*</span><span class="Constant">.6</span> <span class="Global">memory*</span><span class="Constant">.2</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'read' returns written value"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>~is <span class="Constant">1</span> <span class="Global">memory*</span><span class="Constant">.7</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is <span class="Constant">1</span> <span class="Global">memory*</span><span class="Constant">.8</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'read' dequeues item from channel"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"channel-write-wrap"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Delimiter">'((</span>main
<span class="Comment">; channel with 2 slots (capacity 1 since we waste a slot)</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-channel <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Comment">; write a value</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>integer literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-tagged-value <span class="Delimiter">(</span>integer-address literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer-address<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> write <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> tagged-value-address deref<span class="Delimiter">))</span></span>
<span class="Comment">; first-free will now be 1</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>first-free offset<span class="Delimiter">))</span></span>
<span class="Comment">; read one value</span>
<span class="Mu"><span class="Delimiter">(</span>_ <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> read <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">))</span></span>
<span class="Comment">; write a second value; verify that first-free wraps around to 0.</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> write <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> tagged-value-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>first-free offset<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="CommentedCode">;? (= dump-trace* (obj blacklist '("sz" "m" "setm" "addr" "array-len" "cvt0" "cvt1")))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn canon.memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>~is <span class="Constant">1</span> <span class="Global">memory*</span><span class="Constant">.4</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is <span class="Constant">0</span> <span class="Global">memory*</span><span class="Constant">.5</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'write' can wrap pointer back to start"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"channel-read-wrap"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Delimiter">'((</span>main
<span class="Comment">; channel with 2 slots (capacity 1 since we waste a slot)</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-channel <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Comment">; write a value</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>integer literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-tagged-value <span class="Delimiter">(</span>integer-address literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer-address<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> write <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> tagged-value-address deref<span class="Delimiter">))</span></span>
<span class="Comment">; read one value</span>
<span class="Mu"><span class="Delimiter">(</span>_ <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> read <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">))</span></span>
<span class="Comment">; first-full will now be 1</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>first-full offset<span class="Delimiter">))</span></span>
<span class="Comment">; write a second value</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> write <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> tagged-value-address deref<span class="Delimiter">))</span></span>
<span class="Comment">; read second value; verify that first-full wraps around to 0.</span>
<span class="Mu"><span class="Delimiter">(</span>_ <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> read <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>first-full offset<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="CommentedCode">;? (= dump-trace* (obj blacklist '("sz" "m" "setm" "addr" "array-len" "cvt0" "cvt1")))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn canon.memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>~is <span class="Constant">1</span> <span class="Global">memory*</span><span class="Constant">.4</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is <span class="Constant">0</span> <span class="Global">memory*</span><span class="Constant">.5</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'read' can wrap pointer back to start"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"channel-new-empty-not-full"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Delimiter">'((</span>main
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-channel <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> empty? <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> full? <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>~is t <span class="Global">memory*</span><span class="Constant">.2</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is nil <span class="Global">memory*</span><span class="Constant">.3</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - a new channel is always empty, never full"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"channel-write-not-empty"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Delimiter">'((</span>main
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-channel <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>integer literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-tagged-value <span class="Delimiter">(</span>integer-address literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer-address<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> write <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> tagged-value-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> empty? <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> full? <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>~is nil <span class="Global">memory*</span><span class="Constant">.4</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is nil <span class="Global">memory*</span><span class="Constant">.5</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - a channel after writing is never empty"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"channel-write-full"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Delimiter">'((</span>main
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-channel <span class="Delimiter">(</span><span class="MuConstant">2</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>integer literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-tagged-value <span class="Delimiter">(</span>integer-address literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer-address<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> write <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> tagged-value-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> empty? <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> full? <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>~is nil <span class="Global">memory*</span><span class="Constant">.4</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is t <span class="Global">memory*</span><span class="Constant">.5</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - a channel after writing may be full"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"channel-read-not-full"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Delimiter">'((</span>main
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-channel <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>integer literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-tagged-value <span class="Delimiter">(</span>integer-address literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer-address<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> write <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> tagged-value-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> write <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> tagged-value-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>_ <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> read <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> empty? <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> full? <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>~is nil <span class="Global">memory*</span><span class="Constant">.4</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is nil <span class="Global">memory*</span><span class="Constant">.5</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - a channel after reading is never full"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"channel-read-empty"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Delimiter">'((</span>main
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-channel <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>integer literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-tagged-value <span class="Delimiter">(</span>integer-address literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer-address<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> write <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> tagged-value-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>_ <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> read <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> empty? <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> full? <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn memory*)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>~is t <span class="Global">memory*</span><span class="Constant">.4</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is nil <span class="Global">memory*</span><span class="Constant">.5</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - a channel after reading may be empty"</span><span class="Delimiter">))</span>
<span class="Comment">; The key property of channels; writing to a full channel blocks the current</span>
<span class="Comment">; routine until it creates space. Ditto reading from an empty channel.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"channel-read-block"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Delimiter">'((</span>main
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-channel <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Comment">; channel is empty, but receives a read</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> tagged-value<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> read <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="CommentedCode">;? (= dump-trace* (obj whitelist '("run")))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn int-canon.memory*)</span>
<span class="CommentedCode">;? (prn sleeping-routines*)</span>
<span class="Comment">; read should cause the routine to sleep, and</span>
<span class="Comment">; the sole sleeping routine should trigger the deadlock detector</span>
<span class="Delimiter">(</span><span class="Normal">let</span> last-routine <span class="Delimiter">(</span>deq <span class="Global">completed-routines*</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>when <span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>no rep.last-routine!error<span class="Delimiter">)</span>
<span class="Delimiter">(</span>~posmatch <span class="Constant">"deadlock"</span> rep.last-routine!error<span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'read' on empty channel blocks (puts the routine to sleep until the channel gets data)"</span><span class="Delimiter">)))</span>
<span class="CommentedCode">;? (quit)</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"channel-write-block"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Delimiter">'((</span>main
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-channel <span class="Delimiter">(</span><span class="MuConstant">1</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>integer literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-tagged-value <span class="Delimiter">(</span>integer-address literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer-address<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> write <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> tagged-value-address deref<span class="Delimiter">))</span></span>
<span class="Comment">; channel has capacity 1, but receives a second write</span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> write <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> tagged-value-address deref<span class="Delimiter">)))))</span></span>
<span class="CommentedCode">;? (set dump-trace*)</span>
<span class="CommentedCode">;? (= dump-trace* (obj whitelist '("run")))</span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="CommentedCode">;? (prn int-canon.memory*)</span>
<span class="Comment">; second write should cause the routine to sleep, and</span>
<span class="Comment">; the sole sleeping routine should trigger the deadlock detector</span>
<span class="Delimiter">(</span><span class="Normal">let</span> last-routine <span class="Delimiter">(</span>deq <span class="Global">completed-routines*</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>when <span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>no rep.last-routine!error<span class="Delimiter">)</span>
<span class="Delimiter">(</span>~posmatch <span class="Constant">"deadlock"</span> rep.last-routine!error<span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'write' on full channel blocks (puts the routine to sleep until the channel gets data)"</span><span class="Delimiter">)))</span>
<span class="Comment">; But how will the sleeping routines wake up? Our scheduler can't watch for</span>
<span class="Comment">; changes to arbitrary values, just tell us if a specific raw location becomes</span>
<span class="Comment">; non-zero (see the sleep-location test above). So both reader and writer set</span>
<span class="Comment">; 'read-watch' and 'write-watch' respectively at the end of a successful call.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"channel-write-watch"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Delimiter">'((</span>main
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-channel <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>integer literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-tagged-value <span class="Delimiter">(</span>integer-address literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer-address<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>read-watch offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> write <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> tagged-value-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>write-watch offset<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>~is nil <span class="Global">memory*</span><span class="Constant">.4</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is t <span class="Global">memory*</span><span class="Constant">.5</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'write' sets channel watch"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="Delimiter">(</span>new-trace <span class="Constant">"channel-read-watch"</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>add-fns
<span class="Delimiter">'((</span>main
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-channel <span class="Delimiter">(</span><span class="MuConstant">3</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address<span class="Delimiter">)</span> <span class="Op"><-</span> new <span class="Delimiter">(</span>integer literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">34</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> tagged-value-address<span class="Delimiter">)</span> <span class="Op"><-</span> new-tagged-value <span class="Delimiter">(</span>integer-address literal<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">2</span> integer-address<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> write <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span><span class="Constant">3</span> tagged-value-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">4</span> boolean<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>read-watch offset<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>_ <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Op"><-</span> read <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">5</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> get <span class="Delimiter">(</span><span class="Constant">1</span> channel-address deref<span class="Delimiter">)</span> <span class="Delimiter">(</span>read-watch offset<span class="Delimiter">)))))</span></span>
<span class="Delimiter">(</span>run <span class="Delimiter">'</span>main<span class="Delimiter">)</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span><span class="Normal">or</span> <span class="Delimiter">(</span>~is nil <span class="Global">memory*</span><span class="Constant">.4</span><span class="Delimiter">)</span>
<span class="Delimiter">(</span>~is t <span class="Global">memory*</span><span class="Constant">.5</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - 'read' sets channel watch"</span><span class="Delimiter">))</span>
<span class="SalientComment">;; Separating concerns</span>
<span class="Comment">;</span>
<span class="Comment">; Lightweight tools can also operate on quoted lists of statements surrounded</span>
<span class="Comment">; by square brackets. In the example below, we mimic Go's 'defer' keyword</span>
<span class="Comment">; using 'convert-quotes'. It lets us write code anywhere in a function, but</span>
<span class="Comment">; have it run just before the function exits. Great for keeping code to</span>
<span class="Comment">; reclaim memory or other resources close to the code to allocate it. (C++</span>
<span class="Comment">; programmers know this as RAII.) We'll use 'defer' when we build a memory</span>
<span class="Comment">; deallocation routine like C's 'free'.</span>
<span class="Comment">;</span>
<span class="Comment">; More powerful reorderings are also possible like in Literate Programming or</span>
<span class="Comment">; Aspect-Oriented Programming; one advantage of prohibiting arbitrarily nested</span>
<span class="Comment">; code is that we can naturally name 'join points' wherever we want.</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span>
<span class="CommentedCode">;? (new-trace "convert-quotes-defer")</span>
<span class="Delimiter">(</span><span class="Normal">if</span> <span class="Delimiter">(</span>~iso <span class="Delimiter">(</span>convert-quotes
<span class="Mu"><span class="Delimiter">'(((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">(</span>defer <span class="Delimiter">[</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">6</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">])</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">5</span> literal<span class="Delimiter">))))</span></span>
<span class="Mu"><span class="Delimiter">'(((</span><span class="Constant">1</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">4</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">2</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">5</span> literal<span class="Delimiter">))</span></span>
<span class="Mu"><span class="Delimiter">((</span><span class="Constant">3</span> integer<span class="Delimiter">)</span> <span class="Op"><-</span> copy <span class="Delimiter">(</span><span class="MuConstant">6</span> literal<span class="Delimiter">))))</span></span>
<span class="Delimiter">(</span>prn <span class="Constant">"F - convert-quotes can handle 'defer'"</span><span class="Delimiter">))</span>
<span class="Delimiter">(</span>reset<span class="Delimiter">)</span> <span class="Comment">; end file with this to persist the trace for the final test</span>
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->