+ <h3>Evaluation Rules in Continuation-Passing Style</h3>
+ <p>Elementary continuations:</p>
+ <ul>
+ <li>$\serialform$</li>
+ <li>$\iftestform$</li>
+ <li>$\setvalueform$</li>
+ <li>$\blockserialforms$</li>
+ <li>$\returnfromvaluesform$</li>
+ <li>$\catchexittagform$</li>
+ <li>$\catchserialforms$</li>
+ <li>$\throwexittagform$</li>
+ <li>$\throwvaluesform$</li>
+ <li>$\handlerbindhandlerform$</li>
+ <li>$\handlerbindserialforms$</li>
+ <li>$\unwindprotectprotectedform$</li>
+ <li>$\unwindprotectcleanupforms$</li>
+ <li>$\foreachfunctionform$</li>
+ <li>$\foreachlistform$</li>
+ <li>$\foreachelement$</li>
+ <li>$\functioncalloperatorform$</li>
+ <li>$\functioncalloperandform$</li>
+ <li>$\macro$</li>
+ </ul>
+ <p>Auxiliary functions:</p>
+ <ul>
+ <li>$\evalserialforms$</li>
+ <li>$\evalserialformforms$</li>
+ <li>$\foreach$</li>
+ <li>$\evaloperandforms$</li>
+ <li>$\invoke$</li>
+ </ul>
+ <dl>
+ <!-- quote-form -->
+ <dt>To evaluate <code class="bg">(quote $\mlvar{literal}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Invoke $k$ on $\mlvar{literal}$.</dd>
+ <!-- progn-form -->
+ <dt>To evaluate <code class="bg">(progn $\mlvar{serial-forms}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Invoke the auxiliary function $\evalserialforms$ on $\mlvar{serial-forms}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the auxiliary function $\evalserialforms$ on $\mlvar{serial-forms}$, $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>If $\mlvar{serial-forms}$ is empty, then invoke $k$ on <code>#v</code>. Otherwise, invoke the auxiliary function $\evalserialformforms$ on $\mlvar{serial-forms}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the auxiliary function $\evalserialformforms$ on $\mlvar{serial-forms}$, $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>If $\mlvar{serial-forms}$ contains exactly one element, then evaluate the single element of $\mlvar{serial-forms}$ with respect to $\lexenv$, $\dynenv$, and $k$. Otherwise, evaluate the first element of $\mlvar{serial-forms}$ with respect to $\lexenv$, $\dynenv$, and a $\serialform$ continuation capturing $\mlvar{serial-forms}$ minus its first element, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\serialform(\mlvar{serial-forms},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, invoke the auxiliary function $\evalserialformforms$ on $\mlvar{serial-forms}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <!-- if-form -->
+ <dt>To evaluate <code class="bg">(if $\mlvar{test-form}$ $\mlvar{then-form}$ $\mlvar{else-form}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Evaluate $\mlvar{test-form}$ with respect to an $\iftestform$ continuation capturing $\mlvar{then-form}$, $\mlvar{else-form}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\iftestform(\mlvar{then-form},\mlvar{else-form},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, let $\mlvar{test}$ be the primary value of $\outcome$. If $\mlvar{test}$ is not a boolean, then invoke $k$ on an abrupt completion reason of type <code>error</code>. If $\mlvar{test}$ is the boolean <code>#t</code>, then evaluate $\mlvar{then-form}$ with respect to $\lexenv$, $\dynenv$, and $k$. If $\mlvar{test}$ is the boolean <code>#f</code>, then evaluate $\mlvar{else-form}$ with respect to $\lexenv$, $\dynenv$, and $k$.</dd>
+ <!-- lambda abstractions -->
+ <dt>To evaluate <code class="bg">(_vlambda $\mlvar{parameter-list}$ $\mlvar{body}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dt>To evaluate <code class="bg">(_mlambda $\mlvar{parameter-list}$ $\mlvar{body}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dt>To evaluate <code class="bg">(_flambda $\mlvar{parameter-list}$ $\mlvar{body}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dt>To evaluate <code class="bg">(_dlambda $\mlvar{parameter-list}$ $\mlvar{body}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Invoke $k$ on a closure recording the lambda abstraction and $\lexenv$.</dd>
+ <!-- variable references -->
+ <dt>To evaluate <code class="bg">(vref $\mlvar{variable}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dt>To evaluate <code class="bg">(fref $\mlvar{variable}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dt>To evaluate <code class="bg">(dref $\mlvar{variable}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>If a binding exists for $\mlvar{variable}$, then invoke $k$ on its value. Otherwise, invoke $k$ on an abrupt completion reason of type <code>error</code>.</dd>
+ <!-- variable assignments -->
+ <dt>To evaluate <code class="bg">(vset! $\mlvar{variable}$ $\mlvar{value-form}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dt>To evaluate <code class="bg">(fset! $\mlvar{variable}$ $\mlvar{value-form}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dt>To evaluate <code class="bg">(dset! $\mlvar{variable}$ $\mlvar{value-form}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Evaluate $\mlvar{value-form}$ with respect to a $\setvalueform$ continuation capturing $\mlvar{variable}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\setvalueform(\mlvar{variable},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, let $\mlvar{value}$ be the primary value of $\outcome$. If a binding exists for $\mlvar{variable}$, then set its value to $\mlvar{value}$ and invoke $k$ on $\mlvar{value}$. Otherwise, create a binding between $\mlvar{variable}$ and $\mlvar{value}$ and invoke $k$ on $\mlvar{value}$.</dd>
+ <!-- block-form -->
+ <dt>To evaluate <code class="bg">(block $\mlvar{block-name}$ $\mlvar{serial-forms}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Let $\mlvar{exit-tag}$ be a new uninterned variable. Invoke the auxiliary function $\evalserialforms$ on $\mlvar{serial-forms}$ and a $\blockserialforms$ continuation capturing $\mlvar{exit-tag}$, the environment extending $\lexenv$ to bind, in the block namespace, the variable $\mlvar{block-name}$ to $\mlvar{exit-tag}$, the environment extending $\dynenv$ to bind, in the exit-point namespace, the variable $\mlvar{exit-tag}$ to <code>#v</code>, and $k$.</dd>
+ <dt>To invoke the continuation $\blockserialforms(\mlvar{exit-tag},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $result$ is an abrupt completion reason of type <code>nonlocal-exit</code> carrying an exit tag <code>eq?</code> to $\mlvar{exit-tag}$, then invoke $k$ on the values carried by $\outcome$. Otherwise, invoke $k$ on $\outcome$.</dd>
+ <!-- return-from-form -->
+ <dt>To evaluate <code class="bg">(return-from $\mlvar{block-name}$ $\mlvar{values-form}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>If there exists no binding for the variable $\mlvar{block-name}$ in the block namespace of $\lexenv$, then invoke $k$ on an abrupt completion reason of type <code>error</code>. Otherwise, let $\mlvar{exit-tag}$ be the value of the binding for the variable $\mlvar{block-name}$ in the block namespace of $\lexenv$. If there exists no binding for the variable $\mlvar{exit-tag}$ in the exit-point namespace of $\dynenv$, then invoke $k$ on an abrupt completion reason of type <code>error</code>. Otherwise, evaluate $\mlvar{values-form}$ with respect to $\lexenv$, $\dynenv$, and a $\returnfromvaluesform$ continuation capturing $\mlvar{exit-tag}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\returnfromvaluesform(\mlvar{exit-tag},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, invoke $k$ on an abrupt completion reason of type <code>nonlocal-exit</code> carrying $\mlvar{exit-tag}$ and $\outcome$.</dd>
+ <!-- catch-form -->
+ <dt>To evaluate <code class="bg">(catch $\mlvar{exit-tag-form}$ $\mlvar{serial-forms}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Evaluate $\mlvar{exit-tag-form}$ with respect to a $\catchexittagform$ continuation capturing $\mlvar{serial-forms}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\catchexittagform(\mlvar{serial-forms},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, let $\mlvar{exit-tag}$ be the primary value of $\outcome$. If $\mlvar{exit-tag}$ is not a variable, then invoke $k$ on an abrupt completion reason of type <code>error</code>. Otherwise, invoke the auxiliary function $\evalserialforms$ on $\mlvar{serial-forms}$ and a $\catchserialforms$ continuation capturing $\mlvar{exit-tag}$, $\lexenv$, the environment extending $\dynenv$ to bind, in the exit-point namespace, the variable $\mlvar{exit-tag}$ to <code>#v</code>, and $k$.</dd>
+ <dt>To invoke the continuation $\catchserialforms(\mlvar{exit-tag},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $result$ is an abrupt completion reason of type <code>nonlocal-exit</code> carrying an exit tag <code>eq?</code> to $\mlvar{exit-tag}$, then invoke $k$ on the values carried by $\outcome$. Otherwise, invoke $k$ on $\outcome$.</dd>
+ <!-- throw-form -->
+ <dt>To evaluate <code class="bg">(throw $\mlvar{exit-tag-form}$ $\mlvar{values-form}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Evaluate $\mlvar{exit-tag-form}$ with respect to a $\throwexittagform$ continuation capturing $\mlvar{values-form}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\throwexittagform(\mlvar{values-form},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $\outcome$ is an abrupt completion reason, then invoke $k$ $\outcome$. Otherwise, let $\mlvar{exit-tag}$ be the primary value of $\outcome$. If $\mlvar{exit-tag}$ is not a variable, then invoke $k$ on an abrupt completion reason of type <code>error</code>. Otherwise, if there exists no binding for the variable $\mlvar{exit-tag}$ in the exit-point namespace of $\dynenv$, then invoke $k$ on an abrupt completion reason of type <code>error</code>. Otherwise, evaluate $\mlvar{values-form}$ with respect to a $\throwvaluesform$ continuation capturing $\mlvar{exit-tag}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\throwvaluesform(\mlvar{exit-tag},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, invoke $k$ on an abrupt completion reason of type <code>nonlocal-exit</code> carrying $\mlvar{exit-tag}$ and $\outcome$.</dd>
+ <!-- _handler-bind-form -->
+ <dt>To evaluate <code class="bg">(_handler-bind $\mlvar{handler-form}$ $\mlvar{serial-forms}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Evaluate $\mlvar{handler-form}$ with respect to a $\handlerbindhandlerform$ continuation capturing $\mlvar{serial-forms}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\handlerbindhandlerform(\mlvar{serial-forms},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, let $\mlvar{handler}$ be the primary value of $\outcome$. If $\mlvar{handler}$ is not a function, then invoke $k$ on an abrupt completion reason of type <code>error</code>. Otherwise, invoke the auxiliary function $\evalserialforms$ on $\mlvar{serial-forms}$ and a $\handlerbindserialforms$ continuation capturing $\mlvar{handler}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\handlerbindserialforms(\mlvar{handler},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $\outcome$ is an abrupt completion reason of type <code>error</code>, then invoke the auxiliary function $\invoke$ on $\mlvar{handler}$, the string carried by $\outcome$, $\dynenv$, and $k$. Otherwise, invoke $k$ on $\outcome$.</dd>
+ <!-- unwind-protect-form -->
+ <dt>To evaluate <code class="bg">(unwind-protect $\mlvar{protected-form}$ $\mlvar{cleanup-forms}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Evaluate $\mlvar{protected-form}$ with respect to an $\unwindprotectprotectedform$ continuation capturing $\mlvar{cleanup-forms}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\unwindprotectprotectedform(\mlvar{cleanup-forms},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>Invoke the auxiliary function $\evalserialforms$ on $\mlvar{cleanup-forms}$ and an $\unwindprotectcleanupforms$ continuation capturing $\outcome$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\unwindprotectcleanupforms(\mlvar{protected-form-outcome},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, invoke $k$ on $\mlvar{protected-form-outcome}$.</dd>
+ <!-- _for-each-form -->
+ <dt>To evaluate <code class="bg">(_for-each $\mlvar{function-form}$ $\mlvar{list-form}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Evaluate $\mlvar{function-form}$ with respect to a $\foreachfunctionform$ continuation capturing $\mlvar{list-form}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\foreachfunctionform(\mlvar{list-form},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, let $\mlvar{function}$ be the primary value of $\outcome$. If $\mlvar{function}$ is not a function, then invoke $k$ on an abrupt completion reason of type <code>error</code>. Otherwise, evaluate $\mlvar{list-form}$ with respect to a $\foreachlistform$ continuation capturing $\mlvar{function}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\foreachlistform(\mlvar{function},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, let $\mlvar{list}$ be the primary value of $\outcome$. If $\mlvar{list}$ is not a proper list, then invoke $k$ on an abrupt completion reason of type <code>error</code>. Otherwise, invoke the auxiliary function $\foreach$ on $\mlvar{function}$, $\mlvar{list}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the auxiliary function $\foreach$ on $\mlvar{function}$, $\mlvar{list}$, $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>If $\mlvar{list}$ is empty, then invoke $k$ on <code>#v</code>. Otherwise, invoke the auxiliary function $\invoke$ on $\mlvar{function}$, the car of $\mlvar{list}$, $\dynenv$, and a $\foreachelement$ continuation capturing $\mlvar{function}$, the cdr of $\mlvar{list}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\foreachelement(\mlvar{function},\mlvar{list},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, invoke the auxiliary function $\foreach$ on $\mlvar{function}$, $\mlvar{list}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <!-- function calls -->
+ <dt>To evaluate <code class="bg">($\mlvar{operator-form}$ $\mlvar{operand-forms}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dt>To evaluate <code class="bg">(apply $\mlvar{operator-form}$ $\mlvar{operand-forms}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dt>To evaluate <code class="bg">(multiple-value-call $\mlvar{operator-form}$ $\mlvar{operand-forms}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dt>To evaluate <code class="bg">(multiple-value-apply $\mlvar{operator-form}$ $\mlvar{operand-forms}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Evaluate $\mlvar{operator-form}$ with respect to a $\functioncalloperatorform$ continuation capturing $\mlvar{operand-forms}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\functioncalloperatorform(\mlvar{operand-forms},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, let $\mlvar{operator}$ be the primary value of $\outcome$. If $\mlvar{operator}$ is not a function, then invoke $k$ on an abrupt completion reason of type <code>error</code>. Otherwise, invoke the auxiliary function $\evaloperandforms$ on $\mlvar{operator}$, $\mlvar{operand-forms}$, $[]$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the auxiliary function $\evaloperandforms$ on $\mlvar{operator}$, $\mlvar{operand-forms}$, $\mlvar{arguments}$, $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>If $\mlvar{operand-forms}$ is not empty, then evaluate the first element of $\mlvar{operand-forms}$ with respect to a $\functioncalloperandform$ continuation capturing $\mlvar{operator}$, $\mlvar{operand-forms}$ minus its first element, $\mlvar{arguments}$, $\lexenv$, $\dynenv$, and $k$. Otherwise, invoke the auxiliary function $\invoke$ on $\mlvar{operator}$, $\mlvar{arguments}$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\functioncalloperandform(\mlvar{operator},\mlvar{operand-forms},\mlvar{arguments},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, let $\mlvar{augmented-arguments}$ be the result of appending the primary value of $\outcome$ or all the values of $\outcome$ to $\mlvar{arguments}$. Invoke the auxiliary function $\evaloperandforms$ on $\mlvar{operator}$, $\mlvar{operand-forms}$, $\mlvar{augmented-arguments}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the auxiliary function $\invoke$ on $\mlvar{function}$, $\mlvar{arguments}$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>If $\mlvar{function}$ is a primitive function, then invoke $k$ on the outcome of the invocation of the JavaScript function implementing $\mlvar{function}$ on $\mlvar{arguments}$. If $\mlvar{function}$ is a closure, then invoke the auxiliary function $\evalserialforms$ on the body of the lambda abstraction recorded by the closure, the lexical environment recorded by the closure or an extension thereof, $\dynenv$ or an extension thereof, and $k$.</dd>
+ <!-- macro call -->
+ <dt>To evaluate <code class="bg">($\mlvar{macro-operator}$ $\mlvar{macro-operands}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Let $\mlvar{macro}$ be the macro named by $\mlvar{macro-operator}$. Invoke the auxiliary function $\invoke$ on $\mlvar{macro}$, $\mlvar{macro-operands}$, $\dynenv$, and a $\macro$ continuation capturing $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\macro(\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, evaluate the primary value of $\outcome$ with respect to $\lexenv$, $\dynenv$, and $k$.</dd>
+ </dl>